Changeset View
Changeset View
Standalone View
Standalone View
source/blender/render/intern/source/external_engine.c
| Show First 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | #endif | ||||
| if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) { | if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) { | ||||
| BLI_threaded_malloc_end(); | BLI_threaded_malloc_end(); | ||||
| } | } | ||||
| 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] = -1; | |||||
| primitive[1] = -1; | |||||
| continue; | |||||
| } | |||||
| primitive[0] = *(float*)&bake_pixel->object_id; | |||||
| primitive[1] = *(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) | ||||
| { | { | ||||
| RenderPart *pa; | RenderPart *pa; | ||||
| for (pa = re->parts.first; pa; pa = pa->next) { | for (pa = re->parts.first; pa; pa = pa->next) { | ||||
| if (result->tilerect.xmin == pa->disprect.xmin - re->disprect.xmin && | if (result->tilerect.xmin == pa->disprect.xmin - re->disprect.xmin && | ||||
| result->tilerect.ymin == pa->disprect.ymin - re->disprect.ymin && | result->tilerect.ymin == pa->disprect.ymin - re->disprect.ymin && | ||||
| result->tilerect.xmax == pa->disprect.xmax - re->disprect.xmin && | result->tilerect.xmax == pa->disprect.xmax - re->disprect.xmin && | ||||
| result->tilerect.ymax == pa->disprect.ymax - re->disprect.ymin) | result->tilerect.ymax == pa->disprect.ymax - re->disprect.ymin) | ||||
| { | { | ||||
| return pa; | return pa; | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname) | 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; | 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 All 38 Lines | if (pa) | ||||
| pa->status = PART_STATUS_IN_PROGRESS; | pa->status = PART_STATUS_IN_PROGRESS; | ||||
| } | } | ||||
| 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) { | ||||
| 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 11 Lines | |||||
| void RE_engine_end_result(RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results) | void RE_engine_end_result(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 224 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| RenderEngineType *type = RE_engines_find(re->r.engine); | RenderEngineType *type = RE_engines_find(re->r.engine); | ||||
| return (type->bake != NULL); | return (type->bake != NULL); | ||||
| } | } | ||||
| bool RE_bake_engine( | bool RE_bake_engine( | ||||
| Render *re, Object *object, | Render *re, Object *object, | ||||
| const int object_id, const BakePixel pixel_array[], | const int object_id, const BakePixel pixel_array[], | ||||
| const size_t num_pixels, const int depth, | const BakeImages *bake_images, const int depth, | ||||
| const eScenePassType pass_type, const int pass_filter, | const eScenePassType pass_type, 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; | ||||
| /* set render info */ | /* set render info */ | ||||
| Show All 20 Lines | bool RE_bake_engine( | ||||
| RE_parts_init(re, false); | RE_parts_init(re, false); | ||||
| engine->tile_x = re->r.tilex; | engine->tile_x = re->r.tilex; | ||||
| engine->tile_y = re->r.tiley; | engine->tile_y = re->r.tiley; | ||||
| /* 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, re->scene); | type->update(engine, re->main, re->scene); | ||||
| if (type->bake) | if (type->bake) { | ||||
| type->bake(engine, re->scene, 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, re->scene, object, pass_type, pass_filter, image->width, image->height); | |||||
| memset(&engine->bake, 0, sizeof(engine->bake)); | |||||
| } | |||||
| } | |||||
| 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; | ||||
| BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE); | BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE); | ||||
| /* re->engine becomes zero if user changed active render engine during render */ | /* re->engine becomes zero if user changed active render engine during render */ | ||||
| ▲ Show 20 Lines • Show All 245 Lines • Show Last 20 Lines | |||||