Changeset View
Changeset View
Standalone View
Standalone View
source/blender/render/intern/source/external_engine.c
| Show All 27 Lines | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_ghash.h" | #include "BLI_ghash.h" | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_rect.h" | #include "BLI_rect.h" | ||||
| #include "BLI_math_bits.h" | |||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "BKE_camera.h" | #include "BKE_camera.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_colortools.h" | #include "BKE_colortools.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| ▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) { | ||||
| BLI_threaded_malloc_end(); | BLI_threaded_malloc_end(); | ||||
| } | } | ||||
| BLI_mutex_end(&engine->update_render_passes_mutex); | BLI_mutex_end(&engine->update_render_passes_mutex); | ||||
| MEM_freeN(engine); | 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 */ | /* Render Results */ | ||||
| static RenderPart *get_part_from_result(Render *re, RenderResult *result) | static RenderPart *get_part_from_result(Render *re, RenderResult *result) | ||||
| { | { | ||||
| rcti key = result->tilerect; | rcti key = result->tilerect; | ||||
| BLI_rcti_translate(&key, re->disprect.xmin, re->disprect.ymin); | BLI_rcti_translate(&key, re->disprect.xmin, re->disprect.ymin); | ||||
| return BLI_ghash_lookup(re->parts, &key); | return BLI_ghash_lookup(re->parts, &key); | ||||
| } | } | ||||
| RenderResult *RE_engine_begin_result( | RenderResult *RE_engine_begin_result( | ||||
| RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname) | 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; | Render *re = engine->re; | ||||
| RenderResult *result; | RenderResult *result; | ||||
| rcti disprect; | rcti disprect; | ||||
| /* ensure the coordinates are within the right limits */ | /* ensure the coordinates are within the right limits */ | ||||
| CLAMP(x, 0, re->result->rectx); | CLAMP(x, 0, re->result->rectx); | ||||
| CLAMP(y, 0, re->result->recty); | CLAMP(y, 0, re->result->recty); | ||||
| CLAMP(w, 0, re->result->rectx); | CLAMP(w, 0, re->result->rectx); | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | if (result) { | ||||
| } | } | ||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| void RE_engine_update_result(RenderEngine *engine, RenderResult *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; | Render *re = engine->re; | ||||
| if (result) { | if (result) { | ||||
| render_result_merge(re->result, result); | render_result_merge(re->result, result); | ||||
| result->renlay = result->layers.first; /* weak, draws first layer always */ | result->renlay = result->layers.first; /* weak, draws first layer always */ | ||||
| re->display_update(re->duh, result, NULL); | re->display_update(re->duh, result, NULL); | ||||
| } | } | ||||
| } | } | ||||
| Show All 17 Lines | void RE_engine_end_result( | ||||
| RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results) | RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results) | ||||
| { | { | ||||
| Render *re = engine->re; | Render *re = engine->re; | ||||
| if (!result) { | if (!result) { | ||||
| return; | 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 */ | /* merge. on break, don't merge in result for preview renders, looks nicer */ | ||||
| if (!highlight) { | if (!highlight) { | ||||
| /* for exr tile render, detect tiles that are done */ | /* for exr tile render, detect tiles that are done */ | ||||
| RenderPart *pa = get_part_from_result(re, result); | RenderPart *pa = get_part_from_result(re, result); | ||||
| if (pa) { | if (pa) { | ||||
| pa->status = (!cancel && merge_results) ? PART_STATUS_MERGED : PART_STATUS_RENDERED; | pa->status = (!cancel && merge_results) ? PART_STATUS_MERGED : PART_STATUS_RENDERED; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 288 Lines • ▼ Show 20 Lines | bool RE_bake_has_engine(Render *re) | ||||
| return (type->bake != NULL); | return (type->bake != NULL); | ||||
| } | } | ||||
| bool RE_bake_engine(Render *re, | bool RE_bake_engine(Render *re, | ||||
| Depsgraph *depsgraph, | Depsgraph *depsgraph, | ||||
| Object *object, | Object *object, | ||||
| const int object_id, | const int object_id, | ||||
| const BakePixel pixel_array[], | const BakePixel pixel_array[], | ||||
| const size_t num_pixels, | const BakeImages *bake_images, | ||||
| const int depth, | const int depth, | ||||
| const eScenePassType pass_type, | const eScenePassType pass_type, | ||||
| const int pass_filter, | const int pass_filter, | ||||
| float result[]) | float result[]) | ||||
| { | { | ||||
| RenderEngineType *type = RE_engines_find(re->r.engine); | RenderEngineType *type = RE_engines_find(re->r.engine); | ||||
| RenderEngine *engine; | RenderEngine *engine; | ||||
| bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0; | bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0; | ||||
| Show All 26 Lines | bool RE_bake_engine(Render *re, | ||||
| if (type->bake) { | if (type->bake) { | ||||
| engine->depsgraph = depsgraph; | engine->depsgraph = depsgraph; | ||||
| /* update is only called so we create the engine.session */ | /* update is only called so we create the engine.session */ | ||||
| if (type->update) { | if (type->update) { | ||||
| type->update(engine, re->main, engine->depsgraph); | type->update(engine, re->main, engine->depsgraph); | ||||
| } | } | ||||
| type->bake(engine, | for (int i = 0; i < bake_images->size; i++) { | ||||
| engine->depsgraph, | const BakeImage *image = bake_images->data + i; | ||||
| object, | |||||
| pass_type, | engine->bake.pixels = pixel_array + image->offset; | ||||
| pass_filter, | engine->bake.result = result + image->offset * depth; | ||||
| object_id, | engine->bake.width = image->width; | ||||
| pixel_array, | engine->bake.height = image->height; | ||||
| num_pixels, | engine->bake.depth = depth; | ||||
| depth, | engine->bake.object_id = object_id; | ||||
| result); | |||||
| type->bake( | |||||
| engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height); | |||||
| memset(&engine->bake, 0, sizeof(engine->bake)); | |||||
| } | |||||
| engine->depsgraph = NULL; | engine->depsgraph = NULL; | ||||
| } | } | ||||
| engine->tile_x = 0; | engine->tile_x = 0; | ||||
| engine->tile_y = 0; | engine->tile_y = 0; | ||||
| engine->flag &= ~RE_ENGINE_RENDERING; | engine->flag &= ~RE_ENGINE_RENDERING; | ||||
| ▲ Show 20 Lines • Show All 250 Lines • Show Last 20 Lines | |||||