Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2016-10-07 04:45:28 +0300
committerDalai Felinto <dfelinto@gmail.com>2016-10-07 04:47:30 +0300
commit49beb714c540a4ceecf6e818836e3ff4cd5a95eb (patch)
tree9de9a81b9a219bd7a7984c239d316c30f4deebbf /source/blender/editors/space_view3d/view3d_draw.c
parent4539c2b173a942ecb5320eac5e3777cc6d46beae (diff)
Viewport: support for external render engines (e.g., Cycles) with depth
(it is still a rough approach, but you can already see Cycles with Floor (when using board render or full render)
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c200
1 files changed, 189 insertions, 11 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index d249a9e5447..584b6dc7bfe 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -42,6 +42,7 @@
#include "BLI_threads.h"
#include "DNA_camera_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
@@ -52,12 +53,58 @@
#include "UI_resources.h"
+#include "RE_engine.h"
+
#include "WM_api.h"
#include "view3d_intern.h" /* own include */
+/* prototypes */
+static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth);
+
+typedef struct DrawData {
+ rcti border_rect;
+ bool render_border;
+ bool clip_border;
+ bool is_render;
+} DrawData;
+
+static void view3d_draw_data_init(const bContext *C, ARegion *ar, DrawData *draw_data)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ draw_data->is_render = (v3d->drawtype == OB_RENDER);
+
+ draw_data->render_border = ED_view3d_calc_render_border(scene, v3d, ar, &draw_data->border_rect);
+ draw_data->clip_border = (draw_data->render_border && !BLI_rcti_compare(&ar->drawrct, &draw_data->border_rect));
+}
+
/* ******************** general functions ***************** */
+static bool use_depth_doit(Scene *scene, View3D *v3d)
+{
+ if (v3d->drawtype > OB_WIRE)
+ return true;
+
+ /* special case (depth for wire color) */
+ if (v3d->drawtype <= OB_WIRE) {
+ if (scene->obedit && scene->obedit->type == OB_MESH) {
+ Mesh *me = scene->obedit->data;
+ if (me->drawflag & ME_DRAWEIGHT) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+static bool use_depth(const bContext *C)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ return use_depth_doit(scene, v3d);
+}
/**
* \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
@@ -213,6 +260,75 @@ static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
}
}
+/* ******************** offline engine ***************** */
+
+static bool view3d_draw_render_draw(const bContext *C, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ bool clip_border, const rcti *border_rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ RenderEngineType *type;
+ GLint scissor[4];
+
+ /* create render engine */
+ if (!rv3d->render_engine) {
+ RenderEngine *engine;
+
+ type = RE_engines_find(scene->r.engine);
+
+ if (!(type->view_update && type->view_draw))
+ return false;
+
+ engine = RE_engine_create_ex(type, true);
+
+ engine->tile_x = scene->r.tilex;
+ engine->tile_y = scene->r.tiley;
+
+ type->view_update(engine, C);
+
+ rv3d->render_engine = engine;
+ }
+
+ /* background draw */
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ ED_region_pixelspace(ar);
+
+ if (clip_border) {
+ /* for border draw, we only need to clear a subset of the 3d view */
+ if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
+ glScissor(border_rect->xmin, border_rect->ymin,
+ BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
+ }
+ else {
+ return false;
+ }
+ }
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ /* don't change depth buffer */
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* render result draw */
+ type = rv3d->render_engine->type;
+ type->view_draw(rv3d->render_engine, C);
+
+ if (clip_border) {
+ /* restore scissor as it was before */
+ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ return true;
+}
+
/* ******************** solid plates ***************** */
/**
@@ -228,9 +344,10 @@ static void view3d_draw_background(const bContext *C)
/**
*
*/
-static void view3d_draw_render_solid_surfaces(const bContext *C, const bool run_screen_shaders)
+static void view3d_draw_render_solid_surfaces(const bContext *C, ARegion *ar, const bool run_screen_shaders)
{
/* TODO viewport */
+ draw_all_objects(C, ar, false, use_depth(C));
}
/**
@@ -814,24 +931,76 @@ static void view3d_draw_setup_view(const bContext *C, ARegion *ar)
view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
}
+static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ Base *base;
+
+ if (only_depth)
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ if (only_depth || use_depth) {
+ glEnable(GL_DEPTH_TEST);
+ v3d->zbuf = true;
+ }
+
+ for (base = scene->base.first; base; base = base->next) {
+ if (v3d->lay & base->lay) {
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI)
+ draw_dupli_objects(scene, ar, v3d, base);
+
+ draw_object(scene, ar, v3d, base, 0);
+ }
+ }
+
+ if (only_depth)
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ glDisable(GL_DEPTH_TEST);
+}
+
+/**
+ * Draw only the scene depth buffer
+ */
+static void draw_depth_buffer(const bContext *C, ARegion *ar)
+{
+ draw_all_objects(C, ar, true, true);
+}
+
/**
* Required if the shaders need it or external engines
* (e.g., Cycles requires depth buffer handled separately).
*/
-static void view3d_draw_prerender_buffers(const bContext *C)
+static void view3d_draw_prerender_buffers(const bContext *C, ARegion *ar, DrawData *draw_data)
{
/* TODO viewport */
+ if (draw_data->is_render && (!draw_data->clip_border)) {
+ draw_depth_buffer(C, ar);
+ }
}
/**
* Draw all the plates that will fill the RGBD buffer
*/
-static void view3d_draw_solid_plates(const bContext *C)
+static void view3d_draw_solid_plates(const bContext *C, ARegion *ar, DrawData *draw_data)
{
- view3d_draw_background(C);
- view3d_draw_render_solid_surfaces(C, true);
- view3d_draw_render_transparent_surfaces(C);
- view3d_draw_post_draw(C);
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ /* realtime plates */
+ if ((!draw_data->is_render) || draw_data->clip_border) {
+ view3d_draw_background(C);
+ view3d_draw_render_solid_surfaces(C, ar, true);
+ view3d_draw_render_transparent_surfaces(C);
+ view3d_draw_post_draw(C);
+ }
+
+ /* offline plates*/
+ if (draw_data->is_render) {
+ view3d_draw_render_draw(C, scene, ar, v3d, draw_data->clip_border, &draw_data->border_rect);
+ }
}
/**
@@ -883,14 +1052,14 @@ static void view3d_draw_grease_pencil(const bContext *C)
* - left/right stereo
* - panorama / fisheye individual cubemap faces
*/
-static void view3d_draw_view(const bContext *C, ARegion *ar)
+static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data)
{
/* TODO - Technically this should be drawn to a few FBO, so we can handle
* compositing better, but for now this will get the ball rolling (dfelinto) */
view3d_draw_setup_view(C, ar);
- view3d_draw_prerender_buffers(C);
- view3d_draw_solid_plates(C);
+ view3d_draw_prerender_buffers(C, ar, draw_data);
+ view3d_draw_solid_plates(C, ar, draw_data);
view3d_draw_geometry_overlay(C);
view3d_draw_other_elements(C, ar);
view3d_draw_tool_ui(C);
@@ -910,7 +1079,11 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
/* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c
* before we even call the drawing routine, but let's move on for now (dfelinto)
* but this is a provisory way to start seeing things in the viewport */
- view3d_draw_view(C, ar);
+ DrawData draw_data;
+ view3d_draw_data_init(C, ar, &draw_data);
+ view3d_draw_view(C, ar, &draw_data);
+
+ v3d->flag |= V3D_INVALID_BACKBUF;
}
/* ******************** legacy interface ***************** */
@@ -943,3 +1116,8 @@ void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
{
view3d_stereo3d_setup(scene, v3d, ar);
}
+
+bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
+{
+ return use_depth_doit(scene, v3d);
+} \ No newline at end of file