diff options
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_bake.h | 3 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_engine.h | 18 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 13 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_render_ext.h | 22 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_shader_ext.h | 8 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_result.h | 11 | ||||
-rw-r--r-- | source/blender/render/intern/source/bake_api.c | 13 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 154 | ||||
-rw-r--r-- | source/blender/render/intern/source/initrender.c | 5 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 109 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 36 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_texture.c | 78 |
13 files changed, 280 insertions, 192 deletions
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index a1dd9b3d5b0..f49c68a258d 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -108,4 +108,6 @@ if(APPLE) endif() endif() +add_definitions(${GL_DEFINITIONS}) + blender_add_lib_nolist(bf_render "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h index 372defbe8db..3bab9179f84 100644 --- a/source/blender/render/extern/include/RE_bake.h +++ b/source/blender/render/extern/include/RE_bake.h @@ -67,7 +67,7 @@ bool RE_bake_engine(struct Render *re, struct Object *object, const int object_id, const BakePixel pixel_array[], - const size_t num_pixels, + const BakeImages *bake_images, const int depth, const eScenePassType pass_type, const int pass_filter, @@ -84,6 +84,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, const size_t num_pixels, const bool is_custom_cage, const float cage_extrusion, + const float max_ray_distance, float mat_low[4][4], float mat_cage[4][4], struct Mesh *me_cage); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 0b5b62e2f08..77a60854616 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -68,7 +68,6 @@ struct bNodeTree; #define RE_ENGINE_DO_UPDATE 8 #define RE_ENGINE_RENDERING 16 #define RE_ENGINE_HIGHLIGHT_TILES 32 -#define RE_ENGINE_USED_FOR_VIEWPORT 64 extern ListBase R_engines; @@ -87,11 +86,8 @@ typedef struct RenderEngineType { struct Object *object, const int pass_type, const int pass_filter, - const int object_id, - const struct BakePixel *pixel_array, - const int num_pixels, - const int depth, - void *result); + const int width, + const int height); void (*view_update)(struct RenderEngine *engine, const struct bContext *context, @@ -110,7 +106,7 @@ typedef struct RenderEngineType { struct DrawEngineType *draw_engine; /* RNA integration */ - ExtensionRNA ext; + ExtensionRNA rna_ext; } RenderEngineType; typedef void (*update_render_passes_cb_t)(void *userdata, @@ -140,6 +136,13 @@ typedef struct RenderEngine { struct ReportList *reports; + struct { + const struct BakePixel *pixels; + float *result; + int width, height, depth; + int object_id; + } bake; + /* Depsgraph */ struct Depsgraph *depsgraph; @@ -155,7 +158,6 @@ typedef struct RenderEngine { } RenderEngine; RenderEngine *RE_engine_create(RenderEngineType *type); -RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport); void RE_engine_free(RenderEngine *engine); void RE_layer_load_from_file( diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 319d8b1c2ed..f9d2e915fad 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -40,6 +40,10 @@ struct StampData; struct ViewLayer; struct bMovieHandle; +#ifdef __cplusplus +extern "C" { +#endif + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* this include is what is exposed of render to outside world */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -156,8 +160,7 @@ typedef struct RenderResult { typedef struct RenderStats { int cfra; - int totface, totvert, totstrand, tothalo, totlamp, totpart; - short curfield, curblur, curpart, partsdone, convertdone, curfsa; + int totface, totvert, totlamp, totpart; bool localview; double starttime, lastframetime; const char *infostr, *statstr; @@ -363,7 +366,7 @@ struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, #define RE_BAKE_DISPLACEMENT 1 #define RE_BAKE_AO 2 -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]); +void RE_GetCameraWindow(struct Render *re, struct Object *camera, float mat[4][4]); void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float overscan); void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_mat[4][4]); struct Scene *RE_GetScene(struct Render *re); @@ -386,4 +389,8 @@ struct RenderView *RE_RenderViewGetByName(struct RenderResult *res, const char * RenderResult *RE_DuplicateRenderResult(RenderResult *rr); +#ifdef __cplusplus +} +#endif + #endif /* __RE_PIPELINE_H__ */ diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index bca3b749192..bdf81354b8d 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -33,18 +33,16 @@ struct ImagePool; struct MTex; /* render_texture.c */ -/* used by particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */ -int externtex(const struct MTex *mtex, - const float vec[3], - float *tin, - float *tr, - float *tg, - float *tb, - float *ta, - const int thread, - struct ImagePool *pool, - const bool skip_load_image, - const bool texnode_preview); +bool RE_texture_evaluate(const struct MTex *mtex, + const float vec[3], + const int thread, + struct ImagePool *pool, + const bool skip_load_image, + const bool texnode_preview, + /* Return arguments. */ + float *r_intensity, + float r_rgba[4]) ATTR_NONNULL(1, 2, 7, 8); + void texture_rgb_blend( float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype); float texture_value_blend(float tex, float out, float fact, float facg, int blendtype); diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 792b2b7e071..f69ae4dfd5c 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -23,6 +23,10 @@ #ifndef __RE_SHADER_EXT_H__ #define __RE_SHADER_EXT_H__ +#ifdef __cplusplus +extern "C" { +#endif + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* this include is for texture exports */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -75,4 +79,8 @@ int multitex_nodes(struct Tex *tex, struct MTex *mtex, struct ImagePool *pool); +#ifdef __cplusplus +} +#endif + #endif /* __RE_SHADER_EXT_H__ */ diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index fabbd5fb096..0ed8871b224 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -84,11 +84,12 @@ void render_result_exr_file_begin(struct Render *re, struct RenderEngine *engine void render_result_exr_file_end(struct Render *re, struct RenderEngine *engine); /* render pass wrapper for gpencil */ -struct RenderPass *gp_add_pass(struct RenderResult *rr, - struct RenderLayer *rl, - int channels, - const char *name, - const char *viewname); +struct RenderPass *render_layer_add_pass(struct RenderResult *rr, + struct RenderLayer *rl, + int channels, + const char *name, + const char *viewname, + const char *chanid); void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart, diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index e823a481d59..06f77854595 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -321,11 +321,16 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, const float co[3], const float dir[3], const int pixel_id, - const int tot_highpoly) + const int tot_highpoly, + const float max_ray_distance) { int i; int hit_mesh = -1; - float hit_distance = FLT_MAX; + float hit_distance = max_ray_distance; + if (hit_distance == 0.0f) { + /* No ray distance set, use maximum. */ + hit_distance = FLT_MAX; + } BVHTreeRayHit *hits; hits = MEM_mallocN(sizeof(BVHTreeRayHit) * tot_highpoly, "Bake Highpoly to Lowpoly: BVH Rays"); @@ -520,6 +525,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, const size_t num_pixels, const bool is_custom_cage, const float cage_extrusion, + const float max_ray_distance, float mat_low[4][4], float mat_cage[4][4], struct Mesh *me_cage) @@ -623,7 +629,8 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, co, dir, i, - tot_highpoly)) { + tot_highpoly, + max_ray_distance)) { /* if it fails mask out the original pixel array */ pixel_array_from[i].primitive_id = -1; } diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 7c071bb6b04..af3a6fdd384 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -31,6 +31,7 @@ #include "BLI_ghash.h" #include "BLI_listbase.h" +#include "BLI_math_bits.h" #include "BLI_rect.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -87,8 +88,8 @@ void RE_engines_exit(void) BLI_remlink(&R_engines, type); if (!(type->flag & RE_INTERNAL)) { - if (type->ext.free) { - type->ext.free(type->ext.data); + if (type->rna_ext.free) { + type->rna_ext.free(type->rna_ext.data); } MEM_freeN(type); @@ -131,20 +132,9 @@ bool RE_engine_is_opengl(RenderEngineType *render_type) RenderEngine *RE_engine_create(RenderEngineType *type) { - return RE_engine_create_ex(type, false); -} - -RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport) -{ RenderEngine *engine = MEM_callocN(sizeof(RenderEngine), "RenderEngine"); engine->type = type; - if (use_for_viewport) { - engine->flag |= RE_ENGINE_USED_FOR_VIEWPORT; - - BLI_threaded_malloc_begin(); - } - BLI_mutex_init(&engine->update_render_passes_mutex); return engine; @@ -158,15 +148,94 @@ void RE_engine_free(RenderEngine *engine) } #endif - if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) { - BLI_threaded_malloc_end(); - } - BLI_mutex_end(&engine->update_render_passes_mutex); MEM_freeN(engine); } +/* Bake Render Results */ + +static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, int w, int h) +{ + /* Create render result with specified size. */ + RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__); + + rr->rectx = w; + rr->recty = h; + rr->tilerect.xmin = x; + rr->tilerect.ymin = y; + rr->tilerect.xmax = x + w; + rr->tilerect.ymax = y + h; + + /* Add single baking render layer. */ + RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer"); + rl->rectx = w; + rl->recty = h; + BLI_addtail(&rr->layers, rl); + + /* Add render passes. */ + render_layer_add_pass(rr, rl, engine->bake.depth, RE_PASSNAME_COMBINED, "", "RGBA"); + RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA"); + RenderPass *differential_pass = render_layer_add_pass(rr, rl, 4, "BakeDifferential", "", "RGBA"); + + /* Fill render passes from bake pixel array, to be read by the render engine. */ + for (int ty = 0; ty < h; ty++) { + size_t offset = ty * w * 4; + float *primitive = primitive_pass->rect + offset; + float *differential = differential_pass->rect + offset; + + size_t bake_offset = (y + ty) * engine->bake.width + x; + const BakePixel *bake_pixel = engine->bake.pixels + bake_offset; + + for (int tx = 0; tx < w; tx++) { + if (bake_pixel->object_id != engine->bake.object_id) { + primitive[0] = int_as_float(-1); + primitive[1] = int_as_float(-1); + } + else { + primitive[0] = int_as_float(bake_pixel->object_id); + primitive[1] = int_as_float(bake_pixel->primitive_id); + primitive[2] = bake_pixel->uv[0]; + primitive[3] = bake_pixel->uv[1]; + + differential[0] = bake_pixel->du_dx; + differential[1] = bake_pixel->du_dy; + differential[2] = bake_pixel->dv_dx; + differential[3] = bake_pixel->dv_dy; + } + + primitive += 4; + differential += 4; + bake_pixel++; + } + } + + return rr; +} + +static void render_result_to_bake(RenderEngine *engine, RenderResult *rr) +{ + RenderPass *rpass = RE_pass_find_by_name(rr->layers.first, RE_PASSNAME_COMBINED, ""); + + if (!rpass) { + return; + } + + /* Copy from tile render result to full image bake result. */ + int x = rr->tilerect.xmin; + int y = rr->tilerect.ymin; + int w = rr->tilerect.xmax - rr->tilerect.xmin; + int h = rr->tilerect.ymax - rr->tilerect.ymin; + + for (int ty = 0; ty < h; ty++) { + size_t offset = ty * w * engine->bake.depth; + size_t bake_offset = ((y + ty) * engine->bake.width + x) * engine->bake.depth; + size_t size = w * engine->bake.depth * sizeof(float); + + memcpy(engine->bake.result + bake_offset, rpass->rect + offset, size); + } +} + /* Render Results */ static RenderPart *get_part_from_result(Render *re, RenderResult *result) @@ -180,6 +249,12 @@ static RenderPart *get_part_from_result(Render *re, RenderResult *result) RenderResult *RE_engine_begin_result( RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname) { + if (engine->bake.pixels) { + RenderResult *result = render_result_from_bake(engine, x, y, w, h); + BLI_addtail(&engine->fullresult, result); + return result; + } + Render *re = engine->re; RenderResult *result; rcti disprect; @@ -237,6 +312,11 @@ RenderResult *RE_engine_begin_result( void RE_engine_update_result(RenderEngine *engine, RenderResult *result) { + if (engine->bake.pixels) { + /* No interactive baking updates for now. */ + return; + } + Render *re = engine->re; if (result) { @@ -270,6 +350,13 @@ void RE_engine_end_result( return; } + if (engine->bake.pixels) { + render_result_to_bake(engine, result); + BLI_remlink(&engine->fullresult, result); + render_result_free(result); + return; + } + /* merge. on break, don't merge in result for preview renders, looks nicer */ if (!highlight) { /* for exr tile render, detect tiles that are done */ @@ -574,7 +661,7 @@ bool RE_bake_engine(Render *re, Object *object, const int object_id, const BakePixel pixel_array[], - const size_t num_pixels, + const BakeImages *bake_images, const int depth, const eScenePassType pass_type, const int pass_filter, @@ -587,7 +674,7 @@ bool RE_bake_engine(Render *re, /* set render info */ re->i.cfra = re->scene->r.cfra; BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name) - 2); - re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0; + re->i.totface = re->i.totvert = re->i.totlamp = 0; /* render */ engine = re->engine; @@ -605,9 +692,11 @@ bool RE_bake_engine(Render *re, engine->resolution_x = re->winx; engine->resolution_y = re->winy; + BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE); RE_parts_init(re); engine->tile_x = re->r.tilex; engine->tile_y = re->r.tiley; + BLI_rw_mutex_unlock(&re->partsmutex); if (type->bake) { engine->depsgraph = depsgraph; @@ -617,16 +706,21 @@ bool RE_bake_engine(Render *re, type->update(engine, re->main, engine->depsgraph); } - type->bake(engine, - engine->depsgraph, - object, - pass_type, - pass_filter, - object_id, - pixel_array, - num_pixels, - depth, - result); + for (int i = 0; i < bake_images->size; i++) { + const BakeImage *image = bake_images->data + i; + + engine->bake.pixels = pixel_array + image->offset; + engine->bake.result = result + image->offset * depth; + engine->bake.width = image->width; + engine->bake.height = image->height; + engine->bake.depth = depth; + engine->bake.object_id = object_id; + + type->bake( + engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height); + + memset(&engine->bake, 0, sizeof(engine->bake)); + } engine->depsgraph = NULL; } @@ -718,7 +812,7 @@ int RE_engine_render(Render *re, int do_all) /* set render info */ re->i.cfra = re->scene->r.cfra; BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name)); - re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0; + re->i.totface = re->i.totvert = re->i.totlamp = 0; /* render */ engine = re->engine; diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 5a6ecfc3e20..2e9f30397db 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -211,9 +211,8 @@ void RE_SetCamera(Render *re, Object *cam_ob) re_camera_params_get(re, ¶ms); } -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]) +void RE_GetCameraWindow(struct Render *re, struct Object *camera, float mat[4][4]) { - re->r.cfra = frame; RE_SetCamera(re, camera); copy_m4_m4(mat, re->winmat); } @@ -271,8 +270,6 @@ void RE_parts_init(Render *re) /* this is render info for caller, is not reset when parts are freed! */ re->i.totpart = 0; - re->i.curpart = 0; - re->i.partsdone = 0; /* just for readable code.. */ xminb = re->disprect.xmin; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 87568402df3..c66c43ec467 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -51,6 +51,7 @@ #include "BLT_translation.h" +#include "BKE_anim_data.h" #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ #include "BKE_callbacks.h" #include "BKE_camera.h" @@ -186,32 +187,22 @@ static int default_break(void *UNUSED(arg)) static void stats_background(void *UNUSED(arg), RenderStats *rs) { - uintptr_t mem_in_use, mmap_in_use, peak_memory; - float megs_used_memory, mmap_used_memory, megs_peak_memory; + uintptr_t mem_in_use, peak_memory; + float megs_used_memory, megs_peak_memory; char info_time_str[32]; mem_in_use = MEM_get_memory_in_use(); - mmap_in_use = MEM_get_mapped_memory_in_use(); peak_memory = MEM_get_peak_memory(); - megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0); - mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0); + megs_used_memory = (mem_in_use) / (1024.0 * 1024.0); megs_peak_memory = (peak_memory) / (1024.0 * 1024.0); fprintf(stdout, - TIP_("Fra:%d Mem:%.2fM (%.2fM, Peak %.2fM) "), + TIP_("Fra:%d Mem:%.2fM (Peak %.2fM) "), rs->cfra, megs_used_memory, - mmap_used_memory, megs_peak_memory); - if (rs->curfield) { - fprintf(stdout, TIP_("Field %d "), rs->curfield); - } - if (rs->curblur) { - fprintf(stdout, TIP_("Blur %d "), rs->curblur); - } - BLI_timecode_string_from_time_simple( info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime); fprintf(stdout, TIP_("| Time:%s | "), info_time_str); @@ -220,23 +211,12 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs) fprintf(stdout, "%s", rs->infostr); } else { - if (rs->tothalo) { - fprintf(stdout, - TIP_("Sce: %s Ve:%d Fa:%d Ha:%d La:%d"), - rs->scene_name, - rs->totvert, - rs->totface, - rs->tothalo, - rs->totlamp); - } - else { - fprintf(stdout, - TIP_("Sce: %s Ve:%d Fa:%d La:%d"), - rs->scene_name, - rs->totvert, - rs->totface, - rs->totlamp); - } + fprintf(stdout, + TIP_("Sce: %s Ve:%d Fa:%d La:%d"), + rs->scene_name, + rs->totvert, + rs->totface, + rs->totlamp); } /* Flush stdout to be sure python callbacks are printing stuff after blender. */ @@ -1818,42 +1798,42 @@ bool RE_is_rendering_allowed(Scene *scene, } } - if (scemode & R_DOCOMP) { - if (scene->use_nodes) { - if (!scene->nodetree) { - BKE_report(reports, RPT_ERROR, "No node tree in scene"); - return 0; - } + if (RE_seq_render_active(scene, &scene->r)) { + /* Sequencer */ + if (scene->r.mode & R_BORDER) { + BKE_report(reports, RPT_ERROR, "Border rendering is not supported by sequencer"); + return false; + } + } + else if ((scemode & R_DOCOMP) && scene->use_nodes) { + /* Compositor */ + if (!scene->nodetree) { + BKE_report(reports, RPT_ERROR, "No node tree in scene"); + return 0; + } - if (!check_composite_output(scene)) { - BKE_report(reports, RPT_ERROR, "No render output node in scene"); - return 0; - } + if (!check_composite_output(scene)) { + BKE_report(reports, RPT_ERROR, "No render output node in scene"); + return 0; + } - if (scemode & R_FULL_SAMPLE) { - if (composite_needs_render(scene, 0) == 0) { - BKE_report(reports, RPT_ERROR, "Full sample AA not supported without 3D rendering"); - return 0; - } + if (scemode & R_FULL_SAMPLE) { + if (composite_needs_render(scene, 0) == 0) { + BKE_report(reports, RPT_ERROR, "Full sample AA not supported without 3D rendering"); + return 0; } } } - - /* check valid camera, without camera render is OK (compo, seq) */ - if (!check_valid_camera(scene, camera_override, reports)) { - return 0; - } - - if (RE_seq_render_active(scene, &scene->r)) { - if (scene->r.mode & R_BORDER) { - BKE_report(reports, RPT_ERROR, "Border rendering is not supported by sequencer"); - return false; + else { + /* Regular Render */ + if (!render_scene_has_layers_to_render(scene, single_layer)) { + BKE_report(reports, RPT_ERROR, "All render layers are disabled"); + return 0; } } - /* layer flag tests */ - if (!render_scene_has_layers_to_render(scene, single_layer)) { - BKE_report(reports, RPT_ERROR, "All render layers are disabled"); + /* check valid camera, without camera render is OK (compo, seq) */ + if (!check_valid_camera(scene, camera_override, reports)) { return 0; } @@ -2094,14 +2074,13 @@ void RE_RenderFreestyleExternal(Render *re) FRS_init_stroke_renderer(re); - for (RenderView *rv = re->result->views.first; rv; rv = rv->next) { + LISTBASE_FOREACH (RenderView *, rv, &re->result->views) { RE_SetActiveRenderView(re, rv->name); ViewLayer *active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer); FRS_begin_stroke_rendering(re); - for (ViewLayer *view_layer = (ViewLayer *)re->view_layers.first; view_layer; - view_layer = view_layer->next) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &re->view_layers) { if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) { continue; } @@ -2514,7 +2493,7 @@ void RE_RenderAnim(Render *re, { float ctime = BKE_scene_frame_get(scene); AnimData *adt = BKE_animdata_from_id(&scene->id); - BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, ADT_RECALC_ALL, false); + BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, ADT_RECALC_ALL, false); } render_update_depsgraph(re); @@ -2865,7 +2844,7 @@ bool RE_layers_have_name(struct RenderResult *rr) bool RE_passes_have_name(struct RenderLayer *rl) { - for (RenderPass *rp = rl->passes.first; rp; rp = rp->next) { + LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) { if (!STREQ(rp->name, "Combined")) { return true; } @@ -2955,5 +2934,5 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha BLI_freelinkN(&rl->passes, rp); } /* create a totally new pass */ - return gp_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname); + return render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname, "RGBA"); } diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 814e9b1c79e..4b74bfb3e5c 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -213,12 +213,12 @@ static void set_pass_full_name( /********************************** New **************************************/ -static RenderPass *render_layer_add_pass(RenderResult *rr, - RenderLayer *rl, - int channels, - const char *name, - const char *viewname, - const char *chan_id) +RenderPass *render_layer_add_pass(RenderResult *rr, + RenderLayer *rl, + int channels, + const char *name, + const char *viewname, + const char *chan_id) { const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name)); RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name); @@ -255,7 +255,7 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, float *rect; int x; - rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, name); + rpass->rect = MEM_callocN(sizeof(float) * rectsize, name); if (rpass->rect == NULL) { MEM_freeN(rpass); return NULL; @@ -280,12 +280,6 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, return rpass; } -/* wrapper called from render_opengl */ -RenderPass *gp_add_pass( - RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname) -{ - return render_layer_add_pass(rr, rl, channels, name, viewname, "RGBA"); -} /* called by main render as well for parts */ /* will read info from Render *re to define layers */ @@ -917,7 +911,7 @@ bool RE_WriteRenderResult(ReportList *reports, /* First add views since IMB_exr_add_channel checks number of views. */ if (render_result_has_views(rr)) { - for (RenderView *rview = rr->views.first; rview; rview = rview->next) { + LISTBASE_FOREACH (RenderView *, rview, &rr->views) { if (!view || STREQ(view, rview->name)) { IMB_exr_add_view(exrhandle, rview->name); } @@ -926,7 +920,7 @@ bool RE_WriteRenderResult(ReportList *reports, /* Compositing result. */ if (rr->have_combined) { - for (RenderView *rview = rr->views.first; rview; rview = rview->next) { + LISTBASE_FOREACH (RenderView *, rview, &rr->views) { if (!rview->rectf) { continue; } @@ -986,7 +980,7 @@ bool RE_WriteRenderResult(ReportList *reports, continue; } - for (RenderPass *rp = rl->passes.first; rp; rp = rp->next) { + LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) { /* Skip non-RGBA and Z passes if not using multi layer. */ if (!multi_layer && !(STREQ(rp->name, RE_PASSNAME_COMBINED) || STREQ(rp->name, "") || (STREQ(rp->name, RE_PASSNAME_Z) && write_z))) { @@ -1240,7 +1234,7 @@ void render_result_exr_file_begin(Render *re, RenderEngine *engine) char str[FILE_MAX]; for (RenderResult *rr = re->result; rr; rr = rr->next) { - for (RenderLayer *rl = rr->layers.first; rl; rl = rl->next) { + LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) { /* Get passes needed by engine. Normally we would wait for the * engine to create them, but for EXR file we need to know in * advance. */ @@ -1250,7 +1244,7 @@ void render_result_exr_file_begin(Render *re, RenderEngine *engine) /* Create render passes requested by engine. Only this part is * mutex locked to avoid deadlock with Python GIL. */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - for (RenderPass *pass = templates.first; pass; pass = pass->next) { + LISTBASE_FOREACH (RenderPass *, pass, &templates) { RE_create_render_pass( re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL); } @@ -1271,7 +1265,7 @@ void render_result_exr_file_end(Render *re, RenderEngine *engine) { /* Close EXR files. */ for (RenderResult *rr = re->result; rr; rr = rr->next) { - for (RenderLayer *rl = rr->layers.first; rl; rl = rl->next) { + LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) { IMB_exr_close(rl->exrhandle); rl->exrhandle = NULL; } @@ -1285,7 +1279,7 @@ void render_result_exr_file_end(Render *re, RenderEngine *engine) re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); BLI_rw_mutex_unlock(&re->resultmutex); - for (RenderLayer *rl = re->result->layers.first; rl; rl = rl->next) { + LISTBASE_FOREACH (RenderLayer *, rl, &re->result->layers) { /* Get passes needed by engine. */ ListBase templates; render_result_get_pass_templates(engine, re, rl, &templates); @@ -1293,7 +1287,7 @@ void render_result_exr_file_end(Render *re, RenderEngine *engine) /* Create render passes requested by engine. Only this part is * mutex locked to avoid deadlock with Python GIL. */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - for (RenderPass *pass = templates.first; pass; pass = pass->next) { + LISTBASE_FOREACH (RenderPass *, pass, &templates) { RE_create_render_pass(re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL); } diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 22cc1f0eddf..ee484924bf9 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -46,7 +46,6 @@ #include "BKE_image.h" #include "BKE_node.h" -#include "BKE_animsys.h" #include "BKE_colorband.h" #include "BKE_material.h" #include "BKE_scene.h" @@ -80,7 +79,7 @@ void RE_texture_rng_exit(void) /* ------------------------------------------------------------------------- */ /* this allows colorbanded textures to control normals as well */ -static void tex_normal_derivate(Tex *tex, TexResult *texres) +static void tex_normal_derivate(const Tex *tex, TexResult *texres) { if (tex->flag & TEX_COLORBAND) { float col[4]; @@ -107,7 +106,7 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres) texres->nor[2] = texres->tin - texres->nor[2]; } -static int blend(Tex *tex, const float texvec[3], TexResult *texres) +static int blend(const Tex *tex, const float texvec[3], TexResult *texres) { float x, y, t; @@ -171,7 +170,7 @@ static int blend(Tex *tex, const float texvec[3], TexResult *texres) /* newnoise: all noisebased types now have different noisebases to choose from */ -static int clouds(Tex *tex, const float texvec[3], TexResult *texres) +static int clouds(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -272,7 +271,7 @@ static float tex_tri(float a) } /* computes basic wood intensity value at x,y,z */ -static float wood_int(Tex *tex, float x, float y, float z) +static float wood_int(const Tex *tex, float x, float y, float z) { float wi = 0; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */ @@ -309,7 +308,7 @@ static float wood_int(Tex *tex, float x, float y, float z) return wi; } -static int wood(Tex *tex, const float texvec[3], TexResult *texres) +static int wood(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -330,7 +329,7 @@ static int wood(Tex *tex, const float texvec[3], TexResult *texres) } /* computes basic marble intensity at x,y,z */ -static float marble_int(Tex *tex, float x, float y, float z) +static float marble_int(const Tex *tex, float x, float y, float z) { float n, mi; short wf = tex->noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */ @@ -368,7 +367,7 @@ static float marble_int(Tex *tex, float x, float y, float z) return mi; } -static int marble(Tex *tex, const float texvec[3], TexResult *texres) +static int marble(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -392,7 +391,7 @@ static int marble(Tex *tex, const float texvec[3], TexResult *texres) /* ------------------------------------------------------------------------- */ -static int magic(Tex *tex, const float texvec[3], TexResult *texres) +static int magic(const Tex *tex, const float texvec[3], TexResult *texres) { float x, y, z, turb; int n; @@ -468,7 +467,7 @@ static int magic(Tex *tex, const float texvec[3], TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: stucci also modified to use different noisebasis */ -static int stucci(Tex *tex, const float texvec[3], TexResult *texres) +static int stucci(const Tex *tex, const float texvec[3], TexResult *texres) { float nor[3], b2, ofs; int retval = TEX_INT; @@ -534,7 +533,7 @@ static int stucci(Tex *tex, const float texvec[3], TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: musgrave terrain noise types */ -static float mg_mFractalOrfBmTex(Tex *tex, const float texvec[3], TexResult *texres) +static int mg_mFractalOrfBmTex(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, int); @@ -589,7 +588,7 @@ static float mg_mFractalOrfBmTex(Tex *tex, const float texvec[3], TexResult *tex return rv; } -static float mg_ridgedOrHybridMFTex(Tex *tex, const float texvec[3], TexResult *texres) +static int mg_ridgedOrHybridMFTex(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, float, float, int); @@ -652,7 +651,7 @@ static float mg_ridgedOrHybridMFTex(Tex *tex, const float texvec[3], TexResult * return rv; } -static float mg_HTerrainTex(Tex *tex, const float texvec[3], TexResult *texres) +static int mg_HTerrainTex(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -703,7 +702,7 @@ static float mg_HTerrainTex(Tex *tex, const float texvec[3], TexResult *texres) return rv; } -static float mg_distNoiseTex(Tex *tex, const float texvec[3], TexResult *texres) +static int mg_distNoiseTex(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -748,7 +747,7 @@ static float mg_distNoiseTex(Tex *tex, const float texvec[3], TexResult *texres) * probably the slowest, especially with minkovsky, bumpmapping, could be done another way. */ -static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) +static int voronoiTex(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbors */ @@ -762,8 +761,7 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) } voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); - texres->tin = sc * fabsf(tex->vn_w1 * da[0] + tex->vn_w2 * da[1] + tex->vn_w3 * da[2] + - tex->vn_w4 * da[3]); + texres->tin = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); if (tex->vn_coltype) { float ca[3]; /* cell color */ @@ -810,14 +808,11 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) /* calculate bumpnormal */ voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); - texres->nor[0] = sc * fabsf(tex->vn_w1 * da[0] + tex->vn_w2 * da[1] + tex->vn_w3 * da[2] + - tex->vn_w4 * da[3]); + texres->nor[0] = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); - texres->nor[1] = sc * fabsf(tex->vn_w1 * da[0] + tex->vn_w2 * da[1] + tex->vn_w3 * da[2] + - tex->vn_w4 * da[3]); + texres->nor[1] = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp, tex->vn_distm); - texres->nor[2] = sc * fabsf(tex->vn_w1 * da[0] + tex->vn_w2 * da[1] + tex->vn_w3 * da[2] + - tex->vn_w4 * da[3]); + texres->nor[2] = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); tex_normal_derivate(tex, texres); rv |= TEX_NOR; @@ -836,7 +831,7 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) /* ------------------------------------------------------------------------- */ -static int texnoise(Tex *tex, TexResult *texres, int thread) +static int texnoise(const Tex *tex, TexResult *texres, int thread) { float div = 3.0; int val, ran, loop, shift = 29; @@ -1725,17 +1720,20 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen /* ------------------------------------------------------------------------- */ -int externtex(const MTex *mtex, - const float vec[3], - float *tin, - float *tr, - float *tg, - float *tb, - float *ta, - const int thread, - struct ImagePool *pool, - const bool skip_load_image, - const bool texnode_preview) +/** + * \param pool: Thread pool, may be NULL. + * + * \return True if the texture has color, otherwise false. + */ +bool RE_texture_evaluate(const MTex *mtex, + const float vec[3], + const int thread, + struct ImagePool *pool, + const bool skip_load_image, + const bool texnode_preview, + /* Return arguments. */ + float *r_intensity, + float r_rgba[4]) { Tex *tex; TexResult texr; @@ -1797,11 +1795,11 @@ int externtex(const MTex *mtex, texr.tb = mtex->b; } - *tin = texr.tin; - *tr = texr.tr; - *tg = texr.tg; - *tb = texr.tb; - *ta = texr.ta; + *r_intensity = texr.tin; + r_rgba[0] = texr.tr; + r_rgba[1] = texr.tg; + r_rgba[2] = texr.tb; + r_rgba[3] = texr.ta; return (rgb != 0); } |