Compare commits
76 Commits
tmp-vulkan
...
temp-eevee
Author | SHA1 | Date | |
---|---|---|---|
05517c9bed | |||
ff11750ee9 | |||
abbd997193 | |||
0f13e53669 | |||
6100c236fb | |||
0bbccd3741 | |||
deaa90b5a5 | |||
a21742a07b | |||
65ac6e214d | |||
0b9350bb51 | |||
7bb7c3e5cb | |||
49099c9048 | |||
1f51b0212f | |||
6d0d237be3 | |||
5402529deb | |||
7538716d57 | |||
656739067f | |||
74a17505fd | |||
cc6fd329e6 | |||
b1bc3dfb89 | |||
da71d831c3 | |||
ed7b8e847f | |||
60e2e1058d | |||
ce6cc756c3 | |||
a1549065f2 | |||
0de33fb883 | |||
6364780b63 | |||
93aca278d2 | |||
c5e7dff566 | |||
922ebe960c | |||
7f3ea60aa7 | |||
7213006cef | |||
12d98d8a48 | |||
7ea7eae41f | |||
b28b6c62ed | |||
a498ffd4f6 | |||
76f49c7a7b | |||
e50aa8dc9d | |||
077dba6ac2 | |||
025b260144 | |||
d73bdecea4 | |||
c8859d8f66 | |||
77fd1a6a4b | |||
506f5654fe | |||
d8a7fd1006 | |||
e05b7c1616 | |||
e8d4930c4d | |||
02e2428fda | |||
56fd8978a5 | |||
90fdb427af | |||
1cbb195f8d | |||
29a834e530 | |||
5d280a2397 | |||
ce6418fc16 | |||
873acfb124 | |||
007d3074fa | |||
84c0446150 | |||
fbeae8ab13 | |||
43efefdbba | |||
8713dd1621 | |||
38eb004977 | |||
de0c3f563d | |||
51a4af4eb5 | |||
a0f5f3116a | |||
f00a590fd4 | |||
d3c645f72d | |||
ccea4d13b3 | |||
99e236e4d2 | |||
ffa5468bd9 | |||
8c18f79bd3 | |||
44e1c5d817 | |||
60ff71cc40 | |||
71c2768dcf | |||
312b12d172 | |||
49b0ac57c1 | |||
d380267b61 |
@@ -712,15 +712,49 @@ class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
props = scene.eevee
|
props = scene.eevee
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
|
col.operator("scene.light_cache_bake", text="Bake Indirect Lighting", icon='RENDER_STILL')
|
||||||
|
col.operator("scene.light_cache_bake", text="Bake Cubemap Only", icon='LIGHTPROBE_CUBEMAP').subset = "CUBEMAPS"
|
||||||
|
col.operator("scene.light_cache_free", text="Free Lighting Cache")
|
||||||
|
|
||||||
|
cache_info = scene.eevee.gi_cache_info
|
||||||
|
if cache_info:
|
||||||
|
col.label(text=cache_info)
|
||||||
|
|
||||||
|
col.prop(props, "gi_auto_bake")
|
||||||
|
|
||||||
col.prop(props, "gi_diffuse_bounces")
|
col.prop(props, "gi_diffuse_bounces")
|
||||||
col.prop(props, "gi_cubemap_resolution")
|
col.prop(props, "gi_cubemap_resolution")
|
||||||
col.prop(props, "gi_visibility_resolution", text="Diffuse Occlusion")
|
col.prop(props, "gi_visibility_resolution", text="Diffuse Occlusion")
|
||||||
|
|
||||||
|
layout.use_property_split = False
|
||||||
|
row = layout.split(percentage=0.5)
|
||||||
|
row.alignment = 'RIGHT'
|
||||||
|
row.label("Cubemap Display")
|
||||||
|
|
||||||
|
sub = row.row(align=True)
|
||||||
|
sub.prop(props, "gi_cubemap_draw_size", text="Size")
|
||||||
|
if props.gi_show_cubemaps :
|
||||||
|
sub.prop(props, "gi_show_cubemaps", text="", toggle=True, icon='HIDE_OFF')
|
||||||
|
else:
|
||||||
|
sub.prop(props, "gi_show_cubemaps", text="", toggle=True, icon='HIDE_ON')
|
||||||
|
|
||||||
|
row = layout.split(percentage=0.5)
|
||||||
|
row.alignment = 'RIGHT'
|
||||||
|
row.label("Irradiance Display")
|
||||||
|
|
||||||
|
sub = row.row(align=True)
|
||||||
|
sub.prop(props, "gi_irradiance_draw_size", text="Size")
|
||||||
|
if props.gi_show_irradiance :
|
||||||
|
sub.prop(props, "gi_show_irradiance", text="", toggle=True, icon='HIDE_OFF')
|
||||||
|
else:
|
||||||
|
sub.prop(props, "gi_show_irradiance", text="", toggle=True, icon='HIDE_ON')
|
||||||
|
|
||||||
|
|
||||||
class RENDER_PT_eevee_film(RenderButtonsPanel, Panel):
|
class RENDER_PT_eevee_film(RenderButtonsPanel, Panel):
|
||||||
bl_label = "Film"
|
bl_label = "Film"
|
||||||
|
@@ -239,7 +239,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *pixels = MEM_callocN((size_t)gc->p2_width * (size_t)gc->p2_height, "BLF texture init");
|
unsigned char *pixels = MEM_callocN((size_t)gc->p2_width * (size_t)gc->p2_height, "BLF texture init");
|
||||||
GPUTexture *tex = GPU_texture_create_2D(gc->p2_width, gc->p2_height, GPU_R8, (const float *)pixels, error);
|
GPUTexture *tex = GPU_texture_create_nD(gc->p2_width, gc->p2_height, 0, 2, pixels, GPU_R8, GPU_DATA_UNSIGNED_BYTE, 0, false, error);
|
||||||
MEM_freeN(pixels);
|
MEM_freeN(pixels);
|
||||||
gc->textures[gc->texture_current] = tex;
|
gc->textures[gc->texture_current] = tex;
|
||||||
GPU_texture_bind(tex, 0);
|
GPU_texture_bind(tex, 0);
|
||||||
@@ -476,7 +476,7 @@ void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
|
|||||||
BLI_assert(g->height > 0);
|
BLI_assert(g->height > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU_texture_update_sub(g->tex, g->bitmap, g->offset_x, g->offset_y, 0, g->width, g->height, 0);
|
GPU_texture_update_sub(g->tex, GPU_DATA_UNSIGNED_BYTE, g->bitmap, g->offset_x, g->offset_y, 0, g->width, g->height, 0);
|
||||||
|
|
||||||
g->uv[0][0] = ((float)g->offset_x) / ((float)gc->p2_width);
|
g->uv[0][0] = ((float)g->offset_x) / ((float)gc->p2_width);
|
||||||
g->uv[0][1] = ((float)g->offset_y) / ((float)gc->p2_height);
|
g->uv[0][1] = ((float)g->offset_y) / ((float)gc->p2_height);
|
||||||
|
@@ -44,10 +44,4 @@ struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld);
|
|||||||
struct World *BKE_world_localize(struct World *wrld);
|
struct World *BKE_world_localize(struct World *wrld);
|
||||||
void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
|
void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
|
||||||
|
|
||||||
/* Evaluation. */
|
|
||||||
|
|
||||||
struct Depsgraph;
|
|
||||||
|
|
||||||
void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -424,6 +424,8 @@ void BKE_object_free(Object *ob)
|
|||||||
{
|
{
|
||||||
BKE_animdata_free((ID *)ob, false);
|
BKE_animdata_free((ID *)ob, false);
|
||||||
|
|
||||||
|
DRW_drawdata_free((ID *)ob);
|
||||||
|
|
||||||
/* BKE_<id>_free shall never touch to ID->us. Never ever. */
|
/* BKE_<id>_free shall never touch to ID->us. Never ever. */
|
||||||
BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
|
BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
|
||||||
|
|
||||||
@@ -451,13 +453,6 @@ void BKE_object_free(Object *ob)
|
|||||||
|
|
||||||
sbFree(ob);
|
sbFree(ob);
|
||||||
|
|
||||||
for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
|
|
||||||
if (oed->free != NULL) {
|
|
||||||
oed->free(oed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BLI_freelistN(&ob->drawdata);
|
|
||||||
|
|
||||||
BKE_sculptsession_free(ob);
|
BKE_sculptsession_free(ob);
|
||||||
|
|
||||||
BLI_freelistN(&ob->pc_ids);
|
BLI_freelistN(&ob->pc_ids);
|
||||||
@@ -1210,7 +1205,6 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
|
|||||||
ob_dst->derivedFinal = NULL;
|
ob_dst->derivedFinal = NULL;
|
||||||
|
|
||||||
BLI_listbase_clear(&ob_dst->gpulamp);
|
BLI_listbase_clear(&ob_dst->gpulamp);
|
||||||
BLI_listbase_clear(&ob_dst->drawdata);
|
|
||||||
BLI_listbase_clear(&ob_dst->pc_ids);
|
BLI_listbase_clear(&ob_dst->pc_ids);
|
||||||
|
|
||||||
ob_dst->avs = ob_src->avs;
|
ob_dst->avs = ob_src->avs;
|
||||||
|
@@ -102,6 +102,9 @@
|
|||||||
#include "DEG_depsgraph_query.h"
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
#include "RE_engine.h"
|
#include "RE_engine.h"
|
||||||
|
#include "RE_engine.h"
|
||||||
|
|
||||||
|
#include "engines/eevee/eevee_lightcache.h"
|
||||||
|
|
||||||
#include "PIL_time.h"
|
#include "PIL_time.h"
|
||||||
|
|
||||||
@@ -316,6 +319,9 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
|
|||||||
else {
|
else {
|
||||||
sce_dst->preview = NULL;
|
sce_dst->preview = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sce_dst->eevee.light_cache = NULL;
|
||||||
|
/* TODO Copy the cache. */
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||||
@@ -511,6 +517,11 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
|
|||||||
sce->master_collection = NULL;
|
sce->master_collection = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sce->eevee.light_cache) {
|
||||||
|
EEVEE_lightcache_free(sce->eevee.light_cache);
|
||||||
|
sce->eevee.light_cache = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* These are freed on doversion. */
|
/* These are freed on doversion. */
|
||||||
BLI_assert(sce->layer_properties == NULL);
|
BLI_assert(sce->layer_properties == NULL);
|
||||||
}
|
}
|
||||||
@@ -814,6 +825,8 @@ void BKE_scene_init(Scene *sce)
|
|||||||
sce->eevee.gi_diffuse_bounces = 3;
|
sce->eevee.gi_diffuse_bounces = 3;
|
||||||
sce->eevee.gi_cubemap_resolution = 512;
|
sce->eevee.gi_cubemap_resolution = 512;
|
||||||
sce->eevee.gi_visibility_resolution = 32;
|
sce->eevee.gi_visibility_resolution = 32;
|
||||||
|
sce->eevee.gi_cubemap_draw_size = 0.2f;
|
||||||
|
sce->eevee.gi_irradiance_draw_size = 1.0f;
|
||||||
|
|
||||||
sce->eevee.taa_samples = 16;
|
sce->eevee.taa_samples = 16;
|
||||||
sce->eevee.taa_render_samples = 64;
|
sce->eevee.taa_render_samples = 64;
|
||||||
@@ -856,6 +869,8 @@ void BKE_scene_init(Scene *sce)
|
|||||||
sce->eevee.shadow_cube_size = 512;
|
sce->eevee.shadow_cube_size = 512;
|
||||||
sce->eevee.shadow_cascade_size = 1024;
|
sce->eevee.shadow_cascade_size = 1024;
|
||||||
|
|
||||||
|
sce->eevee.light_cache = NULL;
|
||||||
|
|
||||||
sce->eevee.flag =
|
sce->eevee.flag =
|
||||||
SCE_EEVEE_VOLUMETRIC_LIGHTS |
|
SCE_EEVEE_VOLUMETRIC_LIGHTS |
|
||||||
SCE_EEVEE_VOLUMETRIC_COLORED |
|
SCE_EEVEE_VOLUMETRIC_COLORED |
|
||||||
|
@@ -239,8 +239,8 @@ static void studiolight_create_equirectangular_radiance_gputexture(StudioLight *
|
|||||||
offset3 += 3;
|
offset3 += 3;
|
||||||
offset4 += 4;
|
offset4 += 4;
|
||||||
}
|
}
|
||||||
sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(
|
sl->equirectangular_radiance_gputexture = GPU_texture_create_nD(
|
||||||
ibuf->x, ibuf->y, GPU_R11F_G11F_B10F, sl->gpu_matcap_3components, error);
|
ibuf->x, ibuf->y, 0, 2, sl->gpu_matcap_3components, GPU_R11F_G11F_B10F, GPU_DATA_FLOAT, 0, false, error);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(
|
sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(
|
||||||
|
@@ -53,6 +53,8 @@
|
|||||||
#include "BKE_node.h"
|
#include "BKE_node.h"
|
||||||
#include "BKE_world.h"
|
#include "BKE_world.h"
|
||||||
|
|
||||||
|
#include "DRW_engine.h"
|
||||||
|
|
||||||
#include "DEG_depsgraph.h"
|
#include "DEG_depsgraph.h"
|
||||||
|
|
||||||
#include "GPU_material.h"
|
#include "GPU_material.h"
|
||||||
@@ -62,6 +64,8 @@ void BKE_world_free(World *wrld)
|
|||||||
{
|
{
|
||||||
BKE_animdata_free((ID *)wrld, false);
|
BKE_animdata_free((ID *)wrld, false);
|
||||||
|
|
||||||
|
DRW_drawdata_free((ID *)wrld);
|
||||||
|
|
||||||
/* is no lib link block, but world extension */
|
/* is no lib link block, but world extension */
|
||||||
if (wrld->nodetree) {
|
if (wrld->nodetree) {
|
||||||
ntreeFreeTree(wrld->nodetree);
|
ntreeFreeTree(wrld->nodetree);
|
||||||
@@ -163,10 +167,3 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local)
|
|||||||
BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
|
BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_world_eval(struct Depsgraph *depsgraph, World *world)
|
|
||||||
{
|
|
||||||
DEG_debug_print_eval(depsgraph, __func__, world->id.name, world);
|
|
||||||
if (!BLI_listbase_is_empty(&world->gpumaterial)) {
|
|
||||||
world->update_flag = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -30,6 +30,7 @@ set(INC
|
|||||||
../blenlib
|
../blenlib
|
||||||
../blentranslation
|
../blentranslation
|
||||||
../depsgraph
|
../depsgraph
|
||||||
|
../draw
|
||||||
../imbuf
|
../imbuf
|
||||||
../makesdna
|
../makesdna
|
||||||
../makesrna
|
../makesrna
|
||||||
|
@@ -393,6 +393,9 @@ BlendFileData *BLO_read_from_memfile(
|
|||||||
/* makes lookup of existing images in old main */
|
/* makes lookup of existing images in old main */
|
||||||
blo_make_image_pointer_map(fd, oldmain);
|
blo_make_image_pointer_map(fd, oldmain);
|
||||||
|
|
||||||
|
/* makes lookup of existing light caches in old main */
|
||||||
|
blo_make_scene_pointer_map(fd, oldmain);
|
||||||
|
|
||||||
/* makes lookup of existing video clips in old main */
|
/* makes lookup of existing video clips in old main */
|
||||||
blo_make_movieclip_pointer_map(fd, oldmain);
|
blo_make_movieclip_pointer_map(fd, oldmain);
|
||||||
|
|
||||||
@@ -403,6 +406,9 @@ BlendFileData *BLO_read_from_memfile(
|
|||||||
|
|
||||||
bfd = blo_read_file_internal(fd, filename);
|
bfd = blo_read_file_internal(fd, filename);
|
||||||
|
|
||||||
|
/* ensures relinked light caches are not freed */
|
||||||
|
blo_end_scene_pointer_map(fd, oldmain);
|
||||||
|
|
||||||
/* ensures relinked images are not freed */
|
/* ensures relinked images are not freed */
|
||||||
blo_end_image_pointer_map(fd, oldmain);
|
blo_end_image_pointer_map(fd, oldmain);
|
||||||
|
|
||||||
|
@@ -158,6 +158,8 @@
|
|||||||
#include "BKE_colortools.h"
|
#include "BKE_colortools.h"
|
||||||
#include "BKE_workspace.h"
|
#include "BKE_workspace.h"
|
||||||
|
|
||||||
|
#include "DRW_engine.h"
|
||||||
|
|
||||||
#include "DEG_depsgraph.h"
|
#include "DEG_depsgraph.h"
|
||||||
|
|
||||||
#include "NOD_common.h"
|
#include "NOD_common.h"
|
||||||
@@ -1339,6 +1341,8 @@ void blo_freefiledata(FileData *fd)
|
|||||||
oldnewmap_free(fd->imamap);
|
oldnewmap_free(fd->imamap);
|
||||||
if (fd->movieclipmap)
|
if (fd->movieclipmap)
|
||||||
oldnewmap_free(fd->movieclipmap);
|
oldnewmap_free(fd->movieclipmap);
|
||||||
|
if (fd->scenemap)
|
||||||
|
oldnewmap_free(fd->scenemap);
|
||||||
if (fd->soundmap)
|
if (fd->soundmap)
|
||||||
oldnewmap_free(fd->soundmap);
|
oldnewmap_free(fd->soundmap);
|
||||||
if (fd->packedmap)
|
if (fd->packedmap)
|
||||||
@@ -1526,6 +1530,13 @@ static void *newimaadr(FileData *fd, const void *adr) /* used to restore im
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *newsceadr(FileData *fd, const void *adr) /* used to restore scene data after undo */
|
||||||
|
{
|
||||||
|
if (fd->scenemap && adr)
|
||||||
|
return oldnewmap_lookup_and_inc(fd->scenemap, adr, true);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void *newmclipadr(FileData *fd, const void *adr) /* used to restore movie clip data after undo */
|
static void *newmclipadr(FileData *fd, const void *adr) /* used to restore movie clip data after undo */
|
||||||
{
|
{
|
||||||
if (fd->movieclipmap && adr)
|
if (fd->movieclipmap && adr)
|
||||||
@@ -1631,6 +1642,37 @@ void blo_clear_proxy_pointers_from_lib(Main *oldmain)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blo_make_scene_pointer_map(FileData *fd, Main *oldmain)
|
||||||
|
{
|
||||||
|
Scene *sce = oldmain->scene.first;
|
||||||
|
|
||||||
|
fd->scenemap = oldnewmap_new();
|
||||||
|
|
||||||
|
for (; sce; sce = sce->id.next) {
|
||||||
|
if (sce->eevee.light_cache) {
|
||||||
|
struct LightCache *light_cache = sce->eevee.light_cache;
|
||||||
|
oldnewmap_insert(fd->scenemap, light_cache, light_cache, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void blo_end_scene_pointer_map(FileData *fd, Main *oldmain)
|
||||||
|
{
|
||||||
|
OldNew *entry = fd->scenemap->entries;
|
||||||
|
Scene *sce = oldmain->scene.first;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* used entries were restored, so we put them to zero */
|
||||||
|
for (i = 0; i < fd->scenemap->nentries; i++, entry++) {
|
||||||
|
if (entry->nr > 0)
|
||||||
|
entry->newp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; sce; sce = sce->id.next) {
|
||||||
|
sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
|
void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
|
||||||
{
|
{
|
||||||
Image *ima = oldmain->image.first;
|
Image *ima = oldmain->image.first;
|
||||||
@@ -2301,6 +2343,11 @@ static void direct_link_id(FileData *fd, ID *id)
|
|||||||
id->override_static = newdataadr(fd, id->override_static);
|
id->override_static = newdataadr(fd, id->override_static);
|
||||||
link_list_ex(fd, &id->override_static->properties, direct_link_id_override_property_cb);
|
link_list_ex(fd, &id->override_static->properties, direct_link_id_override_property_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
||||||
|
if (drawdata) {
|
||||||
|
BLI_listbase_clear((ListBase *)drawdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************ READ CurveMapping *************** */
|
/* ************ READ CurveMapping *************** */
|
||||||
@@ -5493,7 +5540,6 @@ static void direct_link_object(FileData *fd, Object *ob)
|
|||||||
ob->derivedFinal = NULL;
|
ob->derivedFinal = NULL;
|
||||||
BKE_object_runtime_reset(ob);
|
BKE_object_runtime_reset(ob);
|
||||||
BLI_listbase_clear(&ob->gpulamp);
|
BLI_listbase_clear(&ob->gpulamp);
|
||||||
BLI_listbase_clear(&ob->drawdata);
|
|
||||||
link_list(fd, &ob->pc_ids);
|
link_list(fd, &ob->pc_ids);
|
||||||
|
|
||||||
/* Runtime curve data */
|
/* Runtime curve data */
|
||||||
@@ -5740,6 +5786,41 @@ static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void direct_link_lightcache_texture(FileData *fd, LightCacheTexture *lctex)
|
||||||
|
{
|
||||||
|
lctex->tex = NULL;
|
||||||
|
|
||||||
|
if (lctex->data) {
|
||||||
|
lctex->data = newdataadr(fd, lctex->data);
|
||||||
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||||
|
int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] * lctex->tex_size[2];
|
||||||
|
|
||||||
|
if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
|
||||||
|
BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
|
||||||
|
}
|
||||||
|
else if (lctex->data_type == LIGHTCACHETEX_UINT) {
|
||||||
|
BLI_endian_switch_uint32_array((unsigned int *)lctex->data, data_size * sizeof(unsigned int));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void direct_link_lightcache(FileData *fd, LightCache *cache)
|
||||||
|
{
|
||||||
|
direct_link_lightcache_texture(fd, &cache->cube_tx);
|
||||||
|
direct_link_lightcache_texture(fd, &cache->grid_tx);
|
||||||
|
|
||||||
|
if (cache->cube_mips) {
|
||||||
|
cache->cube_mips = newdataadr(fd, cache->cube_mips);
|
||||||
|
for (int i = 0; i < cache->mips_len; ++i) {
|
||||||
|
direct_link_lightcache_texture(fd, &cache->cube_mips[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->cube_data = newdataadr(fd, cache->cube_data);
|
||||||
|
cache->grid_data = newdataadr(fd, cache->grid_data);
|
||||||
|
}
|
||||||
|
|
||||||
/* check for cyclic set-scene,
|
/* check for cyclic set-scene,
|
||||||
* libs can cause this case which is normally prevented, see (T#####) */
|
* libs can cause this case which is normally prevented, see (T#####) */
|
||||||
#define USE_SETSCENE_CHECK
|
#define USE_SETSCENE_CHECK
|
||||||
@@ -6300,6 +6381,19 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
|||||||
direct_link_view_layer(fd, view_layer);
|
direct_link_view_layer(fd, view_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fd->memfile) {
|
||||||
|
/* If it's undo try to recover the cache. */
|
||||||
|
if (fd->scenemap) sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
|
||||||
|
else sce->eevee.light_cache = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* else read the cache from file. */
|
||||||
|
if (sce->eevee.light_cache) {
|
||||||
|
sce->eevee.light_cache = newdataadr(fd, sce->eevee.light_cache);
|
||||||
|
direct_link_lightcache(fd, sce->eevee.light_cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sce->layer_properties = newdataadr(fd, sce->layer_properties);
|
sce->layer_properties = newdataadr(fd, sce->layer_properties);
|
||||||
IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
||||||
}
|
}
|
||||||
|
@@ -90,6 +90,7 @@ typedef struct FileData {
|
|||||||
struct OldNewMap *libmap;
|
struct OldNewMap *libmap;
|
||||||
struct OldNewMap *imamap;
|
struct OldNewMap *imamap;
|
||||||
struct OldNewMap *movieclipmap;
|
struct OldNewMap *movieclipmap;
|
||||||
|
struct OldNewMap *scenemap;
|
||||||
struct OldNewMap *soundmap;
|
struct OldNewMap *soundmap;
|
||||||
struct OldNewMap *packedmap;
|
struct OldNewMap *packedmap;
|
||||||
|
|
||||||
@@ -140,6 +141,8 @@ FileData *blo_openblendermemfile(struct MemFile *memfile, struct ReportList *rep
|
|||||||
void blo_clear_proxy_pointers_from_lib(Main *oldmain);
|
void blo_clear_proxy_pointers_from_lib(Main *oldmain);
|
||||||
void blo_make_image_pointer_map(FileData *fd, Main *oldmain);
|
void blo_make_image_pointer_map(FileData *fd, Main *oldmain);
|
||||||
void blo_end_image_pointer_map(FileData *fd, Main *oldmain);
|
void blo_end_image_pointer_map(FileData *fd, Main *oldmain);
|
||||||
|
void blo_make_scene_pointer_map(FileData *fd, Main *oldmain);
|
||||||
|
void blo_end_scene_pointer_map(FileData *fd, Main *oldmain);
|
||||||
void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain);
|
void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain);
|
||||||
void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain);
|
void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain);
|
||||||
void blo_make_sound_pointer_map(FileData *fd, Main *oldmain);
|
void blo_make_sound_pointer_map(FileData *fd, Main *oldmain);
|
||||||
|
@@ -1530,6 +1530,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "gi_cubemap_draw_size")) {
|
||||||
|
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
|
||||||
|
scene->eevee.gi_irradiance_draw_size = 0.2f;
|
||||||
|
scene->eevee.gi_cubemap_draw_size = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
|
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
|
||||||
if (scene->toolsettings->manipulator_flag == 0) {
|
if (scene->toolsettings->manipulator_flag == 0) {
|
||||||
scene->toolsettings->manipulator_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE;
|
scene->toolsettings->manipulator_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE;
|
||||||
|
@@ -2479,6 +2479,36 @@ static void write_view_layer(WriteData *wd, ViewLayer *view_layer)
|
|||||||
write_layer_collections(wd, &view_layer->layer_collections);
|
write_layer_collections(wd, &view_layer->layer_collections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_lightcache_texture(WriteData *wd, LightCacheTexture *tex)
|
||||||
|
{
|
||||||
|
if (tex->data) {
|
||||||
|
size_t data_size = tex->components * tex->tex_size[0] * tex->tex_size[1] * tex->tex_size[2];
|
||||||
|
if (tex->data_type == LIGHTCACHETEX_FLOAT) {
|
||||||
|
data_size *= sizeof(float);
|
||||||
|
}
|
||||||
|
else if (tex->data_type == LIGHTCACHETEX_UINT) {
|
||||||
|
data_size *= sizeof(unsigned int);
|
||||||
|
}
|
||||||
|
writedata(wd, DATA, data_size, tex->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_lightcache(WriteData *wd, LightCache *cache)
|
||||||
|
{
|
||||||
|
write_lightcache_texture(wd, &cache->grid_tx);
|
||||||
|
write_lightcache_texture(wd, &cache->cube_tx);
|
||||||
|
|
||||||
|
if (cache->cube_mips) {
|
||||||
|
writestruct(wd, DATA, LightCacheTexture, cache->mips_len, cache->cube_mips);
|
||||||
|
for (int i = 0; i < cache->mips_len; ++i) {
|
||||||
|
write_lightcache_texture(wd, &cache->cube_mips[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writestruct(wd, DATA, LightGridCache, cache->grid_len, cache->grid_data);
|
||||||
|
writestruct(wd, DATA, LightProbeCache, cache->cube_len, cache->cube_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void write_scene(WriteData *wd, Scene *sce)
|
static void write_scene(WriteData *wd, Scene *sce)
|
||||||
{
|
{
|
||||||
/* write LibData */
|
/* write LibData */
|
||||||
@@ -2679,6 +2709,12 @@ static void write_scene(WriteData *wd, Scene *sce)
|
|||||||
write_collection_nolib(wd, sce->master_collection);
|
write_collection_nolib(wd, sce->master_collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Eevee Lightcache */
|
||||||
|
if (sce->eevee.light_cache && !wd->use_memfile) {
|
||||||
|
writestruct(wd, DATA, LightCache, 1, sce->eevee.light_cache);
|
||||||
|
write_lightcache(wd, sce->eevee.light_cache);
|
||||||
|
}
|
||||||
|
|
||||||
/* Freed on doversion. */
|
/* Freed on doversion. */
|
||||||
BLI_assert(sce->layer_properties == NULL);
|
BLI_assert(sce->layer_properties == NULL);
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ set(INC
|
|||||||
../blenkernel
|
../blenkernel
|
||||||
../blenlib
|
../blenlib
|
||||||
../bmesh
|
../bmesh
|
||||||
|
../draw
|
||||||
../makesdna
|
../makesdna
|
||||||
../makesrna
|
../makesrna
|
||||||
../modifiers
|
../modifiers
|
||||||
|
@@ -873,9 +873,7 @@ void DepsgraphNodeBuilder::build_world(World *world)
|
|||||||
/* world itself */
|
/* world itself */
|
||||||
add_operation_node(&world->id,
|
add_operation_node(&world->id,
|
||||||
DEG_NODE_TYPE_SHADING,
|
DEG_NODE_TYPE_SHADING,
|
||||||
function_bind(BKE_world_eval,
|
NULL,
|
||||||
_1,
|
|
||||||
get_cow_datablock(world)),
|
|
||||||
DEG_OPCODE_WORLD_UPDATE);
|
DEG_OPCODE_WORLD_UPDATE);
|
||||||
/* world's nodetree */
|
/* world's nodetree */
|
||||||
if (world->nodetree != NULL) {
|
if (world->nodetree != NULL) {
|
||||||
|
@@ -553,6 +553,13 @@ void update_special_pointers(const Depsgraph *depsgraph,
|
|||||||
update_particle_system_orig_pointers(object_orig, object_cow);
|
update_particle_system_orig_pointers(object_orig, object_cow);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ID_SCE:
|
||||||
|
{
|
||||||
|
Scene *scene_cow = (Scene *)id_cow;
|
||||||
|
const Scene *scene_orig = (const Scene *)id_orig;
|
||||||
|
scene_cow->eevee.light_cache = scene_orig->eevee.light_cache;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -713,7 +720,7 @@ typedef struct ObjectRuntimeBackup {
|
|||||||
CurveCache *curve_cache;
|
CurveCache *curve_cache;
|
||||||
Object_Runtime runtime;
|
Object_Runtime runtime;
|
||||||
short base_flag;
|
short base_flag;
|
||||||
ListBase drawdata;
|
DrawDataList drawdata;
|
||||||
} ObjectRuntimeBackup;
|
} ObjectRuntimeBackup;
|
||||||
|
|
||||||
/* Make a backup of object's evaluation runtime data, additionally
|
/* Make a backup of object's evaluation runtime data, additionally
|
||||||
@@ -742,7 +749,7 @@ static void deg_backup_object_runtime(
|
|||||||
object_runtime_backup->base_flag = object->base_flag;
|
object_runtime_backup->base_flag = object->base_flag;
|
||||||
/* Make backup of object draw data.*/
|
/* Make backup of object draw data.*/
|
||||||
object_runtime_backup->drawdata = object->drawdata;
|
object_runtime_backup->drawdata = object->drawdata;
|
||||||
BLI_listbase_clear(&object->drawdata);
|
BLI_listbase_clear((ListBase *)&object->drawdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deg_restore_object_runtime(
|
static void deg_restore_object_runtime(
|
||||||
@@ -917,6 +924,12 @@ void discard_mesh_edit_mode_pointers(ID *id_cow)
|
|||||||
mesh_cow->edit_btmesh = NULL;
|
mesh_cow->edit_btmesh = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void discard_scene_pointers(ID *id_cow)
|
||||||
|
{
|
||||||
|
Scene *scene_cow = (Scene *)id_cow;
|
||||||
|
scene_cow->eevee.light_cache = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* NULL-ify all edit mode pointers which points to data from
|
/* NULL-ify all edit mode pointers which points to data from
|
||||||
* original object.
|
* original object.
|
||||||
*/
|
*/
|
||||||
@@ -939,6 +952,11 @@ void discard_edit_mode_pointers(ID *id_cow)
|
|||||||
case ID_LT:
|
case ID_LT:
|
||||||
discard_lattice_edit_mode_pointers(id_cow);
|
discard_lattice_edit_mode_pointers(id_cow);
|
||||||
break;
|
break;
|
||||||
|
case ID_SCE:
|
||||||
|
/* Not really edit mode but still needs to run before
|
||||||
|
* BKE_libblock_free_datablock() */
|
||||||
|
discard_scene_pointers(id_cow);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -46,6 +46,8 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
|
|
||||||
|
#include "DRW_engine.h"
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
||||||
#include "DEG_depsgraph.h"
|
#include "DEG_depsgraph.h"
|
||||||
@@ -219,12 +221,12 @@ BLI_INLINE OperationDepsNode *flush_schedule_children(
|
|||||||
|
|
||||||
void flush_engine_data_update(ID *id)
|
void flush_engine_data_update(ID *id)
|
||||||
{
|
{
|
||||||
if (GS(id->name) != ID_OB) {
|
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
||||||
|
if (drawdata == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Object *object = (Object *)id;
|
LISTBASE_FOREACH(DrawData *, dd, drawdata) {
|
||||||
LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) {
|
dd->recalc |= id->recalc;
|
||||||
engine_data->recalc |= id->recalc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -96,6 +96,7 @@ set(SRC
|
|||||||
engines/eevee/eevee_depth_of_field.c
|
engines/eevee/eevee_depth_of_field.c
|
||||||
engines/eevee/eevee_effects.c
|
engines/eevee/eevee_effects.c
|
||||||
engines/eevee/eevee_engine.c
|
engines/eevee/eevee_engine.c
|
||||||
|
engines/eevee/eevee_lightcache.c
|
||||||
engines/eevee/eevee_lightprobes.c
|
engines/eevee/eevee_lightprobes.c
|
||||||
engines/eevee/eevee_lights.c
|
engines/eevee/eevee_lights.c
|
||||||
engines/eevee/eevee_lookdev.c
|
engines/eevee/eevee_lookdev.c
|
||||||
@@ -137,6 +138,7 @@ set(SRC
|
|||||||
modes/edit_mesh_mode_intern.h
|
modes/edit_mesh_mode_intern.h
|
||||||
engines/basic/basic_engine.h
|
engines/basic/basic_engine.h
|
||||||
engines/eevee/eevee_engine.h
|
engines/eevee/eevee_engine.h
|
||||||
|
engines/eevee/eevee_lightcache.h
|
||||||
engines/eevee/eevee_lut.h
|
engines/eevee/eevee_lut.h
|
||||||
engines/eevee/eevee_private.h
|
engines/eevee/eevee_private.h
|
||||||
engines/external/external_engine.h
|
engines/external/external_engine.h
|
||||||
|
@@ -136,6 +136,14 @@ void DRW_opengl_context_destroy(void);
|
|||||||
void DRW_opengl_context_enable(void);
|
void DRW_opengl_context_enable(void);
|
||||||
void DRW_opengl_context_disable(void);
|
void DRW_opengl_context_disable(void);
|
||||||
|
|
||||||
|
void DRW_opengl_render_context_enable(void *re_gl_context);
|
||||||
|
void DRW_opengl_render_context_disable(void *re_gl_context);
|
||||||
|
void DRW_gawain_render_context_enable(void *re_gwn_context);
|
||||||
|
void DRW_gawain_render_context_disable(void *re_gwn_context);
|
||||||
|
|
||||||
void DRW_deferred_shader_remove(struct GPUMaterial *mat);
|
void DRW_deferred_shader_remove(struct GPUMaterial *mat);
|
||||||
|
|
||||||
|
struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id);
|
||||||
|
void DRW_drawdata_free(struct ID *id);
|
||||||
|
|
||||||
#endif /* __DRW_ENGINE_H__ */
|
#endif /* __DRW_ENGINE_H__ */
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "DRW_render.h"
|
#include "DRW_render.h"
|
||||||
|
|
||||||
#include "eevee_private.h"
|
#include "eevee_private.h"
|
||||||
|
#include "eevee_lightcache.h"
|
||||||
|
|
||||||
static void eevee_view_layer_data_free(void *storage)
|
static void eevee_view_layer_data_free(void *storage)
|
||||||
{
|
{
|
||||||
@@ -53,6 +54,11 @@ static void eevee_view_layer_data_free(void *storage)
|
|||||||
MEM_SAFE_FREE(sldata->shcasters_buffers[1].shadow_casters);
|
MEM_SAFE_FREE(sldata->shcasters_buffers[1].shadow_casters);
|
||||||
MEM_SAFE_FREE(sldata->shcasters_buffers[1].flags);
|
MEM_SAFE_FREE(sldata->shcasters_buffers[1].flags);
|
||||||
|
|
||||||
|
if (sldata->fallback_lightcache) {
|
||||||
|
EEVEE_lightcache_free(sldata->fallback_lightcache);
|
||||||
|
sldata->fallback_lightcache = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Probes */
|
/* Probes */
|
||||||
MEM_SAFE_FREE(sldata->probes);
|
MEM_SAFE_FREE(sldata->probes);
|
||||||
DRW_UBO_FREE_SAFE(sldata->probe_ubo);
|
DRW_UBO_FREE_SAFE(sldata->probe_ubo);
|
||||||
@@ -60,15 +66,6 @@ static void eevee_view_layer_data_free(void *storage)
|
|||||||
DRW_UBO_FREE_SAFE(sldata->planar_ubo);
|
DRW_UBO_FREE_SAFE(sldata->planar_ubo);
|
||||||
DRW_UBO_FREE_SAFE(sldata->common_ubo);
|
DRW_UBO_FREE_SAFE(sldata->common_ubo);
|
||||||
DRW_UBO_FREE_SAFE(sldata->clip_ubo);
|
DRW_UBO_FREE_SAFE(sldata->clip_ubo);
|
||||||
GPU_FRAMEBUFFER_FREE_SAFE(sldata->probe_filter_fb);
|
|
||||||
for (int i = 0; i < 6; ++i) {
|
|
||||||
GPU_FRAMEBUFFER_FREE_SAFE(sldata->probe_face_fb[i]);
|
|
||||||
}
|
|
||||||
DRW_TEXTURE_FREE_SAFE(sldata->probe_rt);
|
|
||||||
DRW_TEXTURE_FREE_SAFE(sldata->probe_depth_rt);
|
|
||||||
DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
|
|
||||||
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_pool);
|
|
||||||
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_rt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
|
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
|
||||||
@@ -77,6 +74,18 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
|
|||||||
&draw_engine_eevee_type);
|
&draw_engine_eevee_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer)
|
||||||
|
{
|
||||||
|
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure_ex(
|
||||||
|
view_layer, &draw_engine_eevee_type, &eevee_view_layer_data_free);
|
||||||
|
|
||||||
|
if (*sldata == NULL) {
|
||||||
|
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
|
||||||
|
}
|
||||||
|
|
||||||
|
return *sldata;
|
||||||
|
}
|
||||||
|
|
||||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
|
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
|
||||||
{
|
{
|
||||||
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure(
|
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure(
|
||||||
@@ -91,9 +100,9 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
|
|||||||
|
|
||||||
/* Object data. */
|
/* Object data. */
|
||||||
|
|
||||||
static void eevee_object_data_init(ObjectEngineData *engine_data)
|
static void eevee_object_data_init(DrawData *dd)
|
||||||
{
|
{
|
||||||
EEVEE_ObjectEngineData *eevee_data = (EEVEE_ObjectEngineData *)engine_data;
|
EEVEE_ObjectEngineData *eevee_data = (EEVEE_ObjectEngineData *)dd;
|
||||||
eevee_data->shadow_caster_id = -1;
|
eevee_data->shadow_caster_id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,15 +111,15 @@ EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob)
|
|||||||
if (ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP)) {
|
if (ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (EEVEE_ObjectEngineData *)DRW_object_engine_data_get(
|
return (EEVEE_ObjectEngineData *)DRW_drawdata_get(
|
||||||
ob, &draw_engine_eevee_type);
|
&ob->id, &draw_engine_eevee_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob)
|
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob)
|
||||||
{
|
{
|
||||||
BLI_assert(!ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP));
|
BLI_assert(!ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP));
|
||||||
return (EEVEE_ObjectEngineData *)DRW_object_engine_data_ensure(
|
return (EEVEE_ObjectEngineData *)DRW_drawdata_ensure(
|
||||||
ob,
|
&ob->id,
|
||||||
&draw_engine_eevee_type,
|
&draw_engine_eevee_type,
|
||||||
sizeof(EEVEE_ObjectEngineData),
|
sizeof(EEVEE_ObjectEngineData),
|
||||||
eevee_object_data_init,
|
eevee_object_data_init,
|
||||||
@@ -119,18 +128,10 @@ EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob)
|
|||||||
|
|
||||||
/* Light probe data. */
|
/* Light probe data. */
|
||||||
|
|
||||||
static void eevee_lightprobe_data_init(ObjectEngineData *engine_data)
|
static void eevee_lightprobe_data_init(DrawData *dd)
|
||||||
{
|
{
|
||||||
EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)engine_data;
|
EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)dd;
|
||||||
ped->need_full_update = true;
|
ped->need_update = false;
|
||||||
ped->need_update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eevee_lightprobe_data_free(ObjectEngineData *engine_data)
|
|
||||||
{
|
|
||||||
EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)engine_data;
|
|
||||||
|
|
||||||
BLI_freelistN(&ped->captured_object_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob)
|
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob)
|
||||||
@@ -138,26 +139,26 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob)
|
|||||||
if (ob->type != OB_LIGHTPROBE) {
|
if (ob->type != OB_LIGHTPROBE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (EEVEE_LightProbeEngineData *)DRW_object_engine_data_get(
|
return (EEVEE_LightProbeEngineData *)DRW_drawdata_get(
|
||||||
ob, &draw_engine_eevee_type);
|
&ob->id, &draw_engine_eevee_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob)
|
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob)
|
||||||
{
|
{
|
||||||
BLI_assert(ob->type == OB_LIGHTPROBE);
|
BLI_assert(ob->type == OB_LIGHTPROBE);
|
||||||
return (EEVEE_LightProbeEngineData *)DRW_object_engine_data_ensure(
|
return (EEVEE_LightProbeEngineData *)DRW_drawdata_ensure(
|
||||||
ob,
|
&ob->id,
|
||||||
&draw_engine_eevee_type,
|
&draw_engine_eevee_type,
|
||||||
sizeof(EEVEE_LightProbeEngineData),
|
sizeof(EEVEE_LightProbeEngineData),
|
||||||
eevee_lightprobe_data_init,
|
eevee_lightprobe_data_init,
|
||||||
eevee_lightprobe_data_free);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lamp data. */
|
/* Lamp data. */
|
||||||
|
|
||||||
static void eevee_lamp_data_init(ObjectEngineData *engine_data)
|
static void eevee_lamp_data_init(DrawData *dd)
|
||||||
{
|
{
|
||||||
EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)engine_data;
|
EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)dd;
|
||||||
led->need_update = true;
|
led->need_update = true;
|
||||||
led->prev_cube_shadow_id = -1;
|
led->prev_cube_shadow_id = -1;
|
||||||
}
|
}
|
||||||
@@ -167,17 +168,41 @@ EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob)
|
|||||||
if (ob->type != OB_LAMP) {
|
if (ob->type != OB_LAMP) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (EEVEE_LampEngineData *)DRW_object_engine_data_get(
|
return (EEVEE_LampEngineData *)DRW_drawdata_get(
|
||||||
ob, &draw_engine_eevee_type);
|
&ob->id, &draw_engine_eevee_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob)
|
EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob)
|
||||||
{
|
{
|
||||||
BLI_assert(ob->type == OB_LAMP);
|
BLI_assert(ob->type == OB_LAMP);
|
||||||
return (EEVEE_LampEngineData *)DRW_object_engine_data_ensure(
|
return (EEVEE_LampEngineData *)DRW_drawdata_ensure(
|
||||||
ob,
|
&ob->id,
|
||||||
&draw_engine_eevee_type,
|
&draw_engine_eevee_type,
|
||||||
sizeof(EEVEE_LampEngineData),
|
sizeof(EEVEE_LampEngineData),
|
||||||
eevee_lamp_data_init,
|
eevee_lamp_data_init,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* World data. */
|
||||||
|
|
||||||
|
static void eevee_world_data_init(DrawData *dd)
|
||||||
|
{
|
||||||
|
EEVEE_WorldEngineData *wed = (EEVEE_WorldEngineData *)dd;
|
||||||
|
wed->dd.recalc |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EEVEE_WorldEngineData *EEVEE_world_data_get(World *wo)
|
||||||
|
{
|
||||||
|
return (EEVEE_WorldEngineData *)DRW_drawdata_get(
|
||||||
|
&wo->id, &draw_engine_eevee_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
EEVEE_WorldEngineData *EEVEE_world_data_ensure(World *wo)
|
||||||
|
{
|
||||||
|
return (EEVEE_WorldEngineData *)DRW_drawdata_ensure(
|
||||||
|
&wo->id,
|
||||||
|
&draw_engine_eevee_type,
|
||||||
|
sizeof(EEVEE_WorldEngineData),
|
||||||
|
eevee_world_data_init,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
@@ -123,7 +123,7 @@ static void eevee_cache_init(void *vedata)
|
|||||||
EEVEE_volumes_cache_init(sldata, vedata);
|
EEVEE_volumes_cache_init(sldata, vedata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eevee_cache_populate(void *vedata, Object *ob)
|
void EEVEE_cache_populate(void *vedata, Object *ob)
|
||||||
{
|
{
|
||||||
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ static void eevee_cache_populate(void *vedata, Object *ob)
|
|||||||
/* TODO: Special case for dupli objects because we cannot save the object pointer. */
|
/* TODO: Special case for dupli objects because we cannot save the object pointer. */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EEVEE_lightprobes_cache_add(sldata, ob);
|
EEVEE_lightprobes_cache_add(sldata, vedata, ob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ob->type == OB_LAMP) {
|
else if (ob->type == OB_LAMP) {
|
||||||
@@ -282,7 +282,9 @@ static void eevee_draw_background(void *vedata)
|
|||||||
EEVEE_subsurface_compute(sldata, vedata);
|
EEVEE_subsurface_compute(sldata, vedata);
|
||||||
EEVEE_reflection_compute(sldata, vedata);
|
EEVEE_reflection_compute(sldata, vedata);
|
||||||
EEVEE_occlusion_draw_debug(sldata, vedata);
|
EEVEE_occlusion_draw_debug(sldata, vedata);
|
||||||
DRW_draw_pass(psl->probe_display);
|
if (psl->probe_display) {
|
||||||
|
DRW_draw_pass(psl->probe_display);
|
||||||
|
}
|
||||||
EEVEE_refraction_compute(sldata, vedata);
|
EEVEE_refraction_compute(sldata, vedata);
|
||||||
|
|
||||||
/* Opaque refraction */
|
/* Opaque refraction */
|
||||||
@@ -365,21 +367,35 @@ static void eevee_view_update(void *vedata)
|
|||||||
|
|
||||||
static void eevee_id_object_update(void *UNUSED(vedata), Object *object)
|
static void eevee_id_object_update(void *UNUSED(vedata), Object *object)
|
||||||
{
|
{
|
||||||
/* This is a bit mask of components which update is to be ignored. */
|
|
||||||
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object);
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object);
|
||||||
if (ped != NULL && ped->engine_data.recalc != 0) {
|
if (ped != NULL && ped->dd.recalc != 0) {
|
||||||
ped->need_full_update = true;
|
ped->need_update = (ped->dd.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_COPY_ON_WRITE)) != 0;
|
||||||
ped->engine_data.recalc = 0;
|
ped->dd.recalc = 0;
|
||||||
}
|
}
|
||||||
EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object);
|
EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object);
|
||||||
if (led != NULL && led->engine_data.recalc != 0) {
|
if (led != NULL && led->dd.recalc != 0) {
|
||||||
led->need_update = true;
|
led->need_update = true;
|
||||||
led->engine_data.recalc = 0;
|
led->dd.recalc = 0;
|
||||||
}
|
}
|
||||||
EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object);
|
EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object);
|
||||||
if (oedata != NULL && oedata->engine_data.recalc != 0) {
|
if (oedata != NULL && oedata->dd.recalc != 0) {
|
||||||
oedata->need_update = true;
|
oedata->need_update = true;
|
||||||
oedata->engine_data.recalc = 0;
|
oedata->dd.recalc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eevee_id_world_update(void *vedata, World *wo)
|
||||||
|
{
|
||||||
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
||||||
|
LightCache *lcache = stl->g_data->light_cache;
|
||||||
|
|
||||||
|
EEVEE_WorldEngineData *wedata = EEVEE_world_data_ensure(wo);
|
||||||
|
|
||||||
|
if (wedata != NULL && wedata->dd.recalc != 0) {
|
||||||
|
if ((lcache->flag & (LIGHTCACHE_BAKED | LIGHTCACHE_BAKING)) == 0) {
|
||||||
|
lcache->flag |= LIGHTCACHE_UPDATE_WORLD;
|
||||||
|
}
|
||||||
|
wedata->dd.recalc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +403,9 @@ static void eevee_id_update(void *vedata, ID *id)
|
|||||||
{
|
{
|
||||||
/* Handle updates based on ID type. */
|
/* Handle updates based on ID type. */
|
||||||
switch (GS(id->name)) {
|
switch (GS(id->name)) {
|
||||||
|
case ID_WO:
|
||||||
|
eevee_id_world_update(vedata, (World *)id);
|
||||||
|
break;
|
||||||
case ID_OB:
|
case ID_OB:
|
||||||
eevee_id_object_update(vedata, (Object *)id);
|
eevee_id_object_update(vedata, (Object *)id);
|
||||||
break;
|
break;
|
||||||
@@ -433,7 +452,7 @@ DrawEngineType draw_engine_eevee_type = {
|
|||||||
&eevee_engine_init,
|
&eevee_engine_init,
|
||||||
&eevee_engine_free,
|
&eevee_engine_free,
|
||||||
&eevee_cache_init,
|
&eevee_cache_init,
|
||||||
&eevee_cache_populate,
|
&EEVEE_cache_populate,
|
||||||
&eevee_cache_finish,
|
&eevee_cache_finish,
|
||||||
&eevee_draw_background,
|
&eevee_draw_background,
|
||||||
NULL, /* Everything is drawn in the background pass (see comment on function) */
|
NULL, /* Everything is drawn in the background pass (see comment on function) */
|
||||||
|
1134
source/blender/draw/engines/eevee/eevee_lightcache.c
Normal file
1134
source/blender/draw/engines/eevee/eevee_lightcache.c
Normal file
File diff suppressed because it is too large
Load Diff
59
source/blender/draw/engines/eevee/eevee_lightcache.h
Normal file
59
source/blender/draw/engines/eevee/eevee_lightcache.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018, 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 eevee_lightcache.h
|
||||||
|
* \ingroup eevee
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EEVEE_LIGHTCACHE_H__
|
||||||
|
#define __EEVEE_LIGHTCACHE_H__
|
||||||
|
|
||||||
|
#include "BLI_sys_types.h" /* for bool */
|
||||||
|
|
||||||
|
struct ViewLayer;
|
||||||
|
struct Scene;
|
||||||
|
struct SceneEEVEE;
|
||||||
|
struct LightCache;
|
||||||
|
struct EEVEE_ViewLayerData;
|
||||||
|
struct EEVEE_Data;
|
||||||
|
struct EEVEE_LightBake;
|
||||||
|
|
||||||
|
/* Light Bake */
|
||||||
|
struct wmJob *EEVEE_lightbake_job_create(
|
||||||
|
struct wmWindowManager *wm, struct wmWindow *win, struct Main *bmain,
|
||||||
|
struct ViewLayer *view_layer, struct Scene *scene, int delay);
|
||||||
|
void *EEVEE_lightbake_job_data_alloc(struct Main *bmain, struct ViewLayer *viewlayer, struct Scene *scene, bool run_as_job);
|
||||||
|
void EEVEE_lightbake_job_data_free(void *custom_data);
|
||||||
|
void EEVEE_lightbake_update(void *custom_data);
|
||||||
|
void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress);
|
||||||
|
|
||||||
|
void EEVEE_lightbake_update_world_quick(struct EEVEE_ViewLayerData *sldata, struct EEVEE_Data *vedata, const Scene *scene);
|
||||||
|
|
||||||
|
/* Light Cache */
|
||||||
|
struct LightCache *EEVEE_lightcache_create(
|
||||||
|
const int grid_len, const int cube_len,
|
||||||
|
const int cube_size, const int vis_size,
|
||||||
|
const int irr_size[3]);
|
||||||
|
void EEVEE_lightcache_free(struct LightCache *lcache);
|
||||||
|
void EEVEE_lightcache_load(struct LightCache *lcache);
|
||||||
|
void EEVEE_lightcache_info_update(struct SceneEEVEE *eevee);
|
||||||
|
|
||||||
|
#endif /* __EEVEE_LIGHTCACHE_H__ */
|
File diff suppressed because it is too large
Load Diff
@@ -148,7 +148,7 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
|
|||||||
DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_blur);
|
DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_blur);
|
||||||
|
|
||||||
/* Compute adequate size for the octahedral map. */
|
/* Compute adequate size for the octahedral map. */
|
||||||
linfo->shadow_cube_store_size = (int)ceil(sqrt((sh_cube_size * sh_cube_size) * 6.0f));
|
linfo->shadow_cube_store_size = OCTAHEDRAL_SIZE_FROM_CUBESIZE(sh_cube_size);
|
||||||
|
|
||||||
CLAMP(linfo->shadow_cube_store_size, 1, 4096);
|
CLAMP(linfo->shadow_cube_store_size, 1, 4096);
|
||||||
CLAMP(sh_cube_size, 1, 4096);
|
CLAMP(sh_cube_size, 1, 4096);
|
||||||
|
@@ -30,15 +30,31 @@
|
|||||||
#include "DNA_screen_types.h"
|
#include "DNA_screen_types.h"
|
||||||
#include "DNA_world_types.h"
|
#include "DNA_world_types.h"
|
||||||
|
|
||||||
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
|
|
||||||
#include "eevee_private.h"
|
#include "eevee_private.h"
|
||||||
|
#include "eevee_lightcache.h"
|
||||||
|
|
||||||
|
static void eevee_lookdev_lightcache_delete(EEVEE_Data *vedata)
|
||||||
|
{
|
||||||
|
EEVEE_StorageList *stl = vedata->stl;
|
||||||
|
EEVEE_TextureList *txl = vedata->txl;
|
||||||
|
|
||||||
|
MEM_SAFE_FREE(stl->lookdev_lightcache);
|
||||||
|
MEM_SAFE_FREE(stl->lookdev_grid_data);
|
||||||
|
MEM_SAFE_FREE(stl->lookdev_cube_data);
|
||||||
|
DRW_TEXTURE_FREE_SAFE(txl->lookdev_grid_tx);
|
||||||
|
DRW_TEXTURE_FREE_SAFE(txl->lookdev_cube_tx);
|
||||||
|
}
|
||||||
|
|
||||||
void EEVEE_lookdev_cache_init(
|
void EEVEE_lookdev_cache_init(
|
||||||
EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass,
|
EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass,
|
||||||
World *world, EEVEE_LightProbesInfo *pinfo)
|
World *world, EEVEE_LightProbesInfo *pinfo)
|
||||||
{
|
{
|
||||||
EEVEE_StorageList *stl = vedata->stl;
|
EEVEE_StorageList *stl = vedata->stl;
|
||||||
|
EEVEE_TextureList *txl = vedata->txl;
|
||||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||||
View3D *v3d = draw_ctx->v3d;
|
View3D *v3d = draw_ctx->v3d;
|
||||||
if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
|
if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
|
||||||
@@ -47,6 +63,43 @@ void EEVEE_lookdev_cache_init(
|
|||||||
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
||||||
GPUTexture *tex = NULL;
|
GPUTexture *tex = NULL;
|
||||||
|
|
||||||
|
/* If one of the component is missing we start from scratch. */
|
||||||
|
if ((stl->lookdev_grid_data == NULL) ||
|
||||||
|
(stl->lookdev_cube_data == NULL) ||
|
||||||
|
(txl->lookdev_grid_tx == NULL) ||
|
||||||
|
(txl->lookdev_cube_tx == NULL))
|
||||||
|
{
|
||||||
|
eevee_lookdev_lightcache_delete(vedata);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stl->lookdev_lightcache == NULL) {
|
||||||
|
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
||||||
|
#if defined(IRRADIANCE_SH_L2)
|
||||||
|
int grid_res = 4;
|
||||||
|
#elif defined(IRRADIANCE_CUBEMAP)
|
||||||
|
int grid_res = 8;
|
||||||
|
#elif defined(IRRADIANCE_HL2)
|
||||||
|
int grid_res = 4;
|
||||||
|
#endif
|
||||||
|
int cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(scene_eval->eevee.gi_cubemap_resolution);
|
||||||
|
int vis_res = scene_eval->eevee.gi_visibility_resolution;
|
||||||
|
|
||||||
|
stl->lookdev_lightcache = EEVEE_lightcache_create(1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
|
||||||
|
|
||||||
|
/* We do this to use a special light cache for lookdev.
|
||||||
|
* This lightcache needs to be per viewport. But we need to
|
||||||
|
* have correct freeing when the viewport is closed. So we
|
||||||
|
* need to reference all textures to the txl and the memblocks
|
||||||
|
* to the stl. */
|
||||||
|
stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
|
||||||
|
stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
|
||||||
|
stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
|
||||||
|
txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
|
||||||
|
txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
stl->g_data->light_cache = stl->lookdev_lightcache;
|
||||||
|
|
||||||
*grp = DRW_shgroup_create(shader, pass);
|
*grp = DRW_shgroup_create(shader, pass);
|
||||||
axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
|
axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
|
||||||
DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
|
DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
|
||||||
@@ -77,11 +130,9 @@ void EEVEE_lookdev_cache_init(
|
|||||||
((pinfo->studiolight_index != sl->index) ||
|
((pinfo->studiolight_index != sl->index) ||
|
||||||
(pinfo->studiolight_rot_z != v3d->shading.studiolight_rot_z)))
|
(pinfo->studiolight_rot_z != v3d->shading.studiolight_rot_z)))
|
||||||
{
|
{
|
||||||
pinfo->update_world |= PROBE_UPDATE_ALL;
|
stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
|
||||||
pinfo->studiolight_index = sl->index;
|
pinfo->studiolight_index = sl->index;
|
||||||
pinfo->studiolight_rot_z = v3d->shading.studiolight_rot_z;
|
pinfo->studiolight_rot_z = v3d->shading.studiolight_rot_z;
|
||||||
pinfo->prev_wo_sh_compiled = false;
|
|
||||||
pinfo->prev_world = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -362,6 +362,8 @@ static void add_standard_uniforms(
|
|||||||
DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
||||||
int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend)
|
int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend)
|
||||||
{
|
{
|
||||||
|
LightCache *lcache = vedata->stl->g_data->light_cache;
|
||||||
|
|
||||||
if (ssr_id == NULL) {
|
if (ssr_id == NULL) {
|
||||||
static int no_ssr = -1.0f;
|
static int no_ssr = -1.0f;
|
||||||
ssr_id = &no_ssr;
|
ssr_id = &no_ssr;
|
||||||
@@ -393,12 +395,12 @@ static void add_standard_uniforms(
|
|||||||
|
|
||||||
/* TODO if diffuse bsdf */
|
/* TODO if diffuse bsdf */
|
||||||
if (true) {
|
if (true) {
|
||||||
DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &sldata->irradiance_pool);
|
DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO if glossy bsdf */
|
/* TODO if glossy bsdf */
|
||||||
if (true) {
|
if (true) {
|
||||||
DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &sldata->probe_pool);
|
DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &lcache->cube_tx.tex);
|
||||||
DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool);
|
DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool);
|
||||||
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
|
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
|
||||||
}
|
}
|
||||||
@@ -654,14 +656,14 @@ struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, Wor
|
|||||||
const void *engine = &DRW_engine_viewport_eevee_type;
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
||||||
const int options = VAR_WORLD_PROBE;
|
const int options = VAR_WORLD_PROBE;
|
||||||
|
|
||||||
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
|
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, false);
|
||||||
if (mat != NULL) {
|
if (mat != NULL) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
return DRW_shader_create_from_world(
|
return DRW_shader_create_from_world(
|
||||||
scene, wo, engine, options,
|
scene, wo, engine, options,
|
||||||
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
|
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
|
||||||
SHADER_DEFINES "#define PROBE_CAPTURE\n");
|
SHADER_DEFINES "#define PROBE_CAPTURE\n", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo)
|
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo)
|
||||||
@@ -669,14 +671,14 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, Wor
|
|||||||
const void *engine = &DRW_engine_viewport_eevee_type;
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
||||||
int options = VAR_WORLD_BACKGROUND;
|
int options = VAR_WORLD_BACKGROUND;
|
||||||
|
|
||||||
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
|
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, true);
|
||||||
if (mat != NULL) {
|
if (mat != NULL) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
return DRW_shader_create_from_world(
|
return DRW_shader_create_from_world(
|
||||||
scene, wo, engine, options,
|
scene, wo, engine, options,
|
||||||
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
|
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
|
||||||
SHADER_DEFINES "#define WORLD_BACKGROUND\n");
|
SHADER_DEFINES "#define WORLD_BACKGROUND\n", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *wo)
|
struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *wo)
|
||||||
@@ -684,7 +686,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
|
|||||||
const void *engine = &DRW_engine_viewport_eevee_type;
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
||||||
int options = VAR_WORLD_VOLUME;
|
int options = VAR_WORLD_VOLUME;
|
||||||
|
|
||||||
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
|
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, true);
|
||||||
if (mat != NULL) {
|
if (mat != NULL) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
@@ -694,7 +696,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
|
|||||||
mat = DRW_shader_create_from_world(
|
mat = DRW_shader_create_from_world(
|
||||||
scene, wo, engine, options,
|
scene, wo, engine, options,
|
||||||
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
|
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
|
||||||
defines);
|
defines, true);
|
||||||
|
|
||||||
MEM_freeN(defines);
|
MEM_freeN(defines);
|
||||||
|
|
||||||
@@ -719,7 +721,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
|
|||||||
|
|
||||||
options |= eevee_material_shadow_option(shadow_method);
|
options |= eevee_material_shadow_option(shadow_method);
|
||||||
|
|
||||||
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
|
||||||
if (mat) {
|
if (mat) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
@@ -729,7 +731,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
|
|||||||
mat = DRW_shader_create_from_material(
|
mat = DRW_shader_create_from_material(
|
||||||
scene, ma, engine, options,
|
scene, ma, engine, options,
|
||||||
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
|
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
|
||||||
defines);
|
defines, true);
|
||||||
|
|
||||||
MEM_freeN(defines);
|
MEM_freeN(defines);
|
||||||
|
|
||||||
@@ -741,7 +743,7 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
|
|||||||
const void *engine = &DRW_engine_viewport_eevee_type;
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
||||||
int options = VAR_MAT_VOLUME;
|
int options = VAR_MAT_VOLUME;
|
||||||
|
|
||||||
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
|
||||||
if (mat != NULL) {
|
if (mat != NULL) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
@@ -751,7 +753,7 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
|
|||||||
mat = DRW_shader_create_from_material(
|
mat = DRW_shader_create_from_material(
|
||||||
scene, ma, engine, options,
|
scene, ma, engine, options,
|
||||||
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
|
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
|
||||||
defines);
|
defines, true);
|
||||||
|
|
||||||
MEM_freeN(defines);
|
MEM_freeN(defines);
|
||||||
|
|
||||||
@@ -775,7 +777,7 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
|
|||||||
if (is_shadow)
|
if (is_shadow)
|
||||||
options |= VAR_MAT_SHADOW;
|
options |= VAR_MAT_SHADOW;
|
||||||
|
|
||||||
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
|
||||||
if (mat) {
|
if (mat) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
@@ -791,7 +793,8 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
|
|||||||
(is_shadow) ? datatoc_shadow_vert_glsl : e_data.vert_shader_str,
|
(is_shadow) ? datatoc_shadow_vert_glsl : e_data.vert_shader_str,
|
||||||
NULL,
|
NULL,
|
||||||
frag_str,
|
frag_str,
|
||||||
defines);
|
defines,
|
||||||
|
true);
|
||||||
|
|
||||||
MEM_freeN(frag_str);
|
MEM_freeN(frag_str);
|
||||||
MEM_freeN(defines);
|
MEM_freeN(defines);
|
||||||
@@ -807,7 +810,7 @@ struct GPUMaterial *EEVEE_material_hair_get(
|
|||||||
|
|
||||||
options |= eevee_material_shadow_option(shadow_method);
|
options |= eevee_material_shadow_option(shadow_method);
|
||||||
|
|
||||||
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
|
||||||
if (mat) {
|
if (mat) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
@@ -817,7 +820,7 @@ struct GPUMaterial *EEVEE_material_hair_get(
|
|||||||
mat = DRW_shader_create_from_material(
|
mat = DRW_shader_create_from_material(
|
||||||
scene, ma, engine, options,
|
scene, ma, engine, options,
|
||||||
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
|
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
|
||||||
defines);
|
defines, true);
|
||||||
|
|
||||||
MEM_freeN(defines);
|
MEM_freeN(defines);
|
||||||
|
|
||||||
@@ -971,7 +974,6 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||||||
DRW_shgroup_call_add(grp, geom, NULL);
|
DRW_shgroup_call_add(grp, geom, NULL);
|
||||||
break;
|
break;
|
||||||
case GPU_MAT_QUEUED:
|
case GPU_MAT_QUEUED:
|
||||||
sldata->probes->all_materials_updated = false;
|
|
||||||
/* TODO Bypass probe compilation. */
|
/* TODO Bypass probe compilation. */
|
||||||
col = compile_col;
|
col = compile_col;
|
||||||
break;
|
break;
|
||||||
@@ -1228,7 +1230,6 @@ static void material_opaque(
|
|||||||
}
|
}
|
||||||
case GPU_MAT_QUEUED:
|
case GPU_MAT_QUEUED:
|
||||||
{
|
{
|
||||||
sldata->probes->all_materials_updated = false;
|
|
||||||
/* TODO Bypass probe compilation. */
|
/* TODO Bypass probe compilation. */
|
||||||
color_p = compile_col;
|
color_p = compile_col;
|
||||||
metal_p = spec_p = rough_p = ½
|
metal_p = spec_p = rough_p = ½
|
||||||
@@ -1315,7 +1316,6 @@ static void material_transparent(
|
|||||||
}
|
}
|
||||||
case GPU_MAT_QUEUED:
|
case GPU_MAT_QUEUED:
|
||||||
{
|
{
|
||||||
sldata->probes->all_materials_updated = false;
|
|
||||||
/* TODO Bypass probe compilation. */
|
/* TODO Bypass probe compilation. */
|
||||||
color_p = compile_col;
|
color_p = compile_col;
|
||||||
metal_p = spec_p = rough_p = ½
|
metal_p = spec_p = rough_p = ½
|
||||||
@@ -1645,7 +1645,6 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata,
|
|||||||
}
|
}
|
||||||
case GPU_MAT_QUEUED:
|
case GPU_MAT_QUEUED:
|
||||||
{
|
{
|
||||||
sldata->probes->all_materials_updated = false;
|
|
||||||
color_p = compile_col;
|
color_p = compile_col;
|
||||||
metal_p = spec_p = rough_p = ½
|
metal_p = spec_p = rough_p = ½
|
||||||
break;
|
break;
|
||||||
|
@@ -26,11 +26,14 @@
|
|||||||
#ifndef __EEVEE_PRIVATE_H__
|
#ifndef __EEVEE_PRIVATE_H__
|
||||||
#define __EEVEE_PRIVATE_H__
|
#define __EEVEE_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "DNA_lightprobe_types.h"
|
||||||
|
|
||||||
struct Object;
|
struct Object;
|
||||||
struct EEVEE_BoundSphere;
|
struct EEVEE_BoundSphere;
|
||||||
struct EEVEE_ShadowCasterBuffer;
|
struct EEVEE_ShadowCasterBuffer;
|
||||||
struct RenderLayer;
|
struct RenderLayer;
|
||||||
struct RenderResult;
|
struct RenderResult;
|
||||||
|
struct GPUFrameBuffer;
|
||||||
|
|
||||||
extern struct DrawEngineType draw_engine_eevee_type;
|
extern struct DrawEngineType draw_engine_eevee_type;
|
||||||
|
|
||||||
@@ -98,6 +101,10 @@ extern struct DrawEngineType draw_engine_eevee_type;
|
|||||||
#define USE_SCENE_LIGHT(v3d) ((!v3d) || (!LOOK_DEV_MODE_ENABLED(v3d)) || ((LOOK_DEV_MODE_ENABLED(v3d) && (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS))))
|
#define USE_SCENE_LIGHT(v3d) ((!v3d) || (!LOOK_DEV_MODE_ENABLED(v3d)) || ((LOOK_DEV_MODE_ENABLED(v3d) && (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS))))
|
||||||
#define LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d) (LOOK_DEV_MODE_ENABLED(v3d) && !(v3d->shading.flag & V3D_SHADING_SCENE_WORLD))
|
#define LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d) (LOOK_DEV_MODE_ENABLED(v3d) && !(v3d->shading.flag & V3D_SHADING_SCENE_WORLD))
|
||||||
|
|
||||||
|
#define OCTAHEDRAL_SIZE_FROM_CUBESIZE(cube_size) ((int)ceilf(sqrtf((cube_size * cube_size) * 6.0f)))
|
||||||
|
#define MIN_CUBE_LOD_LEVEL 3
|
||||||
|
#define MAX_PLANAR_LOD_LEVEL 9
|
||||||
|
|
||||||
/* World shader variations */
|
/* World shader variations */
|
||||||
enum {
|
enum {
|
||||||
VAR_WORLD_BACKGROUND = 0,
|
VAR_WORLD_BACKGROUND = 0,
|
||||||
@@ -132,6 +139,27 @@ enum {
|
|||||||
VAR_MAT_SSSALBED = (1 << 17),
|
VAR_MAT_SSSALBED = (1 << 17),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ************ PROBE UBO ************* */
|
||||||
|
|
||||||
|
/* They are the same struct as their Cache siblings.
|
||||||
|
* typedef'ing just to keep the naming consistent with
|
||||||
|
* other eevee types. */
|
||||||
|
typedef LightProbeCache EEVEE_LightProbe;
|
||||||
|
typedef LightGridCache EEVEE_LightGrid;
|
||||||
|
|
||||||
|
typedef struct EEVEE_PlanarReflection {
|
||||||
|
float plane_equation[4];
|
||||||
|
float clip_vec_x[3], attenuation_scale;
|
||||||
|
float clip_vec_y[3], attenuation_bias;
|
||||||
|
float clip_edge_x_pos, clip_edge_x_neg;
|
||||||
|
float clip_edge_y_pos, clip_edge_y_neg;
|
||||||
|
float facing_scale, facing_bias, clipsta, pad;
|
||||||
|
float reflectionmat[4][4]; /* Used for sampling the texture. */
|
||||||
|
float mtx[4][4]; /* Not used in shader. TODO move elsewhere. */
|
||||||
|
} EEVEE_PlanarReflection;
|
||||||
|
|
||||||
|
/* --------------------------------------- */
|
||||||
|
|
||||||
typedef struct EEVEE_BoundSphere {
|
typedef struct EEVEE_BoundSphere {
|
||||||
float center[3], radius;
|
float center[3], radius;
|
||||||
} EEVEE_BoundSphere;
|
} EEVEE_BoundSphere;
|
||||||
@@ -272,6 +300,9 @@ typedef struct EEVEE_TextureList {
|
|||||||
struct GPUTexture *volume_scatter_history;
|
struct GPUTexture *volume_scatter_history;
|
||||||
struct GPUTexture *volume_transmittance_history;
|
struct GPUTexture *volume_transmittance_history;
|
||||||
|
|
||||||
|
struct GPUTexture *lookdev_grid_tx;
|
||||||
|
struct GPUTexture *lookdev_cube_tx;
|
||||||
|
|
||||||
struct GPUTexture *planar_pool;
|
struct GPUTexture *planar_pool;
|
||||||
struct GPUTexture *planar_depth;
|
struct GPUTexture *planar_depth;
|
||||||
|
|
||||||
@@ -288,6 +319,10 @@ typedef struct EEVEE_StorageList {
|
|||||||
|
|
||||||
struct EEVEE_PrivateData *g_data;
|
struct EEVEE_PrivateData *g_data;
|
||||||
|
|
||||||
|
struct LightCache *lookdev_lightcache;
|
||||||
|
EEVEE_LightProbe *lookdev_cube_data;
|
||||||
|
EEVEE_LightGrid *lookdev_grid_data;
|
||||||
|
LightCacheTexture *lookdev_cube_mips;
|
||||||
} EEVEE_StorageList;
|
} EEVEE_StorageList;
|
||||||
|
|
||||||
/* ************ LIGHT UBO ************* */
|
/* ************ LIGHT UBO ************* */
|
||||||
@@ -392,42 +427,11 @@ enum {
|
|||||||
LIGHT_UPDATE_SHADOW_CUBE = (1 << 0),
|
LIGHT_UPDATE_SHADOW_CUBE = (1 << 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************ PROBE UBO ************* */
|
|
||||||
typedef struct EEVEE_LightProbe {
|
|
||||||
float position[3], parallax_type;
|
|
||||||
float attenuation_fac;
|
|
||||||
float attenuation_type;
|
|
||||||
float pad3[2];
|
|
||||||
float attenuationmat[4][4];
|
|
||||||
float parallaxmat[4][4];
|
|
||||||
} EEVEE_LightProbe;
|
|
||||||
|
|
||||||
typedef struct EEVEE_LightGrid {
|
|
||||||
float mat[4][4];
|
|
||||||
int resolution[3], offset;
|
|
||||||
float corner[3], attenuation_scale;
|
|
||||||
float increment_x[3], attenuation_bias; /* world space vector between 2 opposite cells */
|
|
||||||
float increment_y[3], level_bias;
|
|
||||||
float increment_z[3], pad4;
|
|
||||||
float visibility_bias, visibility_bleed, visibility_range, pad5;
|
|
||||||
} EEVEE_LightGrid;
|
|
||||||
|
|
||||||
typedef struct EEVEE_PlanarReflection {
|
|
||||||
float plane_equation[4];
|
|
||||||
float clip_vec_x[3], attenuation_scale;
|
|
||||||
float clip_vec_y[3], attenuation_bias;
|
|
||||||
float clip_edge_x_pos, clip_edge_x_neg;
|
|
||||||
float clip_edge_y_pos, clip_edge_y_neg;
|
|
||||||
float facing_scale, facing_bias, pad[2];
|
|
||||||
float reflectionmat[4][4];
|
|
||||||
} EEVEE_PlanarReflection;
|
|
||||||
|
|
||||||
/* ************ PROBE DATA ************* */
|
/* ************ PROBE DATA ************* */
|
||||||
|
|
||||||
typedef struct EEVEE_LightProbeVisTest {
|
typedef struct EEVEE_LightProbeVisTest {
|
||||||
|
struct Collection *collection; /* Skip test if NULL */
|
||||||
bool invert;
|
bool invert;
|
||||||
bool cached; /* Reuse last test results */
|
bool cached; /* Reuse last test results */
|
||||||
struct Collection *collection; /* Skip test if NULL */
|
|
||||||
} EEVEE_LightProbeVisTest;
|
} EEVEE_LightProbeVisTest;
|
||||||
|
|
||||||
typedef struct EEVEE_LightProbesInfo {
|
typedef struct EEVEE_LightProbesInfo {
|
||||||
@@ -440,13 +444,9 @@ typedef struct EEVEE_LightProbesInfo {
|
|||||||
int updated_bounce;
|
int updated_bounce;
|
||||||
int num_bounce;
|
int num_bounce;
|
||||||
int cubemap_res;
|
int cubemap_res;
|
||||||
int target_size;
|
/* Update */
|
||||||
int grid_initialized;
|
|
||||||
struct World *prev_world;
|
|
||||||
int update_world;
|
|
||||||
bool prev_wo_sh_compiled;
|
|
||||||
bool do_cube_update;
|
bool do_cube_update;
|
||||||
bool all_materials_updated;
|
bool do_grid_update;
|
||||||
/* For rendering probes */
|
/* For rendering probes */
|
||||||
float probemat[6][4][4];
|
float probemat[6][4][4];
|
||||||
int layer;
|
int layer;
|
||||||
@@ -465,15 +465,11 @@ typedef struct EEVEE_LightProbesInfo {
|
|||||||
int shres;
|
int shres;
|
||||||
int studiolight_index;
|
int studiolight_index;
|
||||||
float studiolight_rot_z;
|
float studiolight_rot_z;
|
||||||
/* List of probes in the scene. */
|
EEVEE_LightProbeVisTest planar_vis_tests[MAX_PLANAR];
|
||||||
/* XXX This is fragile, can get out of sync quickly. */
|
|
||||||
struct Object *probes_cube_ref[MAX_PROBE];
|
|
||||||
struct Object *probes_grid_ref[MAX_GRID];
|
|
||||||
struct Object *probes_planar_ref[MAX_PLANAR];
|
|
||||||
/* UBO Storage : data used by UBO */
|
/* UBO Storage : data used by UBO */
|
||||||
struct EEVEE_LightProbe probe_data[MAX_PROBE];
|
EEVEE_LightProbe probe_data[MAX_PROBE];
|
||||||
struct EEVEE_LightGrid grid_data[MAX_GRID];
|
EEVEE_LightGrid grid_data[MAX_GRID];
|
||||||
struct EEVEE_PlanarReflection planar_data[MAX_PLANAR];
|
EEVEE_PlanarReflection planar_data[MAX_PLANAR];
|
||||||
/* Probe Visibility Collection */
|
/* Probe Visibility Collection */
|
||||||
EEVEE_LightProbeVisTest vis_data;
|
EEVEE_LightProbeVisTest vis_data;
|
||||||
} EEVEE_LightProbesInfo;
|
} EEVEE_LightProbesInfo;
|
||||||
@@ -673,24 +669,18 @@ typedef struct EEVEE_ViewLayerData {
|
|||||||
struct GPUUniformBuffer *grid_ubo;
|
struct GPUUniformBuffer *grid_ubo;
|
||||||
struct GPUUniformBuffer *planar_ubo;
|
struct GPUUniformBuffer *planar_ubo;
|
||||||
|
|
||||||
struct GPUFrameBuffer *probe_filter_fb;
|
|
||||||
struct GPUFrameBuffer *probe_face_fb[6];
|
|
||||||
|
|
||||||
struct GPUTexture *probe_rt;
|
|
||||||
struct GPUTexture *probe_depth_rt;
|
|
||||||
struct GPUTexture *probe_pool;
|
|
||||||
struct GPUTexture *irradiance_pool;
|
|
||||||
struct GPUTexture *irradiance_rt;
|
|
||||||
|
|
||||||
/* Common Uniform Buffer */
|
/* Common Uniform Buffer */
|
||||||
struct EEVEE_CommonUniformBuffer common_data;
|
struct EEVEE_CommonUniformBuffer common_data;
|
||||||
struct GPUUniformBuffer *common_ubo;
|
struct GPUUniformBuffer *common_ubo;
|
||||||
|
|
||||||
struct EEVEE_ClipPlanesUniformBuffer clip_data;
|
struct EEVEE_ClipPlanesUniformBuffer clip_data;
|
||||||
struct GPUUniformBuffer *clip_ubo;
|
struct GPUUniformBuffer *clip_ubo;
|
||||||
|
|
||||||
|
struct LightCache *fallback_lightcache;
|
||||||
} EEVEE_ViewLayerData;
|
} EEVEE_ViewLayerData;
|
||||||
|
|
||||||
/* ************ OBJECT DATA ************ */
|
/* ************ OBJECT DATA ************ */
|
||||||
|
|
||||||
typedef struct EEVEE_LightData {
|
typedef struct EEVEE_LightData {
|
||||||
short light_id, shadow_id;
|
short light_id, shadow_id;
|
||||||
} EEVEE_LightData;
|
} EEVEE_LightData;
|
||||||
@@ -711,7 +701,7 @@ typedef struct EEVEE_ShadowCascadeData {
|
|||||||
* It works with even if the object is in multiple layers
|
* It works with even if the object is in multiple layers
|
||||||
* because we don't get the same "Object *" for each layer. */
|
* because we don't get the same "Object *" for each layer. */
|
||||||
typedef struct EEVEE_LampEngineData {
|
typedef struct EEVEE_LampEngineData {
|
||||||
ObjectEngineData engine_data;
|
DrawData dd;
|
||||||
|
|
||||||
bool need_update;
|
bool need_update;
|
||||||
/* This needs to be out of the union to avoid undefined behaviour. */
|
/* This needs to be out of the union to avoid undefined behaviour. */
|
||||||
@@ -724,35 +714,13 @@ typedef struct EEVEE_LampEngineData {
|
|||||||
} EEVEE_LampEngineData;
|
} EEVEE_LampEngineData;
|
||||||
|
|
||||||
typedef struct EEVEE_LightProbeEngineData {
|
typedef struct EEVEE_LightProbeEngineData {
|
||||||
ObjectEngineData engine_data;
|
DrawData dd;
|
||||||
|
|
||||||
/* NOTE: need_full_update is set by dependency graph when the probe or it's
|
|
||||||
* object is updated. This triggers full probe update, including it's
|
|
||||||
* "progressive" GI refresh.
|
|
||||||
*
|
|
||||||
* need_update is always set to truth when need_full_update is tagged, but
|
|
||||||
* might also be forced to be kept truth during GI refresh stages.
|
|
||||||
*
|
|
||||||
* TODO(sergey): Is there a way to avoid two flags here, or at least make
|
|
||||||
* it more clear what's going on here?
|
|
||||||
*/
|
|
||||||
bool need_full_update;
|
|
||||||
bool need_update;
|
bool need_update;
|
||||||
|
|
||||||
bool ready_to_shade;
|
|
||||||
int updated_cells;
|
|
||||||
int updated_lvl;
|
|
||||||
int num_cell;
|
|
||||||
int max_lvl;
|
|
||||||
int probe_id; /* Only used for display data */
|
|
||||||
float probe_size; /* Only used for display data */
|
|
||||||
DRWMatrixState mats; /* For planar probes */
|
|
||||||
float planer_eq_offset[4];
|
|
||||||
struct ListBase captured_object_list;
|
|
||||||
} EEVEE_LightProbeEngineData;
|
} EEVEE_LightProbeEngineData;
|
||||||
|
|
||||||
typedef struct EEVEE_ObjectEngineData {
|
typedef struct EEVEE_ObjectEngineData {
|
||||||
ObjectEngineData engine_data;
|
DrawData dd;
|
||||||
|
|
||||||
Object *ob; /* self reference */
|
Object *ob; /* self reference */
|
||||||
EEVEE_LightProbeVisTest *test_data;
|
EEVEE_LightProbeVisTest *test_data;
|
||||||
@@ -762,6 +730,10 @@ typedef struct EEVEE_ObjectEngineData {
|
|||||||
uint shadow_caster_id;
|
uint shadow_caster_id;
|
||||||
} EEVEE_ObjectEngineData;
|
} EEVEE_ObjectEngineData;
|
||||||
|
|
||||||
|
typedef struct EEVEE_WorldEngineData {
|
||||||
|
DrawData dd;
|
||||||
|
} EEVEE_WorldEngineData;
|
||||||
|
|
||||||
/* *********************************** */
|
/* *********************************** */
|
||||||
|
|
||||||
typedef struct EEVEE_Data {
|
typedef struct EEVEE_Data {
|
||||||
@@ -786,6 +758,8 @@ typedef struct EEVEE_PrivateData {
|
|||||||
struct DRWShadingGroup *planar_display_shgrp;
|
struct DRWShadingGroup *planar_display_shgrp;
|
||||||
struct GHash *material_hash;
|
struct GHash *material_hash;
|
||||||
float background_alpha; /* TODO find a better place for this. */
|
float background_alpha; /* TODO find a better place for this. */
|
||||||
|
/* Chosen lightcache: can come from Lookdev or the viewlayer. */
|
||||||
|
struct LightCache *light_cache;
|
||||||
/* For planar probes */
|
/* For planar probes */
|
||||||
float planar_texel_size[2];
|
float planar_texel_size[2];
|
||||||
/* For double buffering */
|
/* For double buffering */
|
||||||
@@ -803,6 +777,7 @@ typedef struct EEVEE_PrivateData {
|
|||||||
|
|
||||||
/* eevee_data.c */
|
/* eevee_data.c */
|
||||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void);
|
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void);
|
||||||
|
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer);
|
||||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void);
|
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void);
|
||||||
EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob);
|
EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob);
|
||||||
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob);
|
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob);
|
||||||
@@ -810,6 +785,8 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob);
|
|||||||
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob);
|
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob);
|
||||||
EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob);
|
EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob);
|
||||||
EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob);
|
EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob);
|
||||||
|
EEVEE_WorldEngineData *EEVEE_world_data_get(World *wo);
|
||||||
|
EEVEE_WorldEngineData *EEVEE_world_data_ensure(World *wo);
|
||||||
|
|
||||||
/* eevee_materials.c */
|
/* eevee_materials.c */
|
||||||
struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
|
struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
|
||||||
@@ -849,17 +826,37 @@ void EEVEE_lights_update(EEVEE_ViewLayerData *sldata);
|
|||||||
void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
|
void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
|
||||||
void EEVEE_lights_free(void);
|
void EEVEE_lights_free(void);
|
||||||
|
|
||||||
|
|
||||||
/* eevee_lightprobes.c */
|
/* eevee_lightprobes.c */
|
||||||
bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data);
|
bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data);
|
||||||
bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
|
||||||
void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||||
void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||||
void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob);
|
void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *ob);
|
||||||
void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||||
void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||||
void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||||
void EEVEE_lightprobes_free(void);
|
void EEVEE_lightprobes_free(void);
|
||||||
|
|
||||||
|
void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, GPUTexture *rt_color, GPUTexture *rt_depth);
|
||||||
|
void EEVEE_lightbake_render_world(
|
||||||
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6]);
|
||||||
|
void EEVEE_lightbake_render_scene(
|
||||||
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6],
|
||||||
|
const float pos[3], float near_clip, float far_clip);
|
||||||
|
void EEVEE_lightbake_filter_glossy(
|
||||||
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_color, struct GPUFrameBuffer *fb,
|
||||||
|
int probe_idx, float intensity, int maxlevel);
|
||||||
|
void EEVEE_lightbake_filter_diffuse(
|
||||||
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_color, struct GPUFrameBuffer *fb,
|
||||||
|
int grid_offset, float intensity);
|
||||||
|
void EEVEE_lightbake_filter_visibility(
|
||||||
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_depth, struct GPUFrameBuffer *fb,
|
||||||
|
int grid_offset, float clipsta, float clipend, float vis_range, float vis_blur, int vis_size);
|
||||||
|
|
||||||
|
void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *prb_data, int *offset);
|
||||||
|
void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *prb_data);
|
||||||
|
void EEVEE_lightprobes_planar_data_from_object(Object *ob, EEVEE_PlanarReflection *eplanar, EEVEE_LightProbeVisTest *vis_test);
|
||||||
|
|
||||||
/* eevee_depth_of_field.c */
|
/* eevee_depth_of_field.c */
|
||||||
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera);
|
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera);
|
||||||
void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||||
@@ -948,6 +945,9 @@ void EEVEE_render_update_passes(struct RenderEngine *engine, struct Scene *scene
|
|||||||
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, struct World *world, EEVEE_LightProbesInfo *pinfo);
|
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, struct World *world, EEVEE_LightProbesInfo *pinfo);
|
||||||
void EEVEE_lookdev_draw_background(EEVEE_Data *vedata);
|
void EEVEE_lookdev_draw_background(EEVEE_Data *vedata);
|
||||||
|
|
||||||
|
/** eevee_engine.c */
|
||||||
|
void EEVEE_cache_populate(void *vedata, Object *ob);
|
||||||
|
|
||||||
/* Shadow Matrix */
|
/* Shadow Matrix */
|
||||||
static const float texcomat[4][4] = { /* From NDC to TexCo */
|
static const float texcomat[4][4] = { /* From NDC to TexCo */
|
||||||
{0.5f, 0.0f, 0.0f, 0.0f},
|
{0.5f, 0.0f, 0.0f, 0.0f},
|
||||||
|
@@ -134,17 +134,31 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||||||
EEVEE_volumes_cache_init(sldata, vedata);
|
EEVEE_volumes_cache_init(sldata, vedata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used by light cache. in this case engine is NULL. */
|
||||||
void EEVEE_render_cache(
|
void EEVEE_render_cache(
|
||||||
void *vedata, struct Object *ob,
|
void *vedata, struct Object *ob,
|
||||||
struct RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph))
|
struct RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph))
|
||||||
{
|
{
|
||||||
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
||||||
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
||||||
char info[42];
|
|
||||||
BLI_snprintf(info, sizeof(info), "Syncing %s", ob->id.name + 2);
|
|
||||||
RE_engine_update_stats(engine, NULL, info);
|
|
||||||
bool cast_shadow = false;
|
bool cast_shadow = false;
|
||||||
|
|
||||||
|
if (pinfo->vis_data.collection) {
|
||||||
|
/* Used for rendering probe with visibility groups. */
|
||||||
|
bool ob_vis = BKE_collection_has_object_recursive(pinfo->vis_data.collection, ob);
|
||||||
|
ob_vis = (pinfo->vis_data.invert) ? !ob_vis : ob_vis;
|
||||||
|
|
||||||
|
if (!ob_vis) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine) {
|
||||||
|
char info[42];
|
||||||
|
BLI_snprintf(info, sizeof(info), "Syncing %s", ob->id.name + 2);
|
||||||
|
RE_engine_update_stats(engine, NULL, info);
|
||||||
|
}
|
||||||
|
|
||||||
if (ob->base_flag & BASE_VISIBLE) {
|
if (ob->base_flag & BASE_VISIBLE) {
|
||||||
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
|
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
|
||||||
}
|
}
|
||||||
@@ -154,7 +168,7 @@ void EEVEE_render_cache(
|
|||||||
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
|
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
|
||||||
}
|
}
|
||||||
else if (ob->type == OB_LIGHTPROBE) {
|
else if (ob->type == OB_LIGHTPROBE) {
|
||||||
EEVEE_lightprobes_cache_add(sldata, ob);
|
EEVEE_lightprobes_cache_add(sldata, vedata, ob);
|
||||||
}
|
}
|
||||||
else if (ob->type == OB_LAMP) {
|
else if (ob->type == OB_LAMP) {
|
||||||
EEVEE_lights_cache_add(sldata, ob);
|
EEVEE_lights_cache_add(sldata, ob);
|
||||||
@@ -477,14 +491,8 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
|
|||||||
DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV);
|
DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV);
|
||||||
|
|
||||||
/* Refresh Probes */
|
/* Refresh Probes */
|
||||||
while (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) {
|
RE_engine_update_stats(engine, NULL, "Updating Probes");
|
||||||
RE_engine_update_stats(engine, NULL, "Updating Probes");
|
EEVEE_lightprobes_refresh(sldata, vedata);
|
||||||
EEVEE_lightprobes_refresh(sldata, vedata);
|
|
||||||
/* Refreshing probes can take some times, allow exit. */
|
|
||||||
if (RE_engine_test_break(engine)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EEVEE_lightprobes_refresh_planar(sldata, vedata);
|
EEVEE_lightprobes_refresh_planar(sldata, vedata);
|
||||||
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
|
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
|
||||||
|
|
||||||
|
@@ -187,6 +187,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
|
|||||||
EEVEE_StorageList *stl = vedata->stl;
|
EEVEE_StorageList *stl = vedata->stl;
|
||||||
EEVEE_TextureList *txl = vedata->txl;
|
EEVEE_TextureList *txl = vedata->txl;
|
||||||
EEVEE_EffectsInfo *effects = stl->effects;
|
EEVEE_EffectsInfo *effects = stl->effects;
|
||||||
|
LightCache *lcache = stl->g_data->light_cache;
|
||||||
|
|
||||||
struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
|
struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
|
||||||
|
|
||||||
@@ -230,7 +231,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
|
|||||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
|
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
|
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
|
DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &sldata->probe_pool);
|
DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool);
|
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
|
DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output);
|
DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output);
|
||||||
|
@@ -349,6 +349,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||||||
EEVEE_StorageList *stl = vedata->stl;
|
EEVEE_StorageList *stl = vedata->stl;
|
||||||
EEVEE_TextureList *txl = vedata->txl;
|
EEVEE_TextureList *txl = vedata->txl;
|
||||||
EEVEE_EffectsInfo *effects = stl->effects;
|
EEVEE_EffectsInfo *effects = stl->effects;
|
||||||
|
LightCache *lcache = stl->g_data->light_cache;
|
||||||
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
||||||
|
|
||||||
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
|
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
|
||||||
@@ -417,7 +418,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||||||
psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
|
psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
|
||||||
grp = DRW_shgroup_empty_tri_batch_create(scatter_sh, psl->volumetric_scatter_ps,
|
grp = DRW_shgroup_empty_tri_batch_create(scatter_sh, psl->volumetric_scatter_ps,
|
||||||
common_data->vol_tex_size[2]);
|
common_data->vol_tex_size[2]);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &sldata->irradiance_pool);
|
DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &lcache->grid_tx.tex);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
|
DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
|
DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering);
|
DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering);
|
||||||
|
@@ -1,15 +1,18 @@
|
|||||||
|
|
||||||
flat in int pid;
|
flat in int pid;
|
||||||
in vec3 worldNormal;
|
in vec2 quadCoord;
|
||||||
in vec3 worldPosition;
|
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 V = (ProjectionMatrix[3][3] == 0.0) /* if perspective */
|
float dist_sqr = dot(quadCoord, quadCoord);
|
||||||
? normalize(cameraPos - worldPosition)
|
|
||||||
: cameraForward;
|
/* Discard outside the circle. */
|
||||||
vec3 N = normalize(worldNormal);
|
if (dist_sqr > 1.0)
|
||||||
FragColor = vec4(textureLod_octahedron(probeCubes, vec4(reflect(-V, N), pid), 0.0, prbLodCubeMax).rgb, 1.0);
|
discard;
|
||||||
|
|
||||||
|
vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr)));
|
||||||
|
vec3 world_ref = mat3(ViewMatrixInverse) * reflect(vec3(0.0, 0.0, -1.0), view_nor);
|
||||||
|
FragColor = vec4(textureLod_octahedron(probeCubes, vec4(world_ref, pid), 0.0, prbLodCubeMax).rgb, 1.0);
|
||||||
}
|
}
|
||||||
|
@@ -1,26 +1,43 @@
|
|||||||
|
|
||||||
in vec3 pos;
|
/* XXX TODO fix code duplication */
|
||||||
|
struct CubeData {
|
||||||
|
vec4 position_type;
|
||||||
|
vec4 attenuation_fac_type;
|
||||||
|
mat4 influencemat;
|
||||||
|
mat4 parallaxmat;
|
||||||
|
};
|
||||||
|
|
||||||
/* Instance attrib */
|
layout(std140) uniform probe_block {
|
||||||
in int probe_id;
|
CubeData probes_data[MAX_PROBE];
|
||||||
in vec3 probe_location;
|
};
|
||||||
in float sphere_size;
|
|
||||||
|
uniform float sphere_size;
|
||||||
|
uniform vec3 screen_vecs[2];
|
||||||
|
|
||||||
flat out int pid;
|
flat out int pid;
|
||||||
out vec3 worldNormal;
|
out vec2 quadCoord;
|
||||||
out vec3 worldPosition;
|
|
||||||
|
const vec2 pos[6] = vec2[6](
|
||||||
|
vec2(-1.0, -1.0),
|
||||||
|
vec2( 1.0, -1.0),
|
||||||
|
vec2(-1.0, 1.0),
|
||||||
|
|
||||||
|
vec2( 1.0, -1.0),
|
||||||
|
vec2( 1.0, 1.0),
|
||||||
|
vec2(-1.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
pid = probe_id;
|
pid = 1 + (gl_VertexID / 6); /* +1 for the world */
|
||||||
|
int vert_id = gl_VertexID % 6;
|
||||||
|
|
||||||
/* While this is not performant, we do this to
|
quadCoord = pos[vert_id];
|
||||||
* match the object mode engine instancing shader. */
|
|
||||||
mat4 offsetmat = mat4(1.0); /* Identity */
|
|
||||||
offsetmat[3].xyz = probe_location;
|
|
||||||
|
|
||||||
vec4 wpos = offsetmat * vec4(pos * sphere_size, 1.0);
|
vec3 ws_location = probes_data[pid].position_type.xyz;
|
||||||
worldPosition = wpos.xyz;
|
vec3 screen_pos = screen_vecs[0] * quadCoord.x + screen_vecs[1] * quadCoord.y;
|
||||||
gl_Position = ViewProjectionMatrix * wpos;
|
ws_location += screen_pos * sphere_size;
|
||||||
worldNormal = normalize(pos);
|
|
||||||
|
gl_Position = ViewProjectionMatrix * vec4(ws_location, 1.0);
|
||||||
|
gl_Position.z += 0.0001; /* Small bias to let the icon draw without zfighting */
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,19 @@
|
|||||||
|
|
||||||
flat in int cellOffset;
|
flat in int cellOffset;
|
||||||
in vec3 worldNormal;
|
in vec2 quadCoord;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
IrradianceData ir_data = load_irradiance_cell(cellOffset, worldNormal);
|
float dist_sqr = dot(quadCoord, quadCoord);
|
||||||
FragColor = vec4(compute_irradiance(worldNormal, ir_data), 1.0);
|
|
||||||
|
/* Discard outside the circle. */
|
||||||
|
if (dist_sqr > 1.0)
|
||||||
|
discard;
|
||||||
|
|
||||||
|
vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr)));
|
||||||
|
vec3 world_nor = mat3(ViewMatrixInverse) * view_nor;
|
||||||
|
IrradianceData ir_data = load_irradiance_cell(cellOffset, world_nor);
|
||||||
|
FragColor = vec4(compute_irradiance(world_nor, ir_data), 1.0);
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
|
|
||||||
in vec3 pos;
|
|
||||||
|
|
||||||
uniform float sphere_size;
|
uniform float sphere_size;
|
||||||
uniform int offset;
|
uniform int offset;
|
||||||
uniform ivec3 grid_resolution;
|
uniform ivec3 grid_resolution;
|
||||||
@@ -8,25 +6,44 @@ uniform vec3 corner;
|
|||||||
uniform vec3 increment_x;
|
uniform vec3 increment_x;
|
||||||
uniform vec3 increment_y;
|
uniform vec3 increment_y;
|
||||||
uniform vec3 increment_z;
|
uniform vec3 increment_z;
|
||||||
|
uniform vec3 screen_vecs[2];
|
||||||
|
|
||||||
flat out int cellOffset;
|
flat out int cellOffset;
|
||||||
out vec3 worldNormal;
|
out vec2 quadCoord;
|
||||||
|
|
||||||
|
const vec2 pos[6] = vec2[6](
|
||||||
|
vec2(-1.0, -1.0),
|
||||||
|
vec2( 1.0, -1.0),
|
||||||
|
vec2(-1.0, 1.0),
|
||||||
|
|
||||||
|
vec2( 1.0, -1.0),
|
||||||
|
vec2( 1.0, 1.0),
|
||||||
|
vec2(-1.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
int cell_id = gl_VertexID / 6;
|
||||||
|
int vert_id = gl_VertexID % 6;
|
||||||
|
|
||||||
vec3 ls_cell_location;
|
vec3 ls_cell_location;
|
||||||
/* Keep in sync with update_irradiance_probe */
|
/* Keep in sync with update_irradiance_probe */
|
||||||
ls_cell_location.z = float(gl_InstanceID % grid_resolution.z);
|
ls_cell_location.z = float(cell_id % grid_resolution.z);
|
||||||
ls_cell_location.y = float((gl_InstanceID / grid_resolution.z) % grid_resolution.y);
|
ls_cell_location.y = float((cell_id / grid_resolution.z) % grid_resolution.y);
|
||||||
ls_cell_location.x = float(gl_InstanceID / (grid_resolution.z * grid_resolution.y));
|
ls_cell_location.x = float(cell_id / (grid_resolution.z * grid_resolution.y));
|
||||||
|
|
||||||
cellOffset = offset + gl_InstanceID;
|
cellOffset = offset + cell_id;
|
||||||
|
|
||||||
vec3 ws_cell_location = corner +
|
vec3 ws_cell_location = corner +
|
||||||
(increment_x * ls_cell_location.x +
|
(increment_x * ls_cell_location.x +
|
||||||
increment_y * ls_cell_location.y +
|
increment_y * ls_cell_location.y +
|
||||||
increment_z * ls_cell_location.z);
|
increment_z * ls_cell_location.z);
|
||||||
|
|
||||||
gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 * sphere_size + ws_cell_location, 1.0);
|
|
||||||
worldNormal = normalize(pos);
|
quadCoord = pos[vert_id];
|
||||||
|
vec3 screen_pos = screen_vecs[0] * quadCoord.x + screen_vecs[1] * quadCoord.y;
|
||||||
|
ws_cell_location += screen_pos * sphere_size;
|
||||||
|
|
||||||
|
gl_Position = ViewProjectionMatrix * vec4(ws_cell_location , 1.0);
|
||||||
|
gl_Position.z += 0.0001; /* Small bias to let the icon draw without zfighting */
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ struct PlanarData {
|
|||||||
vec4 clip_edges;
|
vec4 clip_edges;
|
||||||
vec4 facing_scale_bias;
|
vec4 facing_scale_bias;
|
||||||
mat4 reflectionmat; /* transform world space into reflection texture space */
|
mat4 reflectionmat; /* transform world space into reflection texture space */
|
||||||
|
mat4 unused;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define pl_plane_eq plane_equation
|
#define pl_plane_eq plane_equation
|
||||||
|
@@ -256,7 +256,7 @@ void CLOSURE_NAME(
|
|||||||
PlanarData pd = planars_data[i];
|
PlanarData pd = planars_data[i];
|
||||||
|
|
||||||
/* Fade on geometric normal. */
|
/* Fade on geometric normal. */
|
||||||
float fade = probe_attenuation_planar(pd, worldPosition, worldNormal, roughness);
|
float fade = probe_attenuation_planar(pd, worldPosition, (gl_FrontFacing) ? worldNormal : -worldNormal, roughness);
|
||||||
|
|
||||||
if (fade > 0.0) {
|
if (fade > 0.0) {
|
||||||
if (!(ssrToggle && ssr_id == outputSsrId)) {
|
if (!(ssrToggle && ssr_id == outputSsrId)) {
|
||||||
@@ -404,7 +404,7 @@ void CLOSURE_NAME(
|
|||||||
spec_occlu = 1.0;
|
spec_occlu = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_spec += spec_accum.rgb * ssr_spec * spec_occlu * float(specToggle);
|
out_spec += spec_accum.rgb * ssr_spec * spec_occlu;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CLOSURE_REFRACTION
|
#ifdef CLOSURE_REFRACTION
|
||||||
@@ -419,7 +419,12 @@ void CLOSURE_NAME(
|
|||||||
vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg;
|
vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg;
|
||||||
vec3 C_fresnel = F_ibl(vec3(0.04), brdf_lut) * specular_occlusion(NV, final_ao, C_roughness);
|
vec3 C_fresnel = F_ibl(vec3(0.04), brdf_lut) * specular_occlusion(NV, final_ao, C_roughness);
|
||||||
|
|
||||||
out_spec += C_spec_accum.rgb * C_fresnel * float(specToggle) * C_intensity;
|
out_spec += C_spec_accum.rgb * C_fresnel * C_intensity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CLOSURE_GLOSSY
|
||||||
|
/* Global toggle for lightprobe baking. */
|
||||||
|
out_spec *= float(specToggle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@@ -258,9 +258,9 @@ static struct GPUTexture *create_jitter_texture(int num_samples)
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
|
|
||||||
static void workbench_init_object_data(ObjectEngineData *engine_data)
|
static void workbench_init_object_data(DrawData *dd)
|
||||||
{
|
{
|
||||||
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data;
|
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
|
||||||
data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
|
data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
|
||||||
data->shadow_bbox_dirty = true;
|
data->shadow_bbox_dirty = true;
|
||||||
}
|
}
|
||||||
@@ -561,8 +561,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
|
|||||||
WORKBENCH_PassList *psl = vedata->psl;
|
WORKBENCH_PassList *psl = vedata->psl;
|
||||||
WORKBENCH_PrivateData *wpd = stl->g_data;
|
WORKBENCH_PrivateData *wpd = stl->g_data;
|
||||||
WORKBENCH_MaterialData *material;
|
WORKBENCH_MaterialData *material;
|
||||||
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure(
|
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
|
||||||
ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
|
&ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
|
||||||
WORKBENCH_MaterialData material_template;
|
WORKBENCH_MaterialData material_template;
|
||||||
|
|
||||||
/* Solid */
|
/* Solid */
|
||||||
@@ -731,8 +731,8 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||||||
// DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat);
|
// DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure(
|
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
|
||||||
ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
|
&ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
|
||||||
|
|
||||||
if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
|
if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
|
||||||
|
|
||||||
|
@@ -126,9 +126,9 @@ static char *workbench_build_forward_composite_frag(void)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void workbench_init_object_data(ObjectEngineData *engine_data)
|
static void workbench_init_object_data(DrawData *dd)
|
||||||
{
|
{
|
||||||
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data;
|
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
|
||||||
data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
|
data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,8 +139,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
|
|||||||
WORKBENCH_PassList *psl = vedata->psl;
|
WORKBENCH_PassList *psl = vedata->psl;
|
||||||
WORKBENCH_PrivateData *wpd = stl->g_data;
|
WORKBENCH_PrivateData *wpd = stl->g_data;
|
||||||
WORKBENCH_MaterialData *material;
|
WORKBENCH_MaterialData *material;
|
||||||
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure(
|
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
|
||||||
ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
|
&ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
|
||||||
WORKBENCH_MaterialData material_template;
|
WORKBENCH_MaterialData material_template;
|
||||||
DRWShadingGroup *grp;
|
DRWShadingGroup *grp;
|
||||||
|
|
||||||
|
@@ -201,12 +201,8 @@ typedef struct WORKBENCH_MaterialData {
|
|||||||
} WORKBENCH_MaterialData;
|
} WORKBENCH_MaterialData;
|
||||||
|
|
||||||
typedef struct WORKBENCH_ObjectData {
|
typedef struct WORKBENCH_ObjectData {
|
||||||
struct ObjectEngineData *next, *prev;
|
DrawData dd;
|
||||||
struct DrawEngineType *engine_type;
|
|
||||||
/* Only nested data, NOT the engine data itself. */
|
|
||||||
ObjectEngineDataFreeCb free;
|
|
||||||
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
|
|
||||||
int recalc;
|
|
||||||
/* Shadow direction in local object space. */
|
/* Shadow direction in local object space. */
|
||||||
float shadow_dir[3], shadow_depth;
|
float shadow_dir[3], shadow_depth;
|
||||||
float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */
|
float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
#include "DNA_lamp_types.h"
|
#include "DNA_lamp_types.h"
|
||||||
#include "DNA_material_types.h"
|
#include "DNA_material_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
#include "DNA_world_types.h"
|
||||||
|
|
||||||
#include "GPU_framebuffer.h"
|
#include "GPU_framebuffer.h"
|
||||||
#include "GPU_texture.h"
|
#include "GPU_texture.h"
|
||||||
@@ -239,14 +240,14 @@ struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines);
|
|||||||
struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines);
|
struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines);
|
||||||
struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
|
struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
|
||||||
struct GPUShader *DRW_shader_create_3D_depth_only(void);
|
struct GPUShader *DRW_shader_create_3D_depth_only(void);
|
||||||
struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options);
|
struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options, bool no_deferred);
|
||||||
struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options);
|
struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options, bool no_deferred);
|
||||||
struct GPUMaterial *DRW_shader_create_from_world(
|
struct GPUMaterial *DRW_shader_create_from_world(
|
||||||
struct Scene *scene, struct World *wo, const void *engine_type, int options,
|
struct Scene *scene, struct World *wo, const void *engine_type, int options,
|
||||||
const char *vert, const char *geom, const char *frag_lib, const char *defines);
|
const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred);
|
||||||
struct GPUMaterial *DRW_shader_create_from_material(
|
struct GPUMaterial *DRW_shader_create_from_material(
|
||||||
struct Scene *scene, struct Material *ma, const void *engine_type, int options,
|
struct Scene *scene, struct Material *ma, const void *engine_type, int options,
|
||||||
const char *vert, const char *geom, const char *frag_lib, const char *defines);
|
const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred);
|
||||||
void DRW_shader_free(struct GPUShader *shader);
|
void DRW_shader_free(struct GPUShader *shader);
|
||||||
#define DRW_SHADER_FREE_SAFE(shader) do { \
|
#define DRW_SHADER_FREE_SAFE(shader) do { \
|
||||||
if (shader != NULL) { \
|
if (shader != NULL) { \
|
||||||
@@ -409,6 +410,7 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass);
|
|||||||
|
|
||||||
/* Viewport */
|
/* Viewport */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
/* keep in sync with the union struct DRWMatrixState. */
|
||||||
DRW_MAT_PERS = 0,
|
DRW_MAT_PERS = 0,
|
||||||
DRW_MAT_PERSINV,
|
DRW_MAT_PERSINV,
|
||||||
DRW_MAT_VIEW,
|
DRW_MAT_VIEW,
|
||||||
@@ -420,7 +422,18 @@ typedef enum {
|
|||||||
} DRWViewportMatrixType;
|
} DRWViewportMatrixType;
|
||||||
|
|
||||||
typedef struct DRWMatrixState {
|
typedef struct DRWMatrixState {
|
||||||
float mat[DRW_MAT_COUNT][4][4];
|
union {
|
||||||
|
float mat[DRW_MAT_COUNT][4][4];
|
||||||
|
struct {
|
||||||
|
/* keep in sync with the enum DRWViewportMatrixType. */
|
||||||
|
float persmat[4][4];
|
||||||
|
float persinv[4][4];
|
||||||
|
float viewmat[4][4];
|
||||||
|
float viewinv[4][4];
|
||||||
|
float winmat[4][4];
|
||||||
|
float wininv[4][4];
|
||||||
|
};
|
||||||
|
};
|
||||||
} DRWMatrixState;
|
} DRWMatrixState;
|
||||||
|
|
||||||
void DRW_viewport_init(const bContext *C);
|
void DRW_viewport_init(const bContext *C);
|
||||||
@@ -453,6 +466,12 @@ void DRW_render_object_iter(
|
|||||||
void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph));
|
void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph));
|
||||||
void DRW_render_instance_buffer_finish(void);
|
void DRW_render_instance_buffer_finish(void);
|
||||||
|
|
||||||
|
void DRW_custom_pipeline(
|
||||||
|
DrawEngineType *draw_engine_type,
|
||||||
|
struct Depsgraph *depsgraph,
|
||||||
|
void (*callback)(void *vedata, void *user_data),
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
/* ViewLayers */
|
/* ViewLayers */
|
||||||
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
|
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
|
||||||
void **DRW_view_layer_engine_data_ensure_ex(
|
void **DRW_view_layer_engine_data_ensure_ex(
|
||||||
@@ -460,16 +479,14 @@ void **DRW_view_layer_engine_data_ensure_ex(
|
|||||||
void **DRW_view_layer_engine_data_ensure(
|
void **DRW_view_layer_engine_data_ensure(
|
||||||
DrawEngineType *engine_type, void (*callback)(void *storage));
|
DrawEngineType *engine_type, void (*callback)(void *storage));
|
||||||
|
|
||||||
/* Objects */
|
/* DrawData */
|
||||||
ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type);
|
DrawData *DRW_drawdata_get(ID *ib, DrawEngineType *engine_type);
|
||||||
ObjectEngineData *DRW_object_engine_data_ensure(
|
DrawData *DRW_drawdata_ensure(
|
||||||
Object *ob,
|
ID *id,
|
||||||
DrawEngineType *engine_type,
|
DrawEngineType *engine_type,
|
||||||
size_t size,
|
size_t size,
|
||||||
ObjectEngineDataInitCb init_cb,
|
DrawDataInitCb init_cb,
|
||||||
ObjectEngineDataFreeCb free_cb);
|
DrawDataFreeCb free_cb);
|
||||||
struct LampEngineData *DRW_lamp_engine_data_ensure(Object *ob, struct RenderEngineType *engine_type);
|
|
||||||
void DRW_lamp_engine_data_free(struct LampEngineData *led);
|
|
||||||
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
bool DRW_object_is_renderable(struct Object *ob);
|
bool DRW_object_is_renderable(struct Object *ob);
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
#include "DNA_camera_types.h"
|
#include "DNA_camera_types.h"
|
||||||
#include "DNA_mesh_types.h"
|
#include "DNA_mesh_types.h"
|
||||||
#include "DNA_meshdata_types.h"
|
#include "DNA_meshdata_types.h"
|
||||||
|
#include "DNA_world_types.h"
|
||||||
|
|
||||||
#include "ED_space_api.h"
|
#include "ED_space_api.h"
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
@@ -696,34 +697,96 @@ void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*cal
|
|||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
/** \name Objects (DRW_object)
|
/** \name Draw Data (DRW_drawdata)
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type)
|
/* Used for DRW_drawdata_from_id()
|
||||||
|
* All ID-datablocks which have their own 'local' DrawData
|
||||||
|
* should have the same arrangement in their structs.
|
||||||
|
*/
|
||||||
|
typedef struct IdDdtTemplate {
|
||||||
|
ID id;
|
||||||
|
struct AnimData *adt;
|
||||||
|
DrawDataList drawdata;
|
||||||
|
} IdDdtTemplate;
|
||||||
|
|
||||||
|
/* Check if ID can have AnimData */
|
||||||
|
static bool id_type_can_have_drawdata(const short id_type)
|
||||||
{
|
{
|
||||||
for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
|
/* Only some ID-blocks have this info for now */
|
||||||
if (oed->engine_type == engine_type) {
|
/* TODO: finish adding this for the other blocktypes */
|
||||||
return oed;
|
switch (id_type) {
|
||||||
|
/* has DrawData */
|
||||||
|
case ID_OB:
|
||||||
|
case ID_WO:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* no DrawData */
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool id_can_have_drawdata(const ID *id)
|
||||||
|
{
|
||||||
|
/* sanity check */
|
||||||
|
if (id == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return id_type_can_have_drawdata(GS(id->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get DrawData from the given ID-block. In order for this to work, we assume that
|
||||||
|
* the DrawData pointer is stored in the struct in the same fashion as in IdDdtTemplate.
|
||||||
|
*/
|
||||||
|
DrawDataList *DRW_drawdatalist_from_id(ID *id)
|
||||||
|
{
|
||||||
|
/* only some ID-blocks have this info for now, so we cast the
|
||||||
|
* types that do to be of type IdDdtTemplate, and extract the
|
||||||
|
* DrawData that way
|
||||||
|
*/
|
||||||
|
if (id_can_have_drawdata(id)) {
|
||||||
|
IdDdtTemplate *idt = (IdDdtTemplate *)id;
|
||||||
|
return &idt->drawdata;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type)
|
||||||
|
{
|
||||||
|
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
||||||
|
|
||||||
|
if (drawdata == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
LISTBASE_FOREACH(DrawData *, dd, drawdata) {
|
||||||
|
if (dd->engine_type == engine_type) {
|
||||||
|
return dd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectEngineData *DRW_object_engine_data_ensure(
|
DrawData *DRW_drawdata_ensure(
|
||||||
Object *ob,
|
ID *id,
|
||||||
DrawEngineType *engine_type,
|
DrawEngineType *engine_type,
|
||||||
size_t size,
|
size_t size,
|
||||||
ObjectEngineDataInitCb init_cb,
|
DrawDataInitCb init_cb,
|
||||||
ObjectEngineDataFreeCb free_cb)
|
DrawDataFreeCb free_cb)
|
||||||
{
|
{
|
||||||
BLI_assert(size >= sizeof(ObjectEngineData));
|
BLI_assert(size >= sizeof(DrawData));
|
||||||
|
BLI_assert(id_can_have_drawdata(id));
|
||||||
/* Try to re-use existing data. */
|
/* Try to re-use existing data. */
|
||||||
ObjectEngineData *oed = DRW_object_engine_data_get(ob, engine_type);
|
DrawData *dd = DRW_drawdata_get(id, engine_type);
|
||||||
if (oed != NULL) {
|
if (dd != NULL) {
|
||||||
return oed;
|
return dd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
||||||
|
|
||||||
/* Allocate new data. */
|
/* Allocate new data. */
|
||||||
if ((ob->base_flag & BASE_FROMDUPLI) != 0) {
|
if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROMDUPLI) != 0) {
|
||||||
/* NOTE: data is not persistent in this case. It is reset each redraw. */
|
/* NOTE: data is not persistent in this case. It is reset each redraw. */
|
||||||
BLI_assert(free_cb == NULL); /* No callback allowed. */
|
BLI_assert(free_cb == NULL); /* No callback allowed. */
|
||||||
/* Round to sizeof(float) for DRW_instance_data_request(). */
|
/* Round to sizeof(float) for DRW_instance_data_request(). */
|
||||||
@@ -734,21 +797,37 @@ ObjectEngineData *DRW_object_engine_data_ensure(
|
|||||||
if (DST.object_instance_data[fsize] == NULL) {
|
if (DST.object_instance_data[fsize] == NULL) {
|
||||||
DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize);
|
DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize);
|
||||||
}
|
}
|
||||||
oed = (ObjectEngineData *)DRW_instance_data_next(DST.object_instance_data[fsize]);
|
dd = (DrawData *)DRW_instance_data_next(DST.object_instance_data[fsize]);
|
||||||
memset(oed, 0, size);
|
memset(dd, 0, size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
oed = MEM_callocN(size, "ObjectEngineData");
|
dd = MEM_callocN(size, "DrawData");
|
||||||
}
|
}
|
||||||
oed->engine_type = engine_type;
|
dd->engine_type = engine_type;
|
||||||
oed->free = free_cb;
|
dd->free = free_cb;
|
||||||
/* Perform user-side initialization, if needed. */
|
/* Perform user-side initialization, if needed. */
|
||||||
if (init_cb != NULL) {
|
if (init_cb != NULL) {
|
||||||
init_cb(oed);
|
init_cb(dd);
|
||||||
}
|
}
|
||||||
/* Register in the list. */
|
/* Register in the list. */
|
||||||
BLI_addtail(&ob->drawdata, oed);
|
BLI_addtail((ListBase *)drawdata, dd);
|
||||||
return oed;
|
return dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRW_drawdata_free(ID *id)
|
||||||
|
{
|
||||||
|
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
||||||
|
|
||||||
|
if (drawdata == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LISTBASE_FOREACH(DrawData *, dd, drawdata) {
|
||||||
|
if (dd->free != NULL) {
|
||||||
|
dd->free(dd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_freelistN((ListBase *)drawdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@@ -794,6 +873,22 @@ static void drw_engines_cache_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drw_engines_world_update(Scene *scene)
|
||||||
|
{
|
||||||
|
if (scene->world == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
|
||||||
|
DrawEngineType *engine = link->data;
|
||||||
|
ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
|
||||||
|
|
||||||
|
if (engine->id_update) {
|
||||||
|
engine->id_update(data, &scene->world->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void drw_engines_cache_populate(Object *ob)
|
static void drw_engines_cache_populate(Object *ob)
|
||||||
{
|
{
|
||||||
DST.ob_state = NULL;
|
DST.ob_state = NULL;
|
||||||
@@ -1161,7 +1256,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
|
|||||||
/* XXX Really nasty locking. But else this could
|
/* XXX Really nasty locking. But else this could
|
||||||
* be executed by the material previews thread
|
* be executed by the material previews thread
|
||||||
* while rendering a viewport. */
|
* while rendering a viewport. */
|
||||||
BLI_mutex_lock(&DST.gl_context_mutex);
|
BLI_ticket_mutex_lock(DST.gl_context_mutex);
|
||||||
|
|
||||||
/* Reset before using it. */
|
/* Reset before using it. */
|
||||||
drw_state_prepare_clean_for_draw(&DST);
|
drw_state_prepare_clean_for_draw(&DST);
|
||||||
@@ -1189,7 +1284,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
|
|||||||
|
|
||||||
drw_engines_disable();
|
drw_engines_disable();
|
||||||
|
|
||||||
BLI_mutex_unlock(&DST.gl_context_mutex);
|
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1273,6 +1368,7 @@ void DRW_draw_render_loop_ex(
|
|||||||
{
|
{
|
||||||
PROFILE_START(stime);
|
PROFILE_START(stime);
|
||||||
drw_engines_cache_init();
|
drw_engines_cache_init();
|
||||||
|
drw_engines_world_update(scene);
|
||||||
|
|
||||||
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
|
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
|
||||||
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
|
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
|
||||||
@@ -1458,14 +1554,10 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
|
|||||||
|
|
||||||
/* Changing Context */
|
/* Changing Context */
|
||||||
if (re_gl_context != NULL) {
|
if (re_gl_context != NULL) {
|
||||||
/* TODO get rid of the blocking. Only here because of the static global DST. */
|
DRW_opengl_render_context_enable(re_gl_context);
|
||||||
BLI_mutex_lock(&DST.gl_context_mutex);
|
/* We need to query gwn context after a gl context has been bound. */
|
||||||
WM_opengl_context_activate(re_gl_context);
|
|
||||||
re_gwn_context = RE_gwn_context_get(render);
|
re_gwn_context = RE_gwn_context_get(render);
|
||||||
if (GWN_context_active_get() == NULL) {
|
DRW_gawain_render_context_enable(re_gwn_context);
|
||||||
GWN_context_active_set(re_gwn_context);
|
|
||||||
}
|
|
||||||
DRW_shape_cache_reset(); /* XXX fix that too. */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DRW_opengl_context_enable();
|
DRW_opengl_context_enable();
|
||||||
@@ -1544,12 +1636,8 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
|
|||||||
|
|
||||||
/* Changing Context */
|
/* Changing Context */
|
||||||
if (re_gl_context != NULL) {
|
if (re_gl_context != NULL) {
|
||||||
DRW_shape_cache_reset(); /* XXX fix that too. */
|
DRW_gawain_render_context_disable(re_gwn_context);
|
||||||
glFlush();
|
DRW_opengl_render_context_disable(re_gl_context);
|
||||||
GWN_context_active_set(NULL);
|
|
||||||
WM_opengl_context_release(re_gl_context);
|
|
||||||
/* TODO get rid of the blocking. */
|
|
||||||
BLI_mutex_unlock(&DST.gl_context_mutex);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DRW_opengl_context_disable();
|
DRW_opengl_context_disable();
|
||||||
@@ -1575,6 +1663,56 @@ void DRW_render_object_iter(
|
|||||||
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
|
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assume a valid gl context is bound (and that the gl_context_mutex has been aquired).
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||||
|
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||||
|
|
||||||
|
/* Reset before using it. */
|
||||||
|
drw_state_prepare_clean_for_draw(&DST);
|
||||||
|
DST.options.is_image_render = true;
|
||||||
|
DST.options.is_scene_render = true;
|
||||||
|
DST.options.draw_background = false;
|
||||||
|
|
||||||
|
DST.draw_ctx = (DRWContextState){
|
||||||
|
.scene = scene,
|
||||||
|
.view_layer = view_layer,
|
||||||
|
.engine_type = NULL,
|
||||||
|
.depsgraph = depsgraph,
|
||||||
|
.object_mode = OB_MODE_OBJECT,
|
||||||
|
};
|
||||||
|
drw_context_state_init();
|
||||||
|
|
||||||
|
DST.viewport = GPU_viewport_create();
|
||||||
|
const int size[2] = {1, 1};
|
||||||
|
GPU_viewport_size_set(DST.viewport, size);
|
||||||
|
|
||||||
|
drw_viewport_var_init();
|
||||||
|
|
||||||
|
DRW_hair_init();
|
||||||
|
|
||||||
|
ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
|
||||||
|
|
||||||
|
/* Execute the callback */
|
||||||
|
callback(data, user_data);
|
||||||
|
DST.buffer_finish_called = false;
|
||||||
|
|
||||||
|
GPU_viewport_free(DST.viewport);
|
||||||
|
GPU_framebuffer_restore();
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* Avoid accidental reuse. */
|
||||||
|
drw_state_ensure_not_reused(&DST);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static struct DRWSelectBuffer {
|
static struct DRWSelectBuffer {
|
||||||
struct GPUFrameBuffer *framebuffer;
|
struct GPUFrameBuffer *framebuffer;
|
||||||
struct GPUTexture *texture_depth;
|
struct GPUTexture *texture_depth;
|
||||||
@@ -1697,6 +1835,7 @@ void DRW_draw_select_loop(
|
|||||||
|
|
||||||
{
|
{
|
||||||
drw_engines_cache_init();
|
drw_engines_cache_init();
|
||||||
|
drw_engines_world_update(scene);
|
||||||
|
|
||||||
if (use_obedit) {
|
if (use_obedit) {
|
||||||
#if 0
|
#if 0
|
||||||
@@ -1891,6 +2030,7 @@ void DRW_draw_depth_loop(
|
|||||||
|
|
||||||
{
|
{
|
||||||
drw_engines_cache_init();
|
drw_engines_cache_init();
|
||||||
|
drw_engines_world_update(scene);
|
||||||
|
|
||||||
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
|
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
|
||||||
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
|
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
|
||||||
@@ -2182,7 +2322,7 @@ void DRW_opengl_context_create(void)
|
|||||||
{
|
{
|
||||||
BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */
|
BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */
|
||||||
|
|
||||||
BLI_mutex_init(&DST.gl_context_mutex);
|
DST.gl_context_mutex = BLI_ticket_mutex_alloc();
|
||||||
if (!G.background) {
|
if (!G.background) {
|
||||||
immDeactivate();
|
immDeactivate();
|
||||||
}
|
}
|
||||||
@@ -2207,7 +2347,7 @@ void DRW_opengl_context_destroy(void)
|
|||||||
GWN_context_active_set(DST.gwn_context);
|
GWN_context_active_set(DST.gwn_context);
|
||||||
GWN_context_discard(DST.gwn_context);
|
GWN_context_discard(DST.gwn_context);
|
||||||
WM_opengl_context_dispose(DST.gl_context);
|
WM_opengl_context_dispose(DST.gl_context);
|
||||||
BLI_mutex_end(&DST.gl_context_mutex);
|
BLI_ticket_mutex_free(DST.gl_context_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2217,7 +2357,7 @@ void DRW_opengl_context_enable(void)
|
|||||||
/* IMPORTANT: We dont support immediate mode in render mode!
|
/* IMPORTANT: We dont support immediate mode in render mode!
|
||||||
* This shall remain in effect until immediate mode supports
|
* This shall remain in effect until immediate mode supports
|
||||||
* multiple threads. */
|
* multiple threads. */
|
||||||
BLI_mutex_lock(&DST.gl_context_mutex);
|
BLI_ticket_mutex_lock(DST.gl_context_mutex);
|
||||||
if (BLI_thread_is_main()) {
|
if (BLI_thread_is_main()) {
|
||||||
if (!G.background) {
|
if (!G.background) {
|
||||||
immDeactivate();
|
immDeactivate();
|
||||||
@@ -2251,8 +2391,43 @@ void DRW_opengl_context_disable(void)
|
|||||||
GWN_context_active_set(NULL);
|
GWN_context_active_set(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_mutex_unlock(&DST.gl_context_mutex);
|
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DRW_opengl_render_context_enable(void *re_gl_context)
|
||||||
|
{
|
||||||
|
/* If thread is main you should use DRW_opengl_context_enable(). */
|
||||||
|
BLI_assert(!BLI_thread_is_main());
|
||||||
|
|
||||||
|
/* TODO get rid of the blocking. Only here because of the static global DST. */
|
||||||
|
BLI_ticket_mutex_lock(DST.gl_context_mutex);
|
||||||
|
WM_opengl_context_activate(re_gl_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRW_opengl_render_context_disable(void *re_gl_context)
|
||||||
|
{
|
||||||
|
glFlush();
|
||||||
|
WM_opengl_context_release(re_gl_context);
|
||||||
|
/* TODO get rid of the blocking. */
|
||||||
|
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Needs to be called AFTER DRW_opengl_render_context_enable() */
|
||||||
|
void DRW_gawain_render_context_enable(void *re_gwn_context)
|
||||||
|
{
|
||||||
|
/* If thread is main you should use DRW_opengl_context_enable(). */
|
||||||
|
BLI_assert(!BLI_thread_is_main());
|
||||||
|
|
||||||
|
GWN_context_active_set(re_gwn_context);
|
||||||
|
DRW_shape_cache_reset(); /* XXX fix that too. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Needs to be called BEFORE DRW_opengl_render_context_disable() */
|
||||||
|
void DRW_gawain_render_context_disable(void *UNUSED(re_gwn_context))
|
||||||
|
{
|
||||||
|
DRW_shape_cache_reset(); /* XXX fix that too. */
|
||||||
|
GWN_context_active_set(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
@@ -373,7 +373,7 @@ typedef struct DRWManager {
|
|||||||
* the top portion of the struct so DO NOT MOVE IT! */
|
* the top portion of the struct so DO NOT MOVE IT! */
|
||||||
void *gl_context; /* Unique ghost context used by the draw manager. */
|
void *gl_context; /* Unique ghost context used by the draw manager. */
|
||||||
Gwn_Context *gwn_context;
|
Gwn_Context *gwn_context;
|
||||||
ThreadMutex gl_context_mutex; /* Mutex to lock the drw manager and avoid concurent context usage. */
|
TicketMutex *gl_context_mutex; /* Mutex to lock the drw manager and avoid concurent context usage. */
|
||||||
|
|
||||||
/** GPU Resource State: Memory storage between drawing. */
|
/** GPU Resource State: Memory storage between drawing. */
|
||||||
struct {
|
struct {
|
||||||
|
@@ -154,10 +154,10 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
|
|||||||
MEM_freeN(comp);
|
MEM_freeN(comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drw_deferred_shader_add(GPUMaterial *mat)
|
static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
|
||||||
{
|
{
|
||||||
/* Do not deferre the compilation if we are rendering for image. */
|
/* Do not deferre the compilation if we are rendering for image. */
|
||||||
if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION) {
|
if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION || !deferred) {
|
||||||
/* Double checking that this GPUMaterial is not going to be
|
/* Double checking that this GPUMaterial is not going to be
|
||||||
* compiled by another thread. */
|
* compiled by another thread. */
|
||||||
DRW_deferred_shader_remove(mat);
|
DRW_deferred_shader_remove(mat);
|
||||||
@@ -308,10 +308,10 @@ GPUShader *DRW_shader_create_3D_depth_only(void)
|
|||||||
return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
|
return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options)
|
GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options, bool deferred)
|
||||||
{
|
{
|
||||||
GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options);
|
GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options);
|
||||||
if (DRW_state_is_image_render()) {
|
if (DRW_state_is_image_render() || !deferred) {
|
||||||
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
||||||
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
|
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
|
||||||
* with the shader code and we will resume the compilation from there. */
|
* with the shader code and we will resume the compilation from there. */
|
||||||
@@ -321,10 +321,10 @@ GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int
|
|||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type, int options)
|
GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type, int options, bool deferred)
|
||||||
{
|
{
|
||||||
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options);
|
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options);
|
||||||
if (DRW_state_is_image_render()) {
|
if (DRW_state_is_image_render() || !deferred) {
|
||||||
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
||||||
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
|
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
|
||||||
* with the shader code and we will resume the compilation from there. */
|
* with the shader code and we will resume the compilation from there. */
|
||||||
@@ -336,7 +336,7 @@ GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type
|
|||||||
|
|
||||||
GPUMaterial *DRW_shader_create_from_world(
|
GPUMaterial *DRW_shader_create_from_world(
|
||||||
struct Scene *scene, World *wo, const void *engine_type, int options,
|
struct Scene *scene, World *wo, const void *engine_type, int options,
|
||||||
const char *vert, const char *geom, const char *frag_lib, const char *defines)
|
const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred)
|
||||||
{
|
{
|
||||||
GPUMaterial *mat = NULL;
|
GPUMaterial *mat = NULL;
|
||||||
if (DRW_state_is_image_render()) {
|
if (DRW_state_is_image_render()) {
|
||||||
@@ -350,7 +350,7 @@ GPUMaterial *DRW_shader_create_from_world(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
||||||
drw_deferred_shader_add(mat);
|
drw_deferred_shader_add(mat, deferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mat;
|
return mat;
|
||||||
@@ -358,7 +358,7 @@ GPUMaterial *DRW_shader_create_from_world(
|
|||||||
|
|
||||||
GPUMaterial *DRW_shader_create_from_material(
|
GPUMaterial *DRW_shader_create_from_material(
|
||||||
struct Scene *scene, Material *ma, const void *engine_type, int options,
|
struct Scene *scene, Material *ma, const void *engine_type, int options,
|
||||||
const char *vert, const char *geom, const char *frag_lib, const char *defines)
|
const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred)
|
||||||
{
|
{
|
||||||
GPUMaterial *mat = NULL;
|
GPUMaterial *mat = NULL;
|
||||||
if (DRW_state_is_image_render()) {
|
if (DRW_state_is_image_render()) {
|
||||||
@@ -372,7 +372,7 @@ GPUMaterial *DRW_shader_create_from_material(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
||||||
drw_deferred_shader_add(mat);
|
drw_deferred_shader_add(mat, deferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mat;
|
return mat;
|
||||||
|
@@ -908,7 +908,7 @@ static void OBJECT_cache_init(void *vedata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_POINT;
|
||||||
DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state);
|
DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state);
|
||||||
struct Gwn_Batch *sphere = DRW_cache_sphere_get();
|
struct Gwn_Batch *sphere = DRW_cache_sphere_get();
|
||||||
struct Gwn_Batch *quad = DRW_cache_quad_get();
|
struct Gwn_Batch *quad = DRW_cache_quad_get();
|
||||||
@@ -1355,14 +1355,14 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, ViewLayer *vie
|
|||||||
static float zero = 0.0f;
|
static float zero = 0.0f;
|
||||||
|
|
||||||
typedef struct LampEngineData {
|
typedef struct LampEngineData {
|
||||||
ObjectEngineData engine_data;
|
DrawData dd;
|
||||||
float shape_mat[4][4];
|
float shape_mat[4][4];
|
||||||
float spot_blend_mat[4][4];
|
float spot_blend_mat[4][4];
|
||||||
} LampEngineData;
|
} LampEngineData;
|
||||||
|
|
||||||
LampEngineData *lamp_engine_data =
|
LampEngineData *lamp_engine_data =
|
||||||
(LampEngineData *)DRW_object_engine_data_ensure(
|
(LampEngineData *)DRW_drawdata_ensure(
|
||||||
ob,
|
&ob->id,
|
||||||
&draw_engine_object_type,
|
&draw_engine_object_type,
|
||||||
sizeof(LampEngineData),
|
sizeof(LampEngineData),
|
||||||
NULL,
|
NULL,
|
||||||
@@ -1712,7 +1712,7 @@ static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer *
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct OBJECT_LightProbeEngineData {
|
typedef struct OBJECT_LightProbeEngineData {
|
||||||
ObjectEngineData engine_data;
|
DrawData dd;
|
||||||
|
|
||||||
float prb_mats[6][4][4];
|
float prb_mats[6][4][4];
|
||||||
float probe_cube_mat[4][4];
|
float probe_cube_mat[4][4];
|
||||||
@@ -1733,8 +1733,8 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
|
|||||||
int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color);
|
int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color);
|
||||||
|
|
||||||
OBJECT_LightProbeEngineData *prb_data =
|
OBJECT_LightProbeEngineData *prb_data =
|
||||||
(OBJECT_LightProbeEngineData *)DRW_object_engine_data_ensure(
|
(OBJECT_LightProbeEngineData *)DRW_drawdata_ensure(
|
||||||
ob,
|
&ob->id,
|
||||||
&draw_engine_object_type,
|
&draw_engine_object_type,
|
||||||
sizeof(OBJECT_LightProbeEngineData),
|
sizeof(OBJECT_LightProbeEngineData),
|
||||||
NULL,
|
NULL,
|
||||||
@@ -1785,8 +1785,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
|
|||||||
DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1);
|
DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1);
|
||||||
DRW_shgroup_uniform_vec3(grp, "increment_z", prb_data->increment_z, 1);
|
DRW_shgroup_uniform_vec3(grp, "increment_z", prb_data->increment_z, 1);
|
||||||
DRW_shgroup_uniform_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1);
|
DRW_shgroup_uniform_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1);
|
||||||
DRW_shgroup_uniform_float(grp, "sphere_size", &prb->data_draw_size, 1);
|
DRW_shgroup_call_procedural_points_add(grp, prb_data->cell_count, NULL);
|
||||||
DRW_shgroup_call_instances_add(grp, DRW_cache_sphere_get(), NULL, &prb_data->cell_count);
|
|
||||||
}
|
}
|
||||||
else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
|
else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
|
||||||
prb_data->draw_size = prb->data_draw_size * 0.1f;
|
prb_data->draw_size = prb->data_draw_size * 0.1f;
|
||||||
@@ -1794,6 +1793,9 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
|
|||||||
copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]);
|
copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]);
|
||||||
|
|
||||||
DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id);
|
DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id);
|
||||||
|
/* TODO remove or change the drawing of the cube probes. Theses line draws nothing on purpose
|
||||||
|
* to keep the call ids correct. */
|
||||||
|
zero_m4(prb_data->probe_cube_mat);
|
||||||
DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, prb_data->probe_cube_mat);
|
DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, prb_data->probe_cube_mat);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
|
|
||||||
in vec3 pos;
|
|
||||||
in vec3 nor;
|
|
||||||
|
|
||||||
uniform mat4 ViewProjectionMatrix;
|
uniform mat4 ViewProjectionMatrix;
|
||||||
|
|
||||||
uniform float sphere_size;
|
uniform float sphere_size;
|
||||||
@@ -10,6 +7,7 @@ uniform vec3 corner;
|
|||||||
uniform vec3 increment_x;
|
uniform vec3 increment_x;
|
||||||
uniform vec3 increment_y;
|
uniform vec3 increment_y;
|
||||||
uniform vec3 increment_z;
|
uniform vec3 increment_z;
|
||||||
|
uniform vec3 screen_vecs[2];
|
||||||
|
|
||||||
uniform int call_id; /* we don't want the builtin callId which would be 0. */
|
uniform int call_id; /* we don't want the builtin callId which would be 0. */
|
||||||
uniform int baseId;
|
uniform int baseId;
|
||||||
@@ -20,16 +18,17 @@ void main()
|
|||||||
{
|
{
|
||||||
vec3 ls_cell_location;
|
vec3 ls_cell_location;
|
||||||
/* Keep in sync with update_irradiance_probe */
|
/* Keep in sync with update_irradiance_probe */
|
||||||
ls_cell_location.z = float(gl_InstanceID % grid_resolution.z);
|
ls_cell_location.z = float(gl_VertexID % grid_resolution.z);
|
||||||
ls_cell_location.y = float((gl_InstanceID / grid_resolution.z) % grid_resolution.y);
|
ls_cell_location.y = float((gl_VertexID / grid_resolution.z) % grid_resolution.y);
|
||||||
ls_cell_location.x = float(gl_InstanceID / (grid_resolution.z * grid_resolution.y));
|
ls_cell_location.x = float(gl_VertexID / (grid_resolution.z * grid_resolution.y));
|
||||||
|
|
||||||
vec3 ws_cell_location = corner +
|
vec3 ws_cell_location = corner +
|
||||||
(increment_x * ls_cell_location.x +
|
(increment_x * ls_cell_location.x +
|
||||||
increment_y * ls_cell_location.y +
|
increment_y * ls_cell_location.y +
|
||||||
increment_z * ls_cell_location.z);
|
increment_z * ls_cell_location.z);
|
||||||
|
|
||||||
gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 * sphere_size + ws_cell_location, 1.0);
|
gl_Position = ViewProjectionMatrix * vec4(ws_cell_location, 1.0);
|
||||||
|
gl_PointSize = 2.0f;
|
||||||
|
|
||||||
finalId = uint(baseId + call_id);
|
finalId = uint(baseId + call_id);
|
||||||
}
|
}
|
||||||
|
@@ -56,6 +56,9 @@ void MATERIAL_OT_paste(struct wmOperatorType *ot);
|
|||||||
void SCENE_OT_view_layer_add(struct wmOperatorType *ot);
|
void SCENE_OT_view_layer_add(struct wmOperatorType *ot);
|
||||||
void SCENE_OT_view_layer_remove(struct wmOperatorType *ot);
|
void SCENE_OT_view_layer_remove(struct wmOperatorType *ot);
|
||||||
|
|
||||||
|
void SCENE_OT_light_cache_bake(struct wmOperatorType *ot);
|
||||||
|
void SCENE_OT_light_cache_free(struct wmOperatorType *ot);
|
||||||
|
|
||||||
void SCENE_OT_render_view_add(struct wmOperatorType *ot);
|
void SCENE_OT_render_view_add(struct wmOperatorType *ot);
|
||||||
void SCENE_OT_render_view_remove(struct wmOperatorType *ot);
|
void SCENE_OT_render_view_remove(struct wmOperatorType *ot);
|
||||||
|
|
||||||
|
@@ -62,6 +62,9 @@ void ED_operatortypes_render(void)
|
|||||||
WM_operatortype_append(SCENE_OT_render_view_add);
|
WM_operatortype_append(SCENE_OT_render_view_add);
|
||||||
WM_operatortype_append(SCENE_OT_render_view_remove);
|
WM_operatortype_append(SCENE_OT_render_view_remove);
|
||||||
|
|
||||||
|
WM_operatortype_append(SCENE_OT_light_cache_bake);
|
||||||
|
WM_operatortype_append(SCENE_OT_light_cache_free);
|
||||||
|
|
||||||
#ifdef WITH_FREESTYLE
|
#ifdef WITH_FREESTYLE
|
||||||
WM_operatortype_append(SCENE_OT_freestyle_module_add);
|
WM_operatortype_append(SCENE_OT_freestyle_module_add);
|
||||||
WM_operatortype_append(SCENE_OT_freestyle_module_remove);
|
WM_operatortype_append(SCENE_OT_freestyle_module_remove);
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "DNA_curve_types.h"
|
#include "DNA_curve_types.h"
|
||||||
#include "DNA_lamp_types.h"
|
#include "DNA_lamp_types.h"
|
||||||
|
#include "DNA_lightprobe_types.h"
|
||||||
#include "DNA_material_types.h"
|
#include "DNA_material_types.h"
|
||||||
#include "DNA_node_types.h"
|
#include "DNA_node_types.h"
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
@@ -94,6 +95,8 @@
|
|||||||
|
|
||||||
#include "RE_pipeline.h"
|
#include "RE_pipeline.h"
|
||||||
|
|
||||||
|
#include "engines/eevee/eevee_lightcache.h"
|
||||||
|
|
||||||
#include "render_intern.h" // own include
|
#include "render_intern.h" // own include
|
||||||
|
|
||||||
/********************** material slot operators *********************/
|
/********************** material slot operators *********************/
|
||||||
@@ -673,6 +676,185 @@ void SCENE_OT_view_layer_remove(wmOperatorType *ot)
|
|||||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************** light cache operators *********************/
|
||||||
|
enum {
|
||||||
|
LIGHTCACHE_SUBSET_ALL = 0,
|
||||||
|
LIGHTCACHE_SUBSET_DIRTY,
|
||||||
|
LIGHTCACHE_SUBSET_CUBE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void light_cache_bake_tag_cache(Scene *scene, wmOperator *op)
|
||||||
|
{
|
||||||
|
if (scene->eevee.light_cache != NULL) {
|
||||||
|
int subset = RNA_enum_get(op->ptr, "subset");
|
||||||
|
switch (subset) {
|
||||||
|
case LIGHTCACHE_SUBSET_ALL:
|
||||||
|
scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_UPDATE_CUBE;
|
||||||
|
break;
|
||||||
|
case LIGHTCACHE_SUBSET_CUBE:
|
||||||
|
scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
|
||||||
|
break;
|
||||||
|
case LIGHTCACHE_SUBSET_DIRTY:
|
||||||
|
/* Leave tag untouched. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* catch esc */
|
||||||
|
static int light_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||||
|
{
|
||||||
|
Scene *scene = (Scene *) op->customdata;
|
||||||
|
|
||||||
|
/* no running blender, remove handler and pass through */
|
||||||
|
if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
|
||||||
|
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* running render */
|
||||||
|
switch (event->type) {
|
||||||
|
case ESCKEY:
|
||||||
|
return OPERATOR_RUNNING_MODAL;
|
||||||
|
}
|
||||||
|
return OPERATOR_PASS_THROUGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void light_cache_bake_cancel(bContext *C, wmOperator *op)
|
||||||
|
{
|
||||||
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
|
Scene *scene = (Scene *) op->customdata;
|
||||||
|
|
||||||
|
/* kill on cancel, because job is using op->reports */
|
||||||
|
WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* executes blocking render */
|
||||||
|
static int light_cache_bake_exec(bContext *C, wmOperator *op)
|
||||||
|
{
|
||||||
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
|
Main *bmain = CTX_data_main(C);
|
||||||
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
|
||||||
|
G.is_break = false;
|
||||||
|
|
||||||
|
/* TODO abort if selected engine is not eevee. */
|
||||||
|
void *rj = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, false);
|
||||||
|
|
||||||
|
light_cache_bake_tag_cache(scene, op);
|
||||||
|
|
||||||
|
short stop = 0, do_update; float progress; /* Not actually used. */
|
||||||
|
EEVEE_lightbake_job(rj, &stop, &do_update, &progress);
|
||||||
|
EEVEE_lightbake_update(rj);
|
||||||
|
EEVEE_lightbake_job_data_free(rj);
|
||||||
|
|
||||||
|
// no redraw needed, we leave state as we entered it
|
||||||
|
ED_update_for_newframe(bmain, CTX_data_depsgraph(C));
|
||||||
|
|
||||||
|
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int light_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||||
|
{
|
||||||
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
|
wmWindow *win = CTX_wm_window(C);
|
||||||
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
|
Main *bmain = CTX_data_main(C);
|
||||||
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
int delay = RNA_int_get(op->ptr, "delay");
|
||||||
|
|
||||||
|
wmJob *wm_job = EEVEE_lightbake_job_create(wm, win, bmain, view_layer, scene, delay);
|
||||||
|
|
||||||
|
if (!wm_job) {
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add modal handler for ESC */
|
||||||
|
WM_event_add_modal_handler(C, op);
|
||||||
|
|
||||||
|
light_cache_bake_tag_cache(scene, op);
|
||||||
|
|
||||||
|
/* store actual owner of job, so modal operator could check for it,
|
||||||
|
* the reason of this is that active scene could change when rendering
|
||||||
|
* several layers from compositor [#31800]
|
||||||
|
*/
|
||||||
|
op->customdata = scene;
|
||||||
|
|
||||||
|
WM_jobs_start(wm, wm_job);
|
||||||
|
|
||||||
|
WM_cursor_wait(0);
|
||||||
|
|
||||||
|
return OPERATOR_RUNNING_MODAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SCENE_OT_light_cache_bake(wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
static const EnumPropertyItem light_cache_subset_items[] = {
|
||||||
|
{LIGHTCACHE_SUBSET_ALL, "ALL", 0, "All LightProbes", "Bake both irradiance grids and reflection cubemaps"},
|
||||||
|
{LIGHTCACHE_SUBSET_DIRTY, "DIRTY", 0, "Dirty Only", "Only bake lightprobes that are marked as dirty"},
|
||||||
|
{LIGHTCACHE_SUBSET_CUBE, "CUBEMAPS", 0, "Cubemaps Only", "Try to only bake reflection cubemaps if irradiance "
|
||||||
|
"grids are up to date"},
|
||||||
|
{0, NULL, 0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* identifiers */
|
||||||
|
ot->name = "Bake Light Cache";
|
||||||
|
ot->idname = "SCENE_OT_light_cache_bake";
|
||||||
|
ot->description = "Bake the active view layer lighting";
|
||||||
|
|
||||||
|
/* api callbacks */
|
||||||
|
ot->invoke = light_cache_bake_invoke;
|
||||||
|
ot->modal = light_cache_bake_modal;
|
||||||
|
ot->cancel = light_cache_bake_cancel;
|
||||||
|
ot->exec = light_cache_bake_exec;
|
||||||
|
|
||||||
|
ot->prop = RNA_def_int(ot->srna, "delay", 0, 0, 2000, "Delay", "Delay in millisecond before baking starts", 0, 2000);
|
||||||
|
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
|
||||||
|
|
||||||
|
ot->prop = RNA_def_enum(ot->srna, "subset", light_cache_subset_items, 0, "Subset", "Subset of probes to update");
|
||||||
|
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool light_cache_free_poll(bContext *C)
|
||||||
|
{
|
||||||
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
|
||||||
|
return scene->eevee.light_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int light_cache_free_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
|
{
|
||||||
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
|
||||||
|
if (!scene->eevee.light_cache) {
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
EEVEE_lightcache_free(scene->eevee.light_cache);
|
||||||
|
scene->eevee.light_cache = NULL;
|
||||||
|
|
||||||
|
EEVEE_lightcache_info_update(&scene->eevee);
|
||||||
|
|
||||||
|
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||||
|
|
||||||
|
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SCENE_OT_light_cache_free(wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
/* identifiers */
|
||||||
|
ot->name = "Free Light Cache";
|
||||||
|
ot->idname = "SCENE_OT_light_cache_free";
|
||||||
|
ot->description = "Free cached indirect lighting";
|
||||||
|
|
||||||
|
/* api callbacks */
|
||||||
|
ot->exec = light_cache_free_exec;
|
||||||
|
ot->poll = light_cache_free_poll;
|
||||||
|
}
|
||||||
|
|
||||||
/********************** render view operators *********************/
|
/********************** render view operators *********************/
|
||||||
|
|
||||||
static bool render_view_remove_poll(bContext *C)
|
static bool render_view_remove_poll(bContext *C)
|
||||||
|
@@ -294,9 +294,6 @@ static void world_changed(Main *UNUSED(bmain), World *wo)
|
|||||||
/* icons */
|
/* icons */
|
||||||
BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
|
BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
|
||||||
|
|
||||||
/* XXX temporary flag waiting for depsgraph proper tagging */
|
|
||||||
wo->update_flag = 1;
|
|
||||||
|
|
||||||
/* glsl */
|
/* glsl */
|
||||||
if (wo->id.recalc & ID_RECALC) {
|
if (wo->id.recalc & ID_RECALC) {
|
||||||
if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) {
|
if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) {
|
||||||
|
@@ -683,6 +683,18 @@ static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void view3d_lightcache_update(bContext *C)
|
||||||
|
{
|
||||||
|
PointerRNA op_ptr;
|
||||||
|
|
||||||
|
WM_operator_properties_create(&op_ptr, "SCENE_OT_light_cache_bake");
|
||||||
|
RNA_int_set(&op_ptr, "delay", 200);
|
||||||
|
RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY");
|
||||||
|
|
||||||
|
WM_operator_name_call(C, "SCENE_OT_light_cache_bake", WM_OP_INVOKE_DEFAULT, &op_ptr);
|
||||||
|
|
||||||
|
WM_operator_properties_free(&op_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* region dropbox definition */
|
/* region dropbox definition */
|
||||||
static void view3d_dropboxes(void)
|
static void view3d_dropboxes(void)
|
||||||
@@ -980,6 +992,9 @@ static void view3d_main_region_listener(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NC_LIGHTPROBE:
|
||||||
|
ED_area_tag_refresh(sa);
|
||||||
|
break;
|
||||||
case NC_IMAGE:
|
case NC_IMAGE:
|
||||||
/* this could be more fine grained checks if we had
|
/* this could be more fine grained checks if we had
|
||||||
* more context than just the region */
|
* more context than just the region */
|
||||||
@@ -1409,6 +1424,13 @@ static void space_view3d_listener(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void space_view3d_refresh(const bContext *C, ScrArea *UNUSED(sa))
|
||||||
|
{
|
||||||
|
/* This is only used by the auto lightprobe refresh for the moment.
|
||||||
|
* So we don't need to check anything to know what to do. */
|
||||||
|
view3d_lightcache_update((bContext *)C);
|
||||||
|
}
|
||||||
|
|
||||||
const char *view3d_context_dir[] = {
|
const char *view3d_context_dir[] = {
|
||||||
"active_base", "active_object", NULL
|
"active_base", "active_object", NULL
|
||||||
};
|
};
|
||||||
@@ -1509,6 +1531,7 @@ void ED_spacetype_view3d(void)
|
|||||||
st->free = view3d_free;
|
st->free = view3d_free;
|
||||||
st->init = view3d_init;
|
st->init = view3d_init;
|
||||||
st->listener = space_view3d_listener;
|
st->listener = space_view3d_listener;
|
||||||
|
st->refresh = space_view3d_refresh;
|
||||||
st->duplicate = view3d_duplicate;
|
st->duplicate = view3d_duplicate;
|
||||||
st->operatortypes = view3d_operatortypes;
|
st->operatortypes = view3d_operatortypes;
|
||||||
st->keymap = view3d_keymap;
|
st->keymap = view3d_keymap;
|
||||||
|
@@ -144,8 +144,23 @@ typedef enum GPUTextureFormat {
|
|||||||
GPU_DEPTH_COMPONENT16,
|
GPU_DEPTH_COMPONENT16,
|
||||||
} GPUTextureFormat;
|
} GPUTextureFormat;
|
||||||
|
|
||||||
|
typedef enum GPUDataFormat {
|
||||||
|
GPU_DATA_FLOAT,
|
||||||
|
GPU_DATA_INT,
|
||||||
|
GPU_DATA_UNSIGNED_INT,
|
||||||
|
GPU_DATA_UNSIGNED_BYTE,
|
||||||
|
GPU_DATA_UNSIGNED_INT_24_8,
|
||||||
|
GPU_DATA_10_11_11_REV,
|
||||||
|
} GPUDataFormat;
|
||||||
|
|
||||||
unsigned int GPU_texture_memory_usage_get(void);
|
unsigned int GPU_texture_memory_usage_get(void);
|
||||||
|
|
||||||
|
/* TODO make it static function again. (create function with GPUDataFormat exposed) */
|
||||||
|
GPUTexture *GPU_texture_create_nD(
|
||||||
|
int w, int h, int d, int n, const void *pixels,
|
||||||
|
GPUTextureFormat tex_format, GPUDataFormat gpu_data_format, int samples,
|
||||||
|
const bool can_rescale, char err_out[256]);
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_1D(
|
GPUTexture *GPU_texture_create_1D(
|
||||||
int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
|
int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
|
||||||
GPUTexture *GPU_texture_create_2D(
|
GPUTexture *GPU_texture_create_2D(
|
||||||
@@ -168,11 +183,15 @@ GPUTexture *GPU_texture_from_blender(
|
|||||||
struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time);
|
struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time);
|
||||||
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
|
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
|
||||||
|
|
||||||
void GPU_texture_update(GPUTexture *tex, const void *pixels);
|
void GPU_texture_add_mipmap(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl, const void *pixels);
|
||||||
|
|
||||||
|
void GPU_texture_update(GPUTexture *tex, GPUDataFormat data_format, const void *pixels);
|
||||||
void GPU_texture_update_sub(
|
void GPU_texture_update_sub(
|
||||||
GPUTexture *tex, const void *pixels,
|
GPUTexture *tex, GPUDataFormat gpu_data_format, const void *pixels,
|
||||||
int offset_x, int offset_y, int offset_z, int width, int height, int depth);
|
int offset_x, int offset_y, int offset_z, int width, int height, int depth);
|
||||||
|
|
||||||
|
void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl);
|
||||||
|
|
||||||
void GPU_invalid_tex_init(void);
|
void GPU_invalid_tex_init(void);
|
||||||
void GPU_invalid_tex_bind(int mode);
|
void GPU_invalid_tex_bind(int mode);
|
||||||
void GPU_invalid_tex_free(void);
|
void GPU_invalid_tex_free(void);
|
||||||
@@ -202,6 +221,7 @@ int GPU_texture_detach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb);
|
|||||||
int GPU_texture_target(const GPUTexture *tex);
|
int GPU_texture_target(const GPUTexture *tex);
|
||||||
int GPU_texture_width(const GPUTexture *tex);
|
int GPU_texture_width(const GPUTexture *tex);
|
||||||
int GPU_texture_height(const GPUTexture *tex);
|
int GPU_texture_height(const GPUTexture *tex);
|
||||||
|
int GPU_texture_layers(const GPUTexture *tex);
|
||||||
GPUTextureFormat GPU_texture_format(const GPUTexture *tex);
|
GPUTextureFormat GPU_texture_format(const GPUTexture *tex);
|
||||||
int GPU_texture_samples(const GPUTexture *tex);
|
int GPU_texture_samples(const GPUTexture *tex);
|
||||||
bool GPU_texture_cube(const GPUTexture *tex);
|
bool GPU_texture_cube(const GPUTexture *tex);
|
||||||
@@ -210,6 +230,8 @@ bool GPU_texture_stencil(const GPUTexture *tex);
|
|||||||
bool GPU_texture_integer(const GPUTexture *tex);
|
bool GPU_texture_integer(const GPUTexture *tex);
|
||||||
int GPU_texture_opengl_bindcode(const GPUTexture *tex);
|
int GPU_texture_opengl_bindcode(const GPUTexture *tex);
|
||||||
|
|
||||||
|
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -134,73 +134,159 @@ unsigned int GPU_texture_memory_usage_get(void)
|
|||||||
|
|
||||||
/* -------------------------------- */
|
/* -------------------------------- */
|
||||||
|
|
||||||
static GLenum gpu_texture_get_format(
|
static int gpu_get_component_count(GPUTextureFormat format)
|
||||||
int components, GPUTextureFormat data_type,
|
{
|
||||||
GLenum *format, GLenum *data_format, GPUTextureFormatFlag *format_flag, unsigned int *bytesize)
|
switch (format) {
|
||||||
|
case GPU_RGBA8:
|
||||||
|
case GPU_RGBA16F:
|
||||||
|
case GPU_RGBA16:
|
||||||
|
case GPU_RGBA32F:
|
||||||
|
return 4;
|
||||||
|
case GPU_RGB16F:
|
||||||
|
case GPU_R11F_G11F_B10F:
|
||||||
|
return 3;
|
||||||
|
case GPU_RG8:
|
||||||
|
case GPU_RG16:
|
||||||
|
case GPU_RG16F:
|
||||||
|
case GPU_RG16I:
|
||||||
|
case GPU_RG16UI:
|
||||||
|
case GPU_RG32F:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Definitely not complete, edit according to the gl specification. */
|
||||||
|
static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat data_format)
|
||||||
|
{
|
||||||
|
if (ELEM(tex_format, GPU_DEPTH_COMPONENT24,
|
||||||
|
GPU_DEPTH_COMPONENT16,
|
||||||
|
GPU_DEPTH_COMPONENT32F))
|
||||||
|
{
|
||||||
|
BLI_assert(data_format == GPU_DATA_FLOAT);
|
||||||
|
}
|
||||||
|
else if (tex_format == GPU_DEPTH24_STENCIL8) {
|
||||||
|
BLI_assert(data_format == GPU_DATA_UNSIGNED_INT_24_8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Integer formats */
|
||||||
|
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
|
||||||
|
if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
|
||||||
|
BLI_assert(data_format == GPU_DATA_UNSIGNED_INT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_assert(data_format == GPU_DATA_INT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Byte formats */
|
||||||
|
else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8)) {
|
||||||
|
BLI_assert(ELEM(data_format, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT));
|
||||||
|
}
|
||||||
|
/* Special case */
|
||||||
|
else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) {
|
||||||
|
BLI_assert(ELEM(data_format, GPU_DATA_10_11_11_REV, GPU_DATA_FLOAT));
|
||||||
|
}
|
||||||
|
/* Float formats */
|
||||||
|
else {
|
||||||
|
BLI_assert(ELEM(data_format, GPU_DATA_FLOAT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GPUDataFormat gpu_get_data_format_from_tex_format(GPUTextureFormat tex_format)
|
||||||
|
{
|
||||||
|
if (ELEM(tex_format, GPU_DEPTH_COMPONENT24,
|
||||||
|
GPU_DEPTH_COMPONENT16,
|
||||||
|
GPU_DEPTH_COMPONENT32F))
|
||||||
|
{
|
||||||
|
return GPU_DATA_FLOAT;
|
||||||
|
}
|
||||||
|
else if (tex_format == GPU_DEPTH24_STENCIL8) {
|
||||||
|
return GPU_DATA_UNSIGNED_INT_24_8;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Integer formats */
|
||||||
|
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
|
||||||
|
if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
|
||||||
|
return GPU_DATA_UNSIGNED_INT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return GPU_DATA_INT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Byte formats */
|
||||||
|
else if (ELEM(tex_format, GPU_R8)) {
|
||||||
|
return GPU_DATA_UNSIGNED_BYTE;
|
||||||
|
}
|
||||||
|
/* Special case */
|
||||||
|
else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) {
|
||||||
|
return GPU_DATA_10_11_11_REV;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return GPU_DATA_FLOAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Definitely not complete, edit according to the gl specification. */
|
||||||
|
static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormatFlag *format_flag)
|
||||||
{
|
{
|
||||||
if (ELEM(data_type, GPU_DEPTH_COMPONENT24,
|
if (ELEM(data_type, GPU_DEPTH_COMPONENT24,
|
||||||
GPU_DEPTH_COMPONENT16,
|
GPU_DEPTH_COMPONENT16,
|
||||||
GPU_DEPTH_COMPONENT32F))
|
GPU_DEPTH_COMPONENT32F))
|
||||||
{
|
{
|
||||||
*format_flag |= GPU_FORMAT_DEPTH;
|
*format_flag |= GPU_FORMAT_DEPTH;
|
||||||
*data_format = GL_FLOAT;
|
return GL_DEPTH_COMPONENT;
|
||||||
*format = GL_DEPTH_COMPONENT;
|
|
||||||
}
|
}
|
||||||
else if (data_type == GPU_DEPTH24_STENCIL8) {
|
else if (data_type == GPU_DEPTH24_STENCIL8) {
|
||||||
*format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL;
|
*format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL;
|
||||||
*data_format = GL_UNSIGNED_INT_24_8;
|
return GL_DEPTH_STENCIL;
|
||||||
*format = GL_DEPTH_STENCIL;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Integer formats */
|
/* Integer formats */
|
||||||
if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
|
if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
|
||||||
if (ELEM(data_type, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
|
|
||||||
*data_format = GL_UNSIGNED_INT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*data_format = GL_INT;
|
|
||||||
}
|
|
||||||
|
|
||||||
*format_flag |= GPU_FORMAT_INTEGER;
|
*format_flag |= GPU_FORMAT_INTEGER;
|
||||||
|
|
||||||
switch (components) {
|
switch (gpu_get_component_count(data_type)) {
|
||||||
case 1: *format = GL_RED_INTEGER; break;
|
case 1: return GL_RED_INTEGER; break;
|
||||||
case 2: *format = GL_RG_INTEGER; break;
|
case 2: return GL_RG_INTEGER; break;
|
||||||
case 3: *format = GL_RGB_INTEGER; break;
|
case 3: return GL_RGB_INTEGER; break;
|
||||||
case 4: *format = GL_RGBA_INTEGER; break;
|
case 4: return GL_RGBA_INTEGER; break;
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ELEM(data_type, GPU_R8)) {
|
else if (ELEM(data_type, GPU_R8)) {
|
||||||
*data_format = GL_UNSIGNED_BYTE;
|
*format_flag |= GPU_FORMAT_FLOAT;
|
||||||
*format = GL_RED;
|
return GL_RED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*data_format = GL_FLOAT;
|
|
||||||
*format_flag |= GPU_FORMAT_FLOAT;
|
*format_flag |= GPU_FORMAT_FLOAT;
|
||||||
|
|
||||||
switch (components) {
|
switch (gpu_get_component_count(data_type)) {
|
||||||
case 1: *format = GL_RED; break;
|
case 1: return GL_RED; break;
|
||||||
case 2: *format = GL_RG; break;
|
case 2: return GL_RG; break;
|
||||||
case 3: *format = GL_RGB; break;
|
case 3: return GL_RGB; break;
|
||||||
case 4: *format = GL_RGBA; break;
|
case 4: return GL_RGBA; break;
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLI_assert(0);
|
||||||
|
*format_flag |= GPU_FORMAT_FLOAT;
|
||||||
|
return GL_RGBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int gpu_get_bytesize(GPUTextureFormat data_type)
|
||||||
|
{
|
||||||
switch (data_type) {
|
switch (data_type) {
|
||||||
case GPU_RGBA32F:
|
case GPU_RGBA32F:
|
||||||
*bytesize = 32;
|
return 32;
|
||||||
break;
|
|
||||||
case GPU_RG32F:
|
case GPU_RG32F:
|
||||||
case GPU_RGBA16F:
|
case GPU_RGBA16F:
|
||||||
case GPU_RGBA16:
|
case GPU_RGBA16:
|
||||||
*bytesize = 16;
|
return 16;
|
||||||
break;
|
|
||||||
case GPU_RGB16F:
|
case GPU_RGB16F:
|
||||||
*bytesize = 12;
|
return 12;
|
||||||
break;
|
|
||||||
case GPU_RG16F:
|
case GPU_RG16F:
|
||||||
case GPU_RG16I:
|
case GPU_RG16I:
|
||||||
case GPU_RG16UI:
|
case GPU_RG16UI:
|
||||||
@@ -212,28 +298,28 @@ static GLenum gpu_texture_get_format(
|
|||||||
case GPU_R32F:
|
case GPU_R32F:
|
||||||
case GPU_R32UI:
|
case GPU_R32UI:
|
||||||
case GPU_R32I:
|
case GPU_R32I:
|
||||||
*bytesize = 4;
|
return 4;
|
||||||
break;
|
|
||||||
case GPU_DEPTH_COMPONENT24:
|
case GPU_DEPTH_COMPONENT24:
|
||||||
*bytesize = 3;
|
return 3;
|
||||||
break;
|
|
||||||
case GPU_DEPTH_COMPONENT16:
|
case GPU_DEPTH_COMPONENT16:
|
||||||
case GPU_R16F:
|
case GPU_R16F:
|
||||||
|
case GPU_R16UI:
|
||||||
case GPU_R16I:
|
case GPU_R16I:
|
||||||
case GPU_RG8:
|
case GPU_RG8:
|
||||||
*bytesize = 2;
|
return 2;
|
||||||
break;
|
|
||||||
case GPU_R8:
|
case GPU_R8:
|
||||||
*bytesize = 1;
|
return 1;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
*bytesize = 0;
|
BLI_assert(!"Texture format incorrect or unsupported\n");
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLenum gpu_get_gl_internalformat(GPUTextureFormat format)
|
||||||
|
{
|
||||||
/* You can add any of the available type to this list
|
/* You can add any of the available type to this list
|
||||||
* For available types see GPU_texture.h */
|
* For available types see GPU_texture.h */
|
||||||
switch (data_type) {
|
switch (format) {
|
||||||
/* Formats texture & renderbuffer */
|
/* Formats texture & renderbuffer */
|
||||||
case GPU_RGBA32F: return GL_RGBA32F;
|
case GPU_RGBA32F: return GL_RGBA32F;
|
||||||
case GPU_RGBA16F: return GL_RGBA16F;
|
case GPU_RGBA16F: return GL_RGBA16F;
|
||||||
@@ -265,31 +351,29 @@ static GLenum gpu_texture_get_format(
|
|||||||
case GPU_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24;
|
case GPU_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24;
|
||||||
case GPU_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16;
|
case GPU_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Texture format incorrect or unsupported\n");
|
BLI_assert(!"Texture format incorrect or unsupported\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gpu_texture_get_component_count(GPUTextureFormat format)
|
static GLenum gpu_get_gl_datatype(GPUDataFormat format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GPU_RGBA8:
|
case GPU_DATA_FLOAT:
|
||||||
case GPU_RGBA16F:
|
return GL_FLOAT;
|
||||||
case GPU_RGBA16:
|
case GPU_DATA_INT:
|
||||||
case GPU_RGBA32F:
|
return GL_INT;
|
||||||
return 4;
|
case GPU_DATA_UNSIGNED_INT:
|
||||||
case GPU_RGB16F:
|
return GL_UNSIGNED_INT;
|
||||||
case GPU_R11F_G11F_B10F:
|
case GPU_DATA_UNSIGNED_BYTE:
|
||||||
return 3;
|
return GL_UNSIGNED_BYTE;
|
||||||
case GPU_RG8:
|
case GPU_DATA_UNSIGNED_INT_24_8:
|
||||||
case GPU_RG16:
|
return GL_UNSIGNED_INT_24_8;
|
||||||
case GPU_RG16F:
|
case GPU_DATA_10_11_11_REV:
|
||||||
case GPU_RG16I:
|
return GL_UNSIGNED_INT_10F_11F_11F_REV;
|
||||||
case GPU_RG16UI:
|
|
||||||
case GPU_RG32F:
|
|
||||||
return 2;
|
|
||||||
default:
|
default:
|
||||||
return 1;
|
BLI_assert(!"Unhandled data format");
|
||||||
|
return GL_FLOAT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,22 +415,22 @@ static float *GPU_texture_3D_rescale(GPUTexture *tex, int w, int h, int d, int c
|
|||||||
/* This tries to allocate video memory for a given texture
|
/* This tries to allocate video memory for a given texture
|
||||||
* If alloc fails, lower the resolution until it fits. */
|
* If alloc fails, lower the resolution until it fits. */
|
||||||
static bool gpu_texture_try_alloc(
|
static bool gpu_texture_try_alloc(
|
||||||
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, GLenum data_format,
|
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum data_format, GLenum data_type,
|
||||||
int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels)
|
int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels)
|
||||||
{
|
{
|
||||||
int r_width;
|
int r_width;
|
||||||
|
|
||||||
switch (proxy) {
|
switch (proxy) {
|
||||||
case GL_PROXY_TEXTURE_1D:
|
case GL_PROXY_TEXTURE_1D:
|
||||||
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
|
glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL);
|
||||||
break;
|
break;
|
||||||
case GL_PROXY_TEXTURE_1D_ARRAY:
|
case GL_PROXY_TEXTURE_1D_ARRAY:
|
||||||
case GL_PROXY_TEXTURE_2D:
|
case GL_PROXY_TEXTURE_2D:
|
||||||
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
|
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
|
||||||
break;
|
break;
|
||||||
case GL_PROXY_TEXTURE_2D_ARRAY:
|
case GL_PROXY_TEXTURE_2D_ARRAY:
|
||||||
case GL_PROXY_TEXTURE_3D:
|
case GL_PROXY_TEXTURE_3D:
|
||||||
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
|
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,11 +451,11 @@ static bool gpu_texture_try_alloc(
|
|||||||
if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break;
|
if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break;
|
||||||
|
|
||||||
if (proxy == GL_PROXY_TEXTURE_1D)
|
if (proxy == GL_PROXY_TEXTURE_1D)
|
||||||
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
|
glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL);
|
||||||
else if (proxy == GL_PROXY_TEXTURE_2D)
|
else if (proxy == GL_PROXY_TEXTURE_2D)
|
||||||
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
|
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
|
||||||
else if (proxy == GL_PROXY_TEXTURE_3D)
|
else if (proxy == GL_PROXY_TEXTURE_3D)
|
||||||
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
|
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
|
||||||
|
|
||||||
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
|
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
|
||||||
}
|
}
|
||||||
@@ -384,6 +468,7 @@ static bool gpu_texture_try_alloc(
|
|||||||
/* Do nothing for now */
|
/* Do nothing for now */
|
||||||
return false;
|
return false;
|
||||||
case GL_PROXY_TEXTURE_3D:
|
case GL_PROXY_TEXTURE_3D:
|
||||||
|
BLI_assert(data_type == GL_FLOAT);
|
||||||
*rescaled_fpixels = GPU_texture_3D_rescale(tex, w, h, d, channels, fpixels);
|
*rescaled_fpixels = GPU_texture_3D_rescale(tex, w, h, d, channels, fpixels);
|
||||||
return (bool)*rescaled_fpixels;
|
return (bool)*rescaled_fpixels;
|
||||||
}
|
}
|
||||||
@@ -393,9 +478,9 @@ static bool gpu_texture_try_alloc(
|
|||||||
return (r_width > 0);
|
return (r_width > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GPUTexture *GPU_texture_create_nD(
|
GPUTexture *GPU_texture_create_nD(
|
||||||
int w, int h, int d, int n, const float *fpixels,
|
int w, int h, int d, int n, const void *pixels,
|
||||||
GPUTextureFormat data_type, int samples,
|
GPUTextureFormat tex_format, GPUDataFormat gpu_data_format, int samples,
|
||||||
const bool can_rescale, char err_out[256])
|
const bool can_rescale, char err_out[256])
|
||||||
{
|
{
|
||||||
if (samples) {
|
if (samples) {
|
||||||
@@ -409,8 +494,9 @@ static GPUTexture *GPU_texture_create_nD(
|
|||||||
tex->samples = samples;
|
tex->samples = samples;
|
||||||
tex->number = -1;
|
tex->number = -1;
|
||||||
tex->refcount = 1;
|
tex->refcount = 1;
|
||||||
tex->format = data_type;
|
tex->format = tex_format;
|
||||||
tex->components = gpu_texture_get_component_count(data_type);
|
tex->components = gpu_get_component_count(tex_format);
|
||||||
|
tex->bytesize = gpu_get_bytesize(tex_format);
|
||||||
tex->format_flag = 0;
|
tex->format_flag = 0;
|
||||||
|
|
||||||
if (n == 2) {
|
if (n == 2) {
|
||||||
@@ -434,12 +520,14 @@ static GPUTexture *GPU_texture_create_nD(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpu_validate_data_format(tex_format, gpu_data_format);
|
||||||
|
|
||||||
if (samples && n == 2 && d == 0)
|
if (samples && n == 2 && d == 0)
|
||||||
tex->target = GL_TEXTURE_2D_MULTISAMPLE;
|
tex->target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||||
|
|
||||||
GLenum format, internalformat, data_format;
|
GLenum internalformat = gpu_get_gl_internalformat(tex_format);
|
||||||
internalformat = gpu_texture_get_format(tex->components, data_type, &format, &data_format,
|
GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
|
||||||
&tex->format_flag, &tex->bytesize);
|
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
|
||||||
|
|
||||||
gpu_texture_memory_footprint_add(tex);
|
gpu_texture_memory_footprint_add(tex);
|
||||||
|
|
||||||
@@ -448,9 +536,9 @@ static GPUTexture *GPU_texture_create_nD(
|
|||||||
|
|
||||||
if (!tex->bindcode) {
|
if (!tex->bindcode) {
|
||||||
if (err_out)
|
if (err_out)
|
||||||
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed");
|
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed\n");
|
||||||
else
|
else
|
||||||
fprintf(stderr, "GPUTexture: texture create failed");
|
fprintf(stderr, "GPUTexture: texture create failed\n");
|
||||||
GPU_texture_free(tex);
|
GPU_texture_free(tex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -474,9 +562,9 @@ static GPUTexture *GPU_texture_create_nD(
|
|||||||
proxy = GL_PROXY_TEXTURE_3D;
|
proxy = GL_PROXY_TEXTURE_3D;
|
||||||
}
|
}
|
||||||
|
|
||||||
float *rescaled_fpixels = NULL;
|
float *rescaled_pixels = NULL;
|
||||||
bool valid = gpu_texture_try_alloc(tex, proxy, internalformat, format, data_format, tex->components, can_rescale,
|
bool valid = gpu_texture_try_alloc(tex, proxy, internalformat, data_format, data_type, tex->components, can_rescale,
|
||||||
fpixels, &rescaled_fpixels);
|
pixels, &rescaled_pixels);
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
if (err_out)
|
if (err_out)
|
||||||
BLI_snprintf(err_out, 256, "GPUTexture: texture alloc failed");
|
BLI_snprintf(err_out, 256, "GPUTexture: texture alloc failed");
|
||||||
@@ -487,7 +575,7 @@ static GPUTexture *GPU_texture_create_nD(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Upload Texture */
|
/* Upload Texture */
|
||||||
const float *pix = (rescaled_fpixels) ? rescaled_fpixels : fpixels;
|
const float *pix = (rescaled_pixels) ? rescaled_pixels : pixels;
|
||||||
|
|
||||||
if (tex->target == GL_TEXTURE_2D ||
|
if (tex->target == GL_TEXTURE_2D ||
|
||||||
tex->target == GL_TEXTURE_2D_MULTISAMPLE ||
|
tex->target == GL_TEXTURE_2D_MULTISAMPLE ||
|
||||||
@@ -496,21 +584,21 @@ static GPUTexture *GPU_texture_create_nD(
|
|||||||
if (samples) {
|
if (samples) {
|
||||||
glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true);
|
glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true);
|
||||||
if (pix)
|
if (pix)
|
||||||
glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, data_format, pix);
|
glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, data_format, data_type, pix);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, data_format, pix);
|
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tex->target == GL_TEXTURE_1D) {
|
else if (tex->target == GL_TEXTURE_1D) {
|
||||||
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, data_format, pix);
|
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, data_format, data_type, pix);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, pix);
|
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, pix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rescaled_fpixels)
|
if (rescaled_pixels)
|
||||||
MEM_freeN(rescaled_fpixels);
|
MEM_freeN(rescaled_pixels);
|
||||||
|
|
||||||
/* Texture Parameters */
|
/* Texture Parameters */
|
||||||
if (GPU_texture_stencil(tex) || /* Does not support filtering */
|
if (GPU_texture_stencil(tex) || /* Does not support filtering */
|
||||||
@@ -547,11 +635,9 @@ static GPUTexture *GPU_texture_cube_create(
|
|||||||
int w, int d,
|
int w, int d,
|
||||||
const float *fpixels_px, const float *fpixels_py, const float *fpixels_pz,
|
const float *fpixels_px, const float *fpixels_py, const float *fpixels_pz,
|
||||||
const float *fpixels_nx, const float *fpixels_ny, const float *fpixels_nz,
|
const float *fpixels_nx, const float *fpixels_ny, const float *fpixels_nz,
|
||||||
GPUTextureFormat data_type,
|
GPUTextureFormat tex_format, GPUDataFormat gpu_data_format,
|
||||||
char err_out[256])
|
char err_out[256])
|
||||||
{
|
{
|
||||||
GLenum format, internalformat, data_format;
|
|
||||||
|
|
||||||
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
|
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
|
||||||
tex->w = w;
|
tex->w = w;
|
||||||
tex->h = w;
|
tex->h = w;
|
||||||
@@ -559,8 +645,9 @@ static GPUTexture *GPU_texture_cube_create(
|
|||||||
tex->samples = 0;
|
tex->samples = 0;
|
||||||
tex->number = -1;
|
tex->number = -1;
|
||||||
tex->refcount = 1;
|
tex->refcount = 1;
|
||||||
tex->format = data_type;
|
tex->format = tex_format;
|
||||||
tex->components = gpu_texture_get_component_count(data_type);
|
tex->components = gpu_get_component_count(tex_format);
|
||||||
|
tex->bytesize = gpu_get_bytesize(tex_format);
|
||||||
tex->format_flag = GPU_FORMAT_CUBE;
|
tex->format_flag = GPU_FORMAT_CUBE;
|
||||||
|
|
||||||
if (d == 0) {
|
if (d == 0) {
|
||||||
@@ -571,8 +658,9 @@ static GPUTexture *GPU_texture_cube_create(
|
|||||||
// tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY;
|
// tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
internalformat = gpu_texture_get_format(tex->components, data_type, &format, &data_format,
|
GLenum internalformat = gpu_get_gl_internalformat(tex_format);
|
||||||
&tex->format_flag, &tex->bytesize);
|
GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
|
||||||
|
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
|
||||||
|
|
||||||
gpu_texture_memory_footprint_add(tex);
|
gpu_texture_memory_footprint_add(tex);
|
||||||
|
|
||||||
@@ -581,9 +669,9 @@ static GPUTexture *GPU_texture_cube_create(
|
|||||||
|
|
||||||
if (!tex->bindcode) {
|
if (!tex->bindcode) {
|
||||||
if (err_out)
|
if (err_out)
|
||||||
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed");
|
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed\n");
|
||||||
else
|
else
|
||||||
fprintf(stderr, "GPUTexture: texture create failed");
|
fprintf(stderr, "GPUTexture: texture create failed\n");
|
||||||
GPU_texture_free(tex);
|
GPU_texture_free(tex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -591,12 +679,12 @@ static GPUTexture *GPU_texture_cube_create(
|
|||||||
glBindTexture(tex->target, tex->bindcode);
|
glBindTexture(tex->target, tex->bindcode);
|
||||||
|
|
||||||
/* Upload Texture */
|
/* Upload Texture */
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_px);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, fpixels_px);
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_py);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, fpixels_py);
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_pz);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, fpixels_pz);
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_nx);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, fpixels_nx);
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_ny);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, fpixels_ny);
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_nz);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, fpixels_nz);
|
||||||
|
|
||||||
/* Texture Parameters */
|
/* Texture Parameters */
|
||||||
if (GPU_texture_stencil(tex) || /* Does not support filtering */
|
if (GPU_texture_stencil(tex) || /* Does not support filtering */
|
||||||
@@ -625,36 +713,37 @@ static GPUTexture *GPU_texture_cube_create(
|
|||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special buffer textures. data_type must be compatible with the buffer content. */
|
/* Special buffer textures. tex_format must be compatible with the buffer content. */
|
||||||
GPUTexture *GPU_texture_create_buffer(GPUTextureFormat data_type, const GLuint buffer)
|
GPUTexture *GPU_texture_create_buffer(GPUTextureFormat tex_format, const GLuint buffer)
|
||||||
{
|
{
|
||||||
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
|
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
|
||||||
tex->number = -1;
|
tex->number = -1;
|
||||||
tex->refcount = 1;
|
tex->refcount = 1;
|
||||||
tex->format = data_type;
|
tex->format = tex_format;
|
||||||
tex->components = gpu_texture_get_component_count(data_type);
|
tex->components = gpu_get_component_count(tex_format);
|
||||||
tex->format_flag = 0;
|
tex->format_flag = 0;
|
||||||
tex->target_base = tex->target = GL_TEXTURE_BUFFER;
|
tex->target_base = tex->target = GL_TEXTURE_BUFFER;
|
||||||
|
tex->bytesize = gpu_get_bytesize(tex_format);
|
||||||
|
|
||||||
GLenum format, internalformat, data_format;
|
GLenum internalformat = gpu_get_gl_internalformat(tex_format);
|
||||||
internalformat = gpu_texture_get_format(tex->components, data_type, &format, &data_format,
|
|
||||||
&tex->format_flag, &tex->bytesize);
|
|
||||||
|
|
||||||
if (!(ELEM(data_type, GPU_R8, GPU_R16) ||
|
gpu_get_gl_dataformat(tex_format, &tex->format_flag);
|
||||||
ELEM(data_type, GPU_R16F, GPU_R32F) ||
|
|
||||||
ELEM(data_type, GPU_R8I, GPU_R16I, GPU_R32I) ||
|
if (!(ELEM(tex_format, GPU_R8, GPU_R16) ||
|
||||||
ELEM(data_type, GPU_R8UI, GPU_R16UI, GPU_R32UI) ||
|
ELEM(tex_format, GPU_R16F, GPU_R32F) ||
|
||||||
ELEM(data_type, GPU_RG8, GPU_RG16) ||
|
ELEM(tex_format, GPU_R8I, GPU_R16I, GPU_R32I) ||
|
||||||
ELEM(data_type, GPU_RG16F, GPU_RG32F) ||
|
ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_R32UI) ||
|
||||||
ELEM(data_type, GPU_RG8I, GPU_RG16I, GPU_RG32I) ||
|
ELEM(tex_format, GPU_RG8, GPU_RG16) ||
|
||||||
ELEM(data_type, GPU_RG8UI, GPU_RG16UI, GPU_RG32UI) ||
|
ELEM(tex_format, GPU_RG16F, GPU_RG32F) ||
|
||||||
//ELEM(data_type, GPU_RGB32F, GPU_RGB32I, GPU_RGB32UI) || /* Not available until gl 4.0 */
|
ELEM(tex_format, GPU_RG8I, GPU_RG16I, GPU_RG32I) ||
|
||||||
ELEM(data_type, GPU_RGBA8, GPU_RGBA16) ||
|
ELEM(tex_format, GPU_RG8UI, GPU_RG16UI, GPU_RG32UI) ||
|
||||||
ELEM(data_type, GPU_RGBA16F, GPU_RGBA32F) ||
|
//ELEM(tex_format, GPU_RGB32F, GPU_RGB32I, GPU_RGB32UI) || /* Not available until gl 4.0 */
|
||||||
ELEM(data_type, GPU_RGBA8I, GPU_RGBA16I, GPU_RGBA32I) ||
|
ELEM(tex_format, GPU_RGBA8, GPU_RGBA16) ||
|
||||||
ELEM(data_type, GPU_RGBA8UI, GPU_RGBA16UI, GPU_RGBA32UI)))
|
ELEM(tex_format, GPU_RGBA16F, GPU_RGBA32F) ||
|
||||||
|
ELEM(tex_format, GPU_RGBA8I, GPU_RGBA16I, GPU_RGBA32I) ||
|
||||||
|
ELEM(tex_format, GPU_RGBA8UI, GPU_RGBA16UI, GPU_RGBA32UI)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "GPUTexture: invalid format for texture buffer");
|
fprintf(stderr, "GPUTexture: invalid format for texture buffer\n");
|
||||||
GPU_texture_free(tex);
|
GPU_texture_free(tex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -663,9 +752,9 @@ GPUTexture *GPU_texture_create_buffer(GPUTextureFormat data_type, const GLuint b
|
|||||||
glGenTextures(1, &tex->bindcode);
|
glGenTextures(1, &tex->bindcode);
|
||||||
|
|
||||||
if (!tex->bindcode) {
|
if (!tex->bindcode) {
|
||||||
fprintf(stderr, "GPUTexture: texture create failed");
|
fprintf(stderr, "GPUTexture: texture create failed\n");
|
||||||
GPU_texture_free(tex);
|
GPU_texture_free(tex);
|
||||||
BLI_assert(0 && "glGenTextures failled: Are you sure a valid OGL context is active on this thread?");
|
BLI_assert(0 && "glGenTextures failled: Are you sure a valid OGL context is active on this thread?\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,40 +855,45 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_1D(
|
GPUTexture *GPU_texture_create_1D(
|
||||||
int w, GPUTextureFormat data_type, const float *pixels, char err_out[256])
|
int w, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
|
||||||
{
|
{
|
||||||
return GPU_texture_create_nD(w, 0, 0, 1, pixels, data_type, 0, false, err_out);
|
GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
|
||||||
|
return GPU_texture_create_nD(w, 0, 0, 1, pixels, tex_format, data_format, 0, false, err_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_2D(
|
GPUTexture *GPU_texture_create_2D(
|
||||||
int w, int h, GPUTextureFormat data_type, const float *pixels, char err_out[256])
|
int w, int h, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
|
||||||
{
|
{
|
||||||
return GPU_texture_create_nD(w, h, 0, 2, pixels, data_type, 0, false, err_out);
|
GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
|
||||||
|
return GPU_texture_create_nD(w, h, 0, 2, pixels, tex_format, data_format, 0, false, err_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_2D_multisample(
|
GPUTexture *GPU_texture_create_2D_multisample(
|
||||||
int w, int h, GPUTextureFormat data_type, const float *pixels, int samples, char err_out[256])
|
int w, int h, GPUTextureFormat tex_format, const float *pixels, int samples, char err_out[256])
|
||||||
{
|
{
|
||||||
return GPU_texture_create_nD(w, h, 0, 2, pixels, data_type, samples, false, err_out);
|
GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
|
||||||
|
return GPU_texture_create_nD(w, h, 0, 2, pixels, tex_format, data_format, samples, false, err_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_2D_array(
|
GPUTexture *GPU_texture_create_2D_array(
|
||||||
int w, int h, int d, GPUTextureFormat data_type, const float *pixels, char err_out[256])
|
int w, int h, int d, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
|
||||||
{
|
{
|
||||||
return GPU_texture_create_nD(w, h, d, 2, pixels, data_type, 0, false, err_out);
|
GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
|
||||||
|
return GPU_texture_create_nD(w, h, d, 2, pixels, tex_format, data_format, 0, false, err_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_3D(
|
GPUTexture *GPU_texture_create_3D(
|
||||||
int w, int h, int d, GPUTextureFormat data_type, const float *pixels, char err_out[256])
|
int w, int h, int d, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
|
||||||
{
|
{
|
||||||
return GPU_texture_create_nD(w, h, d, 3, pixels, data_type, 0, true, err_out);
|
GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
|
||||||
|
return GPU_texture_create_nD(w, h, d, 3, pixels, tex_format, data_format, 0, true, err_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_cube(
|
GPUTexture *GPU_texture_create_cube(
|
||||||
int w, GPUTextureFormat data_type, const float *fpixels, char err_out[256])
|
int w, GPUTextureFormat tex_format, const float *fpixels, char err_out[256])
|
||||||
{
|
{
|
||||||
const float *fpixels_px, *fpixels_py, *fpixels_pz, *fpixels_nx, *fpixels_ny, *fpixels_nz;
|
const float *fpixels_px, *fpixels_py, *fpixels_pz, *fpixels_nx, *fpixels_ny, *fpixels_nz;
|
||||||
const int channels = gpu_texture_get_component_count(data_type);
|
const int channels = gpu_get_component_count(tex_format);
|
||||||
|
|
||||||
if (fpixels) {
|
if (fpixels) {
|
||||||
fpixels_px = fpixels + 0 * w * w * channels;
|
fpixels_px = fpixels + 0 * w * w * channels;
|
||||||
@@ -814,7 +908,7 @@ GPUTexture *GPU_texture_create_cube(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return GPU_texture_cube_create(w, 0, fpixels_px, fpixels_py, fpixels_pz, fpixels_nx, fpixels_ny, fpixels_nz,
|
return GPU_texture_cube_create(w, 0, fpixels_px, fpixels_py, fpixels_pz, fpixels_nx, fpixels_ny, fpixels_nz,
|
||||||
data_type, err_out);
|
tex_format, GPU_DATA_FLOAT, err_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert)
|
GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert)
|
||||||
@@ -886,17 +980,56 @@ GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert)
|
|||||||
return GPU_texture_create_buffer(data_type, vert->vbo_id);
|
return GPU_texture_create_buffer(data_type, vert->vbo_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU_texture_add_mipmap(
|
||||||
|
GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl, const void *pixels)
|
||||||
|
{
|
||||||
|
BLI_assert((int)tex->format > -1);
|
||||||
|
BLI_assert(tex->components > -1);
|
||||||
|
|
||||||
|
gpu_validate_data_format(tex->format, gpu_data_format);
|
||||||
|
|
||||||
|
GLenum internalformat = gpu_get_gl_internalformat(tex->format);
|
||||||
|
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
|
||||||
|
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
|
||||||
|
|
||||||
|
glBindTexture(tex->target, tex->bindcode);
|
||||||
|
|
||||||
|
int size[3];
|
||||||
|
GPU_texture_get_mipmap_size(tex, miplvl, size);
|
||||||
|
|
||||||
|
switch (tex->target) {
|
||||||
|
case GL_TEXTURE_1D:
|
||||||
|
glTexImage1D(tex->target, miplvl, internalformat, size[0], 0, data_format, data_type, pixels);
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_2D:
|
||||||
|
case GL_TEXTURE_1D_ARRAY:
|
||||||
|
glTexImage2D(tex->target, miplvl, internalformat, size[0], size[1], 0, data_format, data_type, pixels);
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_3D:
|
||||||
|
case GL_TEXTURE_2D_ARRAY:
|
||||||
|
glTexImage3D(tex->target, miplvl, internalformat, size[0], size[1], size[2], 0, data_format, data_type, pixels);
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||||
|
/* Multisample textures cannot have mipmaps. */
|
||||||
|
default:
|
||||||
|
BLI_assert(!"tex->target mode not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, miplvl);
|
||||||
|
|
||||||
|
glBindTexture(tex->target, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void GPU_texture_update_sub(
|
void GPU_texture_update_sub(
|
||||||
GPUTexture *tex, const void *pixels,
|
GPUTexture *tex, GPUDataFormat gpu_data_format, const void *pixels,
|
||||||
int offset_x, int offset_y, int offset_z, int width, int height, int depth)
|
int offset_x, int offset_y, int offset_z, int width, int height, int depth)
|
||||||
{
|
{
|
||||||
BLI_assert((int)tex->format > -1);
|
BLI_assert((int)tex->format > -1);
|
||||||
BLI_assert(tex->components > -1);
|
BLI_assert(tex->components > -1);
|
||||||
|
|
||||||
GLenum format, data_format;
|
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
|
||||||
|
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
|
||||||
GLint alignment;
|
GLint alignment;
|
||||||
gpu_texture_get_format(tex->components, tex->format, &format, &data_format,
|
|
||||||
&tex->format_flag, &tex->bytesize);
|
|
||||||
|
|
||||||
/* The default pack size for textures is 4, which won't work for byte based textures */
|
/* The default pack size for textures is 4, which won't work for byte based textures */
|
||||||
if (tex->bytesize == 1) {
|
if (tex->bytesize == 1) {
|
||||||
@@ -906,21 +1039,21 @@ void GPU_texture_update_sub(
|
|||||||
|
|
||||||
glBindTexture(tex->target, tex->bindcode);
|
glBindTexture(tex->target, tex->bindcode);
|
||||||
switch (tex->target) {
|
switch (tex->target) {
|
||||||
|
case GL_TEXTURE_1D:
|
||||||
|
glTexSubImage1D(tex->target, 0, offset_x, width, data_format, data_type, pixels);
|
||||||
|
break;
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||||
case GL_TEXTURE_1D_ARRAY:
|
case GL_TEXTURE_1D_ARRAY:
|
||||||
glTexSubImage2D(
|
glTexSubImage2D(
|
||||||
tex->target, 0, offset_x, offset_y,
|
tex->target, 0, offset_x, offset_y,
|
||||||
width, height, format, data_format, pixels);
|
width, height, data_format, data_type, pixels);
|
||||||
break;
|
|
||||||
case GL_TEXTURE_1D:
|
|
||||||
glTexSubImage1D(tex->target, 0, offset_x, width, format, data_format, pixels);
|
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_3D:
|
case GL_TEXTURE_3D:
|
||||||
case GL_TEXTURE_2D_ARRAY:
|
case GL_TEXTURE_2D_ARRAY:
|
||||||
glTexSubImage3D(
|
glTexSubImage3D(
|
||||||
tex->target, 0, offset_x, offset_y, offset_z,
|
tex->target, 0, offset_x, offset_y, offset_z,
|
||||||
width, height, depth, format, data_format, pixels);
|
width, height, depth, data_format, data_type, pixels);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BLI_assert(!"tex->target mode not supported");
|
BLI_assert(!"tex->target mode not supported");
|
||||||
@@ -933,9 +1066,53 @@ void GPU_texture_update_sub(
|
|||||||
glBindTexture(tex->target, 0);
|
glBindTexture(tex->target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_texture_update(GPUTexture *tex, const void *pixels)
|
void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl)
|
||||||
{
|
{
|
||||||
GPU_texture_update_sub(tex, pixels, 0, 0, 0, tex->w, tex->h, tex->d);
|
int size[3] = {0, 0, 0};
|
||||||
|
GPU_texture_get_mipmap_size(tex, miplvl, size);
|
||||||
|
|
||||||
|
gpu_validate_data_format(tex->format, gpu_data_format);
|
||||||
|
|
||||||
|
size_t buf_size = gpu_texture_memory_footprint_compute(tex);
|
||||||
|
size_t samples_count = max_ii(1, tex->samples);
|
||||||
|
|
||||||
|
samples_count *= size[0];
|
||||||
|
samples_count *= max_ii(1, size[1]);
|
||||||
|
samples_count *= max_ii(1, size[2]);
|
||||||
|
|
||||||
|
switch (gpu_data_format) {
|
||||||
|
case GPU_DATA_FLOAT:
|
||||||
|
buf_size = sizeof(float) * samples_count * tex->components;
|
||||||
|
break;
|
||||||
|
case GPU_DATA_INT:
|
||||||
|
case GPU_DATA_UNSIGNED_INT:
|
||||||
|
buf_size = sizeof(int) * samples_count * tex->components;
|
||||||
|
break;
|
||||||
|
case GPU_DATA_UNSIGNED_INT_24_8:
|
||||||
|
case GPU_DATA_10_11_11_REV:
|
||||||
|
buf_size = sizeof(int) * samples_count;
|
||||||
|
break;
|
||||||
|
case GPU_DATA_UNSIGNED_BYTE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *buf = MEM_mallocN(buf_size, "GPU_texture_read");
|
||||||
|
|
||||||
|
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
|
||||||
|
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
|
||||||
|
|
||||||
|
glBindTexture(tex->target, tex->bindcode);
|
||||||
|
|
||||||
|
glGetTexImage(tex->target, miplvl, data_format, data_type, buf);
|
||||||
|
|
||||||
|
glBindTexture(tex->target, 0);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU_texture_update(GPUTexture *tex, GPUDataFormat data_format, const void *pixels)
|
||||||
|
{
|
||||||
|
GPU_texture_update_sub(tex, data_format, pixels, 0, 0, 0, tex->w, tex->h, tex->d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_invalid_tex_init(void)
|
void GPU_invalid_tex_init(void)
|
||||||
@@ -1199,6 +1376,11 @@ int GPU_texture_height(const GPUTexture *tex)
|
|||||||
return tex->h;
|
return tex->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GPU_texture_layers(const GPUTexture *tex)
|
||||||
|
{
|
||||||
|
return tex->d;
|
||||||
|
}
|
||||||
|
|
||||||
GPUTextureFormat GPU_texture_format(const GPUTexture *tex)
|
GPUTextureFormat GPU_texture_format(const GPUTexture *tex)
|
||||||
{
|
{
|
||||||
return tex->format;
|
return tex->format;
|
||||||
@@ -1260,3 +1442,24 @@ int GPU_texture_detach_framebuffer(GPUTexture *tex, GPUFrameBuffer *fb)
|
|||||||
BLI_assert(!"Error: Texture: Framebuffer is not attached");
|
BLI_assert(!"Error: Texture: Framebuffer is not attached");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
|
||||||
|
{
|
||||||
|
/* TODO assert if lvl is bellow the limit of 1px in each dimension. */
|
||||||
|
int div = 1 << lvl;
|
||||||
|
size[0] = max_ii(1, tex->w / div);
|
||||||
|
|
||||||
|
if (tex->target == GL_TEXTURE_1D_ARRAY) {
|
||||||
|
size[1] = tex->h;
|
||||||
|
}
|
||||||
|
else if (tex->h > 0) {
|
||||||
|
size[1] = max_ii(1, tex->h / div);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex->target == GL_TEXTURE_2D_ARRAY) {
|
||||||
|
size[2] = tex->d;
|
||||||
|
}
|
||||||
|
else if (tex->d > 0) {
|
||||||
|
size[2] = max_ii(1, tex->d / div);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -45,6 +45,27 @@ struct ID;
|
|||||||
struct PackedFile;
|
struct PackedFile;
|
||||||
struct GPUTexture;
|
struct GPUTexture;
|
||||||
|
|
||||||
|
/* Runtime display data */
|
||||||
|
struct DrawData;
|
||||||
|
typedef void (*DrawDataInitCb)(struct DrawData *engine_data);
|
||||||
|
typedef void (*DrawDataFreeCb)(struct DrawData *engine_data);
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
typedef struct DrawData {
|
||||||
|
struct DrawData *next, *prev;
|
||||||
|
struct DrawEngineType *engine_type;
|
||||||
|
/* Only nested data, NOT the engine data itself. */
|
||||||
|
DrawDataFreeCb free;
|
||||||
|
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
|
||||||
|
int recalc;
|
||||||
|
} DrawData;
|
||||||
|
|
||||||
|
typedef struct DrawDataList {
|
||||||
|
struct DrawData *first, *last;
|
||||||
|
} DrawDataList;
|
||||||
|
|
||||||
|
|
||||||
typedef struct IDPropertyData {
|
typedef struct IDPropertyData {
|
||||||
void *pointer;
|
void *pointer;
|
||||||
ListBase group;
|
ListBase group;
|
||||||
|
@@ -106,6 +106,78 @@ enum {
|
|||||||
LIGHTPROBE_SHAPE_BOX = 1,
|
LIGHTPROBE_SHAPE_BOX = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ------- Eevee LightProbes ------- */
|
||||||
|
/* Needs to be there because written to file
|
||||||
|
* with the lightcache. */
|
||||||
|
|
||||||
|
typedef struct LightProbeCache {
|
||||||
|
float position[3], parallax_type;
|
||||||
|
float attenuation_fac;
|
||||||
|
float attenuation_type;
|
||||||
|
float pad3[2];
|
||||||
|
float attenuationmat[4][4];
|
||||||
|
float parallaxmat[4][4];
|
||||||
|
} LightProbeCache;
|
||||||
|
|
||||||
|
typedef struct LightGridCache {
|
||||||
|
float mat[4][4];
|
||||||
|
int resolution[3], offset; /* offset to the first irradiance sample in the pool. */
|
||||||
|
float corner[3], attenuation_scale;
|
||||||
|
float increment_x[3], attenuation_bias; /* world space vector between 2 opposite cells */
|
||||||
|
float increment_y[3], level_bias;
|
||||||
|
float increment_z[3], pad4;
|
||||||
|
float visibility_bias, visibility_bleed, visibility_range, pad5;
|
||||||
|
} LightGridCache;
|
||||||
|
|
||||||
|
/* ------ Eevee Lightcache ------- */
|
||||||
|
|
||||||
|
typedef struct LightCacheTexture {
|
||||||
|
struct GPUTexture *tex;
|
||||||
|
/* Copy of GPU datas to create GPUTextures on file read. */
|
||||||
|
char *data;
|
||||||
|
int tex_size[3];
|
||||||
|
char data_type;
|
||||||
|
char components;
|
||||||
|
char pad[2];
|
||||||
|
} LightCacheTexture;
|
||||||
|
|
||||||
|
typedef struct LightCache {
|
||||||
|
int flag;
|
||||||
|
/* only a single cache for now */
|
||||||
|
int cube_len, grid_len; /* Number of probes to use for rendering. */
|
||||||
|
int mips_len; /* Number of mipmap level to use. */
|
||||||
|
int vis_res, ref_res; /* Size of a visibility/reflection sample. */
|
||||||
|
int pad[2];
|
||||||
|
/* In the future, we could create a bigger texture containing
|
||||||
|
* multiple caches (for animation) and interpolate between the
|
||||||
|
* caches overtime to another texture. */
|
||||||
|
LightCacheTexture grid_tx;
|
||||||
|
LightCacheTexture cube_tx; /* Contains data for mipmap level 0. */
|
||||||
|
LightCacheTexture *cube_mips; /* Does not contains valid GPUTexture, only data. */
|
||||||
|
/* All lightprobes data contained in the cache. */
|
||||||
|
LightProbeCache *cube_data;
|
||||||
|
LightGridCache *grid_data;
|
||||||
|
} LightCache;
|
||||||
|
|
||||||
|
/* LightCache->flag */
|
||||||
|
enum {
|
||||||
|
LIGHTCACHE_BAKED = (1 << 0),
|
||||||
|
LIGHTCACHE_BAKING = (1 << 1),
|
||||||
|
LIGHTCACHE_CUBE_READY = (1 << 2),
|
||||||
|
LIGHTCACHE_GRID_READY = (1 << 3),
|
||||||
|
/* Update tagging */
|
||||||
|
LIGHTCACHE_UPDATE_CUBE = (1 << 4),
|
||||||
|
LIGHTCACHE_UPDATE_GRID = (1 << 5),
|
||||||
|
LIGHTCACHE_UPDATE_WORLD = (1 << 6),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EEVEE_LightCacheTexture->data_type */
|
||||||
|
enum {
|
||||||
|
LIGHTCACHETEX_BYTE = (1 << 0),
|
||||||
|
LIGHTCACHETEX_FLOAT = (1 << 1),
|
||||||
|
LIGHTCACHETEX_UINT = (1 << 2),
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -76,22 +76,6 @@ typedef struct bFaceMap {
|
|||||||
char pad[7];
|
char pad[7];
|
||||||
} bFaceMap;
|
} bFaceMap;
|
||||||
|
|
||||||
/* Object Runtime display data */
|
|
||||||
struct ObjectEngineData;
|
|
||||||
typedef void (*ObjectEngineDataInitCb)(struct ObjectEngineData *engine_data);
|
|
||||||
typedef void (*ObjectEngineDataFreeCb)(struct ObjectEngineData *engine_data);
|
|
||||||
|
|
||||||
#
|
|
||||||
#
|
|
||||||
typedef struct ObjectEngineData {
|
|
||||||
struct ObjectEngineData *next, *prev;
|
|
||||||
struct DrawEngineType *engine_type;
|
|
||||||
/* Only nested data, NOT the engine data itself. */
|
|
||||||
ObjectEngineDataFreeCb free;
|
|
||||||
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
|
|
||||||
int recalc;
|
|
||||||
} ObjectEngineData;
|
|
||||||
|
|
||||||
#define MAX_VGROUP_NAME 64
|
#define MAX_VGROUP_NAME 64
|
||||||
|
|
||||||
/* bDeformGroup->flag */
|
/* bDeformGroup->flag */
|
||||||
@@ -163,6 +147,7 @@ typedef struct Object_Runtime {
|
|||||||
typedef struct Object {
|
typedef struct Object {
|
||||||
ID id;
|
ID id;
|
||||||
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
|
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
|
||||||
|
struct DrawDataList drawdata; /* runtime (must be immediately after id for utilities to use it). */
|
||||||
|
|
||||||
struct SculptSession *sculpt;
|
struct SculptSession *sculpt;
|
||||||
|
|
||||||
@@ -312,7 +297,6 @@ typedef struct Object {
|
|||||||
|
|
||||||
struct PreviewImage *preview;
|
struct PreviewImage *preview;
|
||||||
|
|
||||||
ListBase drawdata; /* runtime, ObjectEngineData */
|
|
||||||
int pad6;
|
int pad6;
|
||||||
int select_color;
|
int select_color;
|
||||||
|
|
||||||
|
@@ -1389,6 +1389,9 @@ typedef struct SceneEEVEE {
|
|||||||
int gi_cubemap_resolution;
|
int gi_cubemap_resolution;
|
||||||
int gi_visibility_resolution;
|
int gi_visibility_resolution;
|
||||||
|
|
||||||
|
float gi_cubemap_draw_size;
|
||||||
|
float gi_irradiance_draw_size;
|
||||||
|
|
||||||
int taa_samples;
|
int taa_samples;
|
||||||
int taa_render_samples;
|
int taa_render_samples;
|
||||||
int sss_samples;
|
int sss_samples;
|
||||||
@@ -1428,6 +1431,9 @@ typedef struct SceneEEVEE {
|
|||||||
int shadow_method;
|
int shadow_method;
|
||||||
int shadow_cube_size;
|
int shadow_cube_size;
|
||||||
int shadow_cascade_size;
|
int shadow_cascade_size;
|
||||||
|
|
||||||
|
struct LightCache *light_cache;
|
||||||
|
char light_cache_info[64];
|
||||||
} SceneEEVEE;
|
} SceneEEVEE;
|
||||||
|
|
||||||
/* *************************************************************** */
|
/* *************************************************************** */
|
||||||
@@ -2101,6 +2107,9 @@ enum {
|
|||||||
SCE_EEVEE_SSR_ENABLED = (1 << 14),
|
SCE_EEVEE_SSR_ENABLED = (1 << 14),
|
||||||
SCE_EEVEE_SSR_REFRACTION = (1 << 15),
|
SCE_EEVEE_SSR_REFRACTION = (1 << 15),
|
||||||
SCE_EEVEE_SSR_HALF_RESOLUTION = (1 << 16),
|
SCE_EEVEE_SSR_HALF_RESOLUTION = (1 << 16),
|
||||||
|
SCE_EEVEE_SHOW_IRRADIANCE = (1 << 17),
|
||||||
|
SCE_EEVEE_SHOW_CUBEMAPS = (1 << 18),
|
||||||
|
SCE_EEVEE_GI_AUTOBAKE = (1 << 19),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SceneEEVEE->shadow_method */
|
/* SceneEEVEE->shadow_method */
|
||||||
|
@@ -51,6 +51,7 @@ struct MTex;
|
|||||||
typedef struct World {
|
typedef struct World {
|
||||||
ID id;
|
ID id;
|
||||||
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
|
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
|
||||||
|
DrawDataList drawdata; /* runtime (must be immediately after id for utilities to use it). */
|
||||||
|
|
||||||
char _pad0[4];
|
char _pad0[4];
|
||||||
short texact, mistype;
|
short texact, mistype;
|
||||||
@@ -81,8 +82,7 @@ typedef struct World {
|
|||||||
short flag, pad3[3];
|
short flag, pad3[3];
|
||||||
|
|
||||||
struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */
|
struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */
|
||||||
short pr_texture, use_nodes, pad;
|
short pr_texture, use_nodes, pad[2];
|
||||||
short update_flag; /* XXX temporary flag waiting for depsgraph proper tagging */
|
|
||||||
|
|
||||||
/* previews */
|
/* previews */
|
||||||
struct PreviewImage *preview;
|
struct PreviewImage *preview;
|
||||||
|
@@ -5814,6 +5814,38 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
|
|||||||
"Size of the shadow map applied to each irradiance sample");
|
"Size of the shadow map applied to each irradiance sample");
|
||||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "gi_show_irradiance", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHOW_IRRADIANCE);
|
||||||
|
RNA_def_property_boolean_default(prop, 0);
|
||||||
|
RNA_def_property_ui_text(prop, "Show Irradiance Cache", "Display irradiance samples in the viewport");
|
||||||
|
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "gi_show_cubemaps", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHOW_CUBEMAPS);
|
||||||
|
RNA_def_property_boolean_default(prop, 0);
|
||||||
|
RNA_def_property_ui_text(prop, "Show Cubemap Cache", "Display captured cubemaps in the viewport");
|
||||||
|
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "gi_irradiance_draw_size", PROP_FLOAT, PROP_NONE);
|
||||||
|
RNA_def_property_range(prop, 0.05f, 10.0f);
|
||||||
|
RNA_def_property_float_default(prop, 0.2f);
|
||||||
|
RNA_def_property_ui_text(prop, "Irradiance Draw Size", "Size of the irradiance sample spheres to debug captured light");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "gi_cubemap_draw_size", PROP_FLOAT, PROP_NONE);
|
||||||
|
RNA_def_property_range(prop, 0.05f, 10.0f);
|
||||||
|
RNA_def_property_float_default(prop, 1.0f);
|
||||||
|
RNA_def_property_ui_text(prop, "Cubemap Draw Size", "Size of the cubemap spheres to debug captured light");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "gi_auto_bake", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GI_AUTOBAKE);
|
||||||
|
RNA_def_property_boolean_default(prop, 0);
|
||||||
|
RNA_def_property_ui_text(prop, "Auto Bake", "Auto bake indirect lighting when editing probes");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "gi_cache_info", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "light_cache_info");
|
||||||
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
RNA_def_property_ui_text(prop, "Light Cache Info", "Info on current cache status");
|
||||||
|
|
||||||
/* Temporal Anti-Aliasing (super sampling) */
|
/* Temporal Anti-Aliasing (super sampling) */
|
||||||
prop = RNA_def_property(srna, "taa_samples", PROP_INT, PROP_NONE);
|
prop = RNA_def_property(srna, "taa_samples", PROP_INT, PROP_NONE);
|
||||||
RNA_def_property_int_default(prop, 16);
|
RNA_def_property_int_default(prop, 16);
|
||||||
|
@@ -524,6 +524,7 @@ enum {
|
|||||||
WM_JOB_TYPE_ALEMBIC,
|
WM_JOB_TYPE_ALEMBIC,
|
||||||
WM_JOB_TYPE_SHADER_COMPILATION,
|
WM_JOB_TYPE_SHADER_COMPILATION,
|
||||||
WM_JOB_TYPE_STUDIOLIGHT,
|
WM_JOB_TYPE_STUDIOLIGHT,
|
||||||
|
WM_JOB_TYPE_LIGHT_BAKE,
|
||||||
/* add as needed, screencast, seq proxy build
|
/* add as needed, screencast, seq proxy build
|
||||||
* if having hard coded values is a problem */
|
* if having hard coded values is a problem */
|
||||||
};
|
};
|
||||||
|
@@ -257,6 +257,7 @@ typedef struct wmNotifier {
|
|||||||
#define NC_GPENCIL (22<<24)
|
#define NC_GPENCIL (22<<24)
|
||||||
#define NC_LINESTYLE (23<<24)
|
#define NC_LINESTYLE (23<<24)
|
||||||
#define NC_CAMERA (24<<24)
|
#define NC_CAMERA (24<<24)
|
||||||
|
#define NC_LIGHTPROBE (25<<24)
|
||||||
|
|
||||||
/* data type, 256 entries is enough, it can overlap */
|
/* data type, 256 entries is enough, it can overlap */
|
||||||
#define NOTE_DATA 0x00FF0000
|
#define NOTE_DATA 0x00FF0000
|
||||||
|
Reference in New Issue
Block a user