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)
This commit is contained in:
parent
4539c2b173
commit
49beb714c5
|
@ -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);
|
||||
}
|
|
@ -1911,7 +1911,7 @@ static void draw_dupli_objects_color(
|
|||
glDeleteLists(displist, 1);
|
||||
}
|
||||
|
||||
static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base)
|
||||
void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base)
|
||||
{
|
||||
/* define the color here so draw_dupli_objects_color can be called
|
||||
* from the set loop */
|
||||
|
@ -2381,22 +2381,7 @@ static void view3d_draw_objects(
|
|||
view3d_draw_clipping(rv3d);
|
||||
|
||||
/* set zbuffer after we draw clipping region */
|
||||
if (v3d->drawtype > OB_WIRE) {
|
||||
v3d->zbuf = true;
|
||||
}
|
||||
else {
|
||||
v3d->zbuf = false;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
v3d->zbuf = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
v3d->zbuf = VP_legacy_use_depth(scene, v3d);
|
||||
|
||||
if (v3d->zbuf) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -3252,6 +3237,10 @@ bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* IMPORTANT: this is deprecated, any changes made in this function should
|
||||
* be mirrored in view3d_draw_render_draw() in view3d_draw.c
|
||||
*/
|
||||
static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
|
||||
ARegion *ar, View3D *v3d,
|
||||
bool clip_border, const rcti *border_rect)
|
||||
|
|
|
@ -326,5 +326,7 @@ void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool
|
|||
void VP_legacy_view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
|
||||
bool VP_legacy_view3d_stereo3d_active(const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d);
|
||||
void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar);
|
||||
void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base);
|
||||
bool VP_legacy_use_depth(Scene *scene, View3D *v3d);
|
||||
|
||||
#endif /* __VIEW3D_INTERN_H__ */
|
Loading…
Reference in New Issue