OpenGL Render restored.
I tried to make it integrate more with regular render but couldn't do it well, it still needs a 3D view to take the settings from, and can't run in a separate thread due to OpenGL. However, it is now rendering to an offscreen buffer which then gets displayed in the image window. This requires FBO's to be available, so a fallback creating a new window is still needed. Currently available from the Render menu in the top header.
This commit is contained in:
@@ -139,5 +139,9 @@ void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d);
|
||||
|
||||
void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene);
|
||||
|
||||
int ED_view3d_context_activate(struct bContext *C);
|
||||
void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
|
||||
int winx, int winy, float viewmat[][4], float winmat[][4]);
|
||||
|
||||
#endif /* ED_VIEW3D_H */
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Import ('env')
|
||||
sources = env.Glob('*.c')
|
||||
|
||||
incs = '../include ../../blenlib ../../blenkernel ../../blenfont ../../makesdna ../../imbuf'
|
||||
incs += ' ../../blenloader ../../windowmanager ../../python ../../makesrna'
|
||||
incs += ' ../../blenloader ../../windowmanager ../../python ../../makesrna ../../gpu'
|
||||
incs += ' ../../render/extern/include'
|
||||
incs += ' #/intern/guardedalloc #/extern/glew/include'
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -41,6 +44,7 @@
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_meta_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_colortools.h"
|
||||
@@ -58,6 +62,7 @@
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_writeavi.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -68,6 +73,7 @@
|
||||
#include "ED_object.h"
|
||||
#include "ED_screen_types.h"
|
||||
#include "ED_keyframes_draw.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "RE_pipeline.h"
|
||||
#include "IMB_imbuf.h"
|
||||
@@ -79,6 +85,8 @@
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
|
||||
#include "wm_window.h"
|
||||
|
||||
#include "screen_intern.h" /* own module include */
|
||||
@@ -2756,7 +2764,7 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
|
||||
}
|
||||
|
||||
/* called inside thread! */
|
||||
static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, volatile rcti *renrect)
|
||||
static void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volatile rcti *renrect)
|
||||
{
|
||||
float x1, y1, *rectf= NULL;
|
||||
int ymin, ymax, xmin, xmax;
|
||||
@@ -2817,7 +2825,7 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
|
||||
rectc= (char *)(ibuf->rect + ibuf->x*rymin + rxmin);
|
||||
|
||||
/* XXX make nice consistent functions for this */
|
||||
if (rj->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
|
||||
if (scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)) {
|
||||
for(y1= 0; y1<ymax; y1++) {
|
||||
float *rf= rectf;
|
||||
float srgb[3];
|
||||
@@ -2858,8 +2866,6 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
|
||||
}
|
||||
}
|
||||
|
||||
/* make jobs timer to send notifier */
|
||||
*(rj->do_update)= 1;
|
||||
}
|
||||
|
||||
static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect)
|
||||
@@ -2869,8 +2875,12 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
|
||||
void *lock;
|
||||
|
||||
ibuf= BKE_image_acquire_ibuf(rj->image, &rj->iuser, &lock);
|
||||
if(ibuf)
|
||||
image_buffer_rect_update(rj, rr, ibuf, renrect);
|
||||
if(ibuf) {
|
||||
image_buffer_rect_update(rj->scene, rr, ibuf, renrect);
|
||||
|
||||
/* make jobs timer to send notifier */
|
||||
*(rj->do_update)= 1;
|
||||
}
|
||||
BKE_image_release_ibuf(rj->image, lock);
|
||||
}
|
||||
|
||||
@@ -3008,7 +3018,301 @@ static void SCREEN_OT_render(wmOperatorType *ot)
|
||||
|
||||
ot->poll= ED_operator_screenactive;
|
||||
|
||||
RNA_def_int(ot->srna, "layers", 0, 0, INT_MAX, "Layers", "", 0, INT_MAX);
|
||||
RNA_def_boolean(ot->srna, "animation", 0, "Animation", "");
|
||||
}
|
||||
|
||||
/* ****************************** opengl render *************************** */
|
||||
|
||||
typedef struct OGLRender {
|
||||
Render *re;
|
||||
Scene *scene;
|
||||
|
||||
View3D *v3d;
|
||||
RegionView3D *rv3d;
|
||||
ARegion *ar;
|
||||
|
||||
Image *ima;
|
||||
ImageUser iuser;
|
||||
|
||||
GPUOffScreen *ofs;
|
||||
int sizex, sizey;
|
||||
|
||||
bMovieHandle *mh;
|
||||
int cfrao, nfra;
|
||||
|
||||
wmTimer *timer;
|
||||
} OGLRender;
|
||||
|
||||
static void screen_opengl_render_apply(OGLRender *oglrender)
|
||||
{
|
||||
Scene *scene= oglrender->scene;
|
||||
ARegion *ar= oglrender->ar;
|
||||
View3D *v3d= oglrender->v3d;
|
||||
RegionView3D *rv3d= oglrender->rv3d;
|
||||
RenderResult *rr;
|
||||
ImBuf *ibuf;
|
||||
void *lock;
|
||||
float winmat[4][4];
|
||||
int sizex= oglrender->sizex;
|
||||
int sizey= oglrender->sizey;
|
||||
|
||||
/* bind */
|
||||
GPU_offscreen_bind(oglrender->ofs);
|
||||
|
||||
/* render 3d view */
|
||||
if(rv3d->persp==RV3D_CAMOB && v3d->camera) {
|
||||
RE_GetCameraWindow(oglrender->re, v3d->camera, scene->r.cfra, winmat);
|
||||
ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat);
|
||||
}
|
||||
else
|
||||
ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL);
|
||||
|
||||
/* read in pixels & stamp */
|
||||
rr= RE_AcquireResultRead(oglrender->re);
|
||||
glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_FLOAT, rr->rectf);
|
||||
if((scene->r.scemode & R_STAMP_INFO) && (scene->r.stamp & R_STAMP_DRAW))
|
||||
BKE_stamp_buf(scene, (unsigned char *)rr->rect32, rr->rectf, rr->rectx, rr->recty, 3);
|
||||
RE_ReleaseResult(oglrender->re);
|
||||
|
||||
/* update byte from float buffer */
|
||||
ibuf= BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
|
||||
if(ibuf) image_buffer_rect_update(NULL, rr, ibuf, NULL);
|
||||
BKE_image_release_ibuf(oglrender->ima, lock);
|
||||
|
||||
/* unbind */
|
||||
GPU_offscreen_unbind(oglrender->ofs);
|
||||
}
|
||||
|
||||
static int screen_opengl_render_init(bContext *C, wmOperator *op)
|
||||
{
|
||||
/* new render clears all callbacks */
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
RenderResult *rr;
|
||||
GPUOffScreen *ofs;
|
||||
OGLRender *oglrender;
|
||||
int sizex, sizey;
|
||||
|
||||
/* ensure we have a 3d view */
|
||||
if(!ED_view3d_context_activate(C))
|
||||
return 0;
|
||||
|
||||
/* only one render job at a time */
|
||||
if(WM_jobs_test(CTX_wm_manager(C), scene))
|
||||
return 0;
|
||||
|
||||
/* stop all running jobs, currently previews frustrate Render */
|
||||
WM_jobs_stop_all(CTX_wm_manager(C));
|
||||
|
||||
/* handle UI stuff */
|
||||
WM_cursor_wait(1);
|
||||
|
||||
/* create offscreen buffer */
|
||||
sizex= (scene->r.size*scene->r.xsch)/100;
|
||||
sizey= (scene->r.size*scene->r.ysch)/100;
|
||||
|
||||
view3d_operator_needs_opengl(C);
|
||||
ofs= GPU_offscreen_create(sizex, sizey);
|
||||
|
||||
if(!ofs) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate opengl render */
|
||||
oglrender= MEM_callocN(sizeof(OGLRender), "OGLRender");
|
||||
op->customdata= oglrender;
|
||||
|
||||
oglrender->ofs= ofs;
|
||||
oglrender->sizex= sizex;
|
||||
oglrender->sizey= sizey;
|
||||
oglrender->scene= scene;
|
||||
|
||||
oglrender->v3d= CTX_wm_view3d(C);
|
||||
oglrender->ar= CTX_wm_region(C);
|
||||
oglrender->rv3d= CTX_wm_region_view3d(C);
|
||||
|
||||
/* create image and image user */
|
||||
oglrender->ima= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
|
||||
BKE_image_signal(oglrender->ima, NULL, IMA_SIGNAL_FREE);
|
||||
|
||||
oglrender->iuser.scene= scene;
|
||||
oglrender->iuser.ok= 1;
|
||||
|
||||
/* create render and render result */
|
||||
oglrender->re= RE_NewRender(scene->id.name);
|
||||
RE_InitState(oglrender->re, NULL, &scene->r, sizex, sizey, NULL);
|
||||
|
||||
rr= RE_AcquireResultWrite(oglrender->re);
|
||||
if(rr->rectf==NULL)
|
||||
rr->rectf= MEM_mallocN(sizeof(float)*4*sizex*sizex, "32 bits rects");
|
||||
RE_ReleaseResult(oglrender->re);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
|
||||
{
|
||||
Scene *scene= oglrender->scene;
|
||||
|
||||
if(oglrender->mh) {
|
||||
if(BKE_imtype_is_movie(scene->r.imtype))
|
||||
oglrender->mh->end_movie();
|
||||
}
|
||||
|
||||
if(oglrender->timer) {
|
||||
scene->r.cfra= oglrender->cfrao;
|
||||
scene_update_for_newframe(scene, scene->lay);
|
||||
|
||||
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), oglrender->timer);
|
||||
}
|
||||
|
||||
WM_cursor_wait(0);
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, oglrender->scene);
|
||||
|
||||
GPU_offscreen_free(oglrender->ofs);
|
||||
|
||||
MEM_freeN(oglrender);
|
||||
}
|
||||
|
||||
static int screen_opengl_render_cancel(bContext *C, wmOperator *op)
|
||||
{
|
||||
screen_opengl_render_end(C, op->customdata);
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
OGLRender *oglrender= op->customdata;
|
||||
Scene *scene= oglrender->scene;
|
||||
ImBuf *ibuf;
|
||||
void *lock;
|
||||
char name[FILE_MAXDIR+FILE_MAXFILE];
|
||||
unsigned int lay;
|
||||
int ok= 0;
|
||||
|
||||
switch(event->type) {
|
||||
case ESCKEY:
|
||||
/* cancel */
|
||||
screen_opengl_render_end(C, op->customdata);
|
||||
return OPERATOR_FINISHED;
|
||||
case TIMER:
|
||||
/* render frame? */
|
||||
if(oglrender->timer == event->customdata)
|
||||
break;
|
||||
default:
|
||||
/* nothing to do */
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
/* go to next frame */
|
||||
while(CFRA<oglrender->nfra) {
|
||||
if(scene->lay & 0xFF000000)
|
||||
lay= scene->lay & 0xFF000000;
|
||||
else
|
||||
lay= scene->lay;
|
||||
|
||||
scene_update_for_newframe(scene, lay);
|
||||
CFRA++;
|
||||
}
|
||||
|
||||
scene_update_for_newframe(scene, scene->lay);
|
||||
|
||||
/* render into offscreen buffer */
|
||||
screen_opengl_render_apply(oglrender);
|
||||
|
||||
/* save to disk */
|
||||
ibuf= BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
|
||||
|
||||
if(ibuf) {
|
||||
if(BKE_imtype_is_movie(scene->r.imtype)) {
|
||||
oglrender->mh->append_movie(&scene->r, CFRA, (int*)ibuf->rect, oglrender->sizex, oglrender->sizey);
|
||||
printf("Append frame %d", scene->r.cfra);
|
||||
ok= 1;
|
||||
}
|
||||
else {
|
||||
BKE_makepicstring(scene, name, scene->r.pic, scene->r.cfra, scene->r.imtype);
|
||||
ok= BKE_write_ibuf(scene, ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
|
||||
|
||||
if(ok==0) printf("write error: cannot save %s\n", name);
|
||||
else printf("saved: %s", name);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_image_release_ibuf(oglrender->ima, lock);
|
||||
|
||||
/* movie stats prints have no line break */
|
||||
printf("\n");
|
||||
|
||||
/* go to next frame */
|
||||
oglrender->nfra += scene->frame_step;
|
||||
scene->r.cfra++;
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, oglrender->scene);
|
||||
|
||||
/* stop at the end or on error */
|
||||
if(scene->r.cfra > EFRA || !ok) {
|
||||
screen_opengl_render_end(C, op->customdata);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int screen_opengl_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
int anim= RNA_boolean_get(op->ptr, "animation");
|
||||
|
||||
if(!screen_opengl_render_init(C, op))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if(!anim) {
|
||||
/* render image */
|
||||
screen_opengl_render_apply(op->customdata);
|
||||
screen_opengl_render_end(C, op->customdata);
|
||||
screen_set_image_output(C, event->x, event->y);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
/* initialize animation */
|
||||
OGLRender *oglrender;
|
||||
Scene *scene;
|
||||
|
||||
oglrender= op->customdata;
|
||||
scene= oglrender->scene;
|
||||
|
||||
oglrender->mh= BKE_get_movie_handle(scene->r.imtype);
|
||||
if(BKE_imtype_is_movie(scene->r.imtype))
|
||||
oglrender->mh->start_movie(scene, &scene->r, oglrender->sizex, oglrender->sizey);
|
||||
|
||||
oglrender->cfrao= scene->r.cfra;
|
||||
oglrender->nfra= SFRA;
|
||||
scene->r.cfra= SFRA;
|
||||
|
||||
WM_event_add_modal_handler(C, op);
|
||||
oglrender->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
|
||||
|
||||
screen_set_image_output(C, event->x, event->y);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void SCREEN_OT_opengl_render(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "OpenGL Render";
|
||||
ot->description= "OpenGL render active viewport.";
|
||||
ot->idname= "SCREEN_OT_opengl_render";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= screen_opengl_render_invoke;
|
||||
ot->modal= screen_opengl_render_modal;
|
||||
ot->cancel= screen_opengl_render_cancel;
|
||||
|
||||
ot->poll= ED_operator_screenactive;
|
||||
|
||||
RNA_def_boolean(ot->srna, "animation", 0, "Animation", "");
|
||||
}
|
||||
|
||||
@@ -3307,6 +3611,7 @@ void ED_operatortypes_screen(void)
|
||||
WM_operatortype_append(SCREEN_OT_render);
|
||||
WM_operatortype_append(SCREEN_OT_render_view_cancel);
|
||||
WM_operatortype_append(SCREEN_OT_render_view_show);
|
||||
WM_operatortype_append(SCREEN_OT_opengl_render);
|
||||
|
||||
/* new/delete */
|
||||
WM_operatortype_append(SCREEN_OT_new);
|
||||
|
||||
@@ -1897,28 +1897,23 @@ static CustomDataMask get_viewedit_datamask(bScreen *screen, Scene *scene, Objec
|
||||
return mask;
|
||||
}
|
||||
|
||||
void view3d_main_area_draw(const bContext *C, ARegion *ar)
|
||||
static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4])
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
RegionView3D *rv3d= CTX_wm_region_view3d(C);
|
||||
Scene *sce;
|
||||
Base *base;
|
||||
Object *ob;
|
||||
int retopo= 0, sculptparticle= 0;
|
||||
Object *obact = OBACT;
|
||||
char *grid_unit= NULL;
|
||||
RegionView3D *rv3d= ar->regiondata;
|
||||
|
||||
/* setup window matrices */
|
||||
if(winmat)
|
||||
Mat4CpyMat4(rv3d->winmat, winmat);
|
||||
else
|
||||
setwinmatrixview3d(ar, v3d, NULL); /* NULL= no pickrect */
|
||||
|
||||
/* from now on all object derived meshes check this */
|
||||
v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C), scene, obact);
|
||||
|
||||
/* shadow buffers, before we setup matrices */
|
||||
if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
|
||||
gpu_update_lamps_shadows(scene, v3d);
|
||||
|
||||
setwinmatrixview3d(ar, v3d, NULL); /* 0= no pick rect */
|
||||
setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */
|
||||
/* setup view matrix */
|
||||
if(viewmat)
|
||||
Mat4CpyMat4(rv3d->viewmat, viewmat);
|
||||
else
|
||||
setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */
|
||||
|
||||
/* update utilitity matrices */
|
||||
Mat4MulMat4(rv3d->persmat, rv3d->viewmat, rv3d->winmat);
|
||||
Mat4Invert(rv3d->persinv, rv3d->persmat);
|
||||
Mat4Invert(rv3d->viewinv, rv3d->viewmat);
|
||||
@@ -1939,23 +1934,118 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
|
||||
else rv3d->pixsize/= (float)ar->winy;
|
||||
}
|
||||
|
||||
if(v3d->drawtype > OB_WIRE) {
|
||||
float col[3];
|
||||
UI_GetThemeColor3fv(TH_BACK, col);
|
||||
glClearColor(col[0], col[1], col[2], 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glLoadIdentity();
|
||||
}
|
||||
else {
|
||||
float col[3];
|
||||
UI_GetThemeColor3fv(TH_BACK, col);
|
||||
glClearColor(col[0], col[1], col[2], 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
/* set for opengl */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
wmLoadMatrix(rv3d->winmat);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
wmLoadMatrix(rv3d->viewmat);
|
||||
}
|
||||
|
||||
void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[][4], float winmat[][4])
|
||||
{
|
||||
Scene *sce;
|
||||
Base *base;
|
||||
int bwinx, bwiny;
|
||||
|
||||
wmPushMatrix();
|
||||
|
||||
/* set temporary new size */
|
||||
bwinx= ar->winx;
|
||||
bwiny= ar->winy;
|
||||
ar->winx= winx;
|
||||
ar->winy= winy;
|
||||
|
||||
/* set flags */
|
||||
G.f |= G_RENDER_OGL;
|
||||
GPU_free_images();
|
||||
|
||||
/* set background color */
|
||||
glClearColor(scene->world->horr, scene->world->horg, scene->world->horb, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* setup view matrices */
|
||||
view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
|
||||
|
||||
/* set zbuffer */
|
||||
if(v3d->drawtype > OB_WIRE) {
|
||||
v3d->zbuf= TRUE;
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
else
|
||||
v3d->zbuf= FALSE;
|
||||
|
||||
/* draw set first */
|
||||
if(scene->set) {
|
||||
for(SETLOOPER(scene->set, base)) {
|
||||
if(v3d->lay & base->lay) {
|
||||
UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
|
||||
draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR|DRAW_SCENESET);
|
||||
|
||||
if(base->object->transflag & OB_DUPLI)
|
||||
draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* then draw not selected and the duplis, but skip editmode object */
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* transp and X-ray afterdraw stuff */
|
||||
view3d_draw_transp(scene, ar, v3d);
|
||||
view3d_draw_xray(scene, ar, v3d, 1); // clears zbuffer if it is used!
|
||||
|
||||
/* cleanup */
|
||||
if(v3d->zbuf) {
|
||||
v3d->zbuf= FALSE;
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
GPU_free_images();
|
||||
|
||||
/* restore size */
|
||||
ar->winx= bwinx;
|
||||
ar->winy= bwiny;
|
||||
|
||||
wmPopMatrix();
|
||||
}
|
||||
|
||||
void view3d_main_area_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
RegionView3D *rv3d= CTX_wm_region_view3d(C);
|
||||
Scene *sce;
|
||||
Base *base;
|
||||
Object *ob;
|
||||
float col[3];
|
||||
int retopo= 0, sculptparticle= 0;
|
||||
Object *obact = OBACT;
|
||||
char *grid_unit= NULL;
|
||||
|
||||
/* from now on all object derived meshes check this */
|
||||
v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C), scene, obact);
|
||||
|
||||
/* shadow buffers, before we setup matrices */
|
||||
if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
|
||||
gpu_update_lamps_shadows(scene, v3d);
|
||||
|
||||
/* clear background */
|
||||
UI_GetThemeColor3fv(TH_BACK, col);
|
||||
glClearColor(col[0], col[1], col[2], 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* setup view matrices */
|
||||
view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
|
||||
|
||||
if(rv3d->rflag & RV3D_CLIPPING)
|
||||
view3d_draw_clipping(rv3d);
|
||||
|
||||
|
||||
@@ -1559,39 +1559,53 @@ int game_engine_poll(bContext *C)
|
||||
return CTX_data_mode_enum(C)==CTX_MODE_OBJECT ? 1:0;
|
||||
}
|
||||
|
||||
static int game_engine_exec(bContext *C, wmOperator *unused)
|
||||
int ED_view3d_context_activate(bContext *C)
|
||||
{
|
||||
#if GAMEBLENDER == 1
|
||||
Scene *startscene = CTX_data_scene(C);
|
||||
bScreen *sc= CTX_wm_screen(C);
|
||||
ScrArea *sa, *prevsa= CTX_wm_area(C);
|
||||
ARegion *ar, *prevar= CTX_wm_region(C);
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
ARegion *ar;
|
||||
RegionView3D *rv3d;
|
||||
rcti cam_frame;
|
||||
|
||||
|
||||
sa= prevsa;
|
||||
if(sa->spacetype != SPACE_VIEW3D) {
|
||||
if(sa->spacetype != SPACE_VIEW3D)
|
||||
for(sa=sc->areabase.first; sa; sa= sa->next)
|
||||
if(sa->spacetype==SPACE_VIEW3D)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!sa)
|
||||
return OPERATOR_CANCELLED;
|
||||
return 0;
|
||||
|
||||
for(ar=sa->regionbase.first; ar; ar=ar->next)
|
||||
if(ar->regiontype == RGN_TYPE_WINDOW)
|
||||
break;
|
||||
|
||||
if(!ar)
|
||||
return OPERATOR_CANCELLED;
|
||||
return 0;
|
||||
|
||||
// bad context switch ..
|
||||
CTX_wm_area_set(C, sa);
|
||||
CTX_wm_region_set(C, ar);
|
||||
rv3d= ar->regiondata;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int game_engine_exec(bContext *C, wmOperator *unused)
|
||||
{
|
||||
#if GAMEBLENDER == 1
|
||||
Scene *startscene = CTX_data_scene(C);
|
||||
ScrArea *sa, *prevsa= CTX_wm_area(C);
|
||||
ARegion *ar, *prevar= CTX_wm_region(C);
|
||||
RegionView3D *rv3d;
|
||||
rcti cam_frame;
|
||||
|
||||
// bad context switch ..
|
||||
if(!ED_view3d_context_activate(C))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
rv3d= CTX_wm_region_view3d(C);
|
||||
sa= CTX_wm_area(C);
|
||||
ar= CTX_wm_region(C);
|
||||
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
game_set_commmandline_options(&startscene->gm);
|
||||
|
||||
@@ -48,6 +48,9 @@ typedef struct GPUTexture GPUTexture;
|
||||
struct GPUFrameBuffer;
|
||||
typedef struct GPUFrameBuffer GPUFrameBuffer;
|
||||
|
||||
struct GPUOffScreen;
|
||||
typedef struct GPUOffScreen GPUOffScreen;
|
||||
|
||||
struct GPUShader;
|
||||
typedef struct GPUShader GPUShader;
|
||||
|
||||
@@ -107,6 +110,14 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb);
|
||||
|
||||
void GPU_framebuffer_restore();
|
||||
|
||||
/* GPU OffScreen
|
||||
- wrapper around framebuffer and texture for simple offscreen drawing */
|
||||
|
||||
GPUOffScreen *GPU_offscreen_create(int width, int height);
|
||||
void GPU_offscreen_free(GPUOffScreen *ofs);
|
||||
void GPU_offscreen_bind(GPUOffScreen *ofs);
|
||||
void GPU_offscreen_unbind(GPUOffScreen *ofs);
|
||||
|
||||
/* GPU Shader
|
||||
- only for fragment shaders now
|
||||
- must call texture bind before setting a texture as uniform! */
|
||||
|
||||
@@ -616,7 +616,7 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex)
|
||||
}
|
||||
else {
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glReadBuffer(GL_NONE);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
}
|
||||
|
||||
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
@@ -727,6 +727,78 @@ void GPU_framebuffer_restore()
|
||||
}
|
||||
}
|
||||
|
||||
/* GPUOffScreen */
|
||||
|
||||
struct GPUOffScreen {
|
||||
GPUFrameBuffer *fb;
|
||||
GPUTexture *color;
|
||||
GPUTexture *depth;
|
||||
};
|
||||
|
||||
GPUOffScreen *GPU_offscreen_create(int width, int height)
|
||||
{
|
||||
GPUOffScreen *ofs;
|
||||
|
||||
ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
|
||||
|
||||
ofs->fb = GPU_framebuffer_create();
|
||||
if(!ofs->fb) {
|
||||
GPU_offscreen_free(ofs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ofs->depth = GPU_texture_create_depth(width, height);
|
||||
if(!ofs->depth) {
|
||||
GPU_offscreen_free(ofs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth)) {
|
||||
GPU_offscreen_free(ofs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ofs->color = GPU_texture_create_2D(width, height, NULL);
|
||||
if(!ofs->color) {
|
||||
GPU_offscreen_free(ofs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->color)) {
|
||||
GPU_offscreen_free(ofs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GPU_framebuffer_restore();
|
||||
|
||||
return ofs;
|
||||
}
|
||||
|
||||
void GPU_offscreen_free(GPUOffScreen *ofs)
|
||||
{
|
||||
if(ofs->fb)
|
||||
GPU_framebuffer_free(ofs->fb);
|
||||
if(ofs->color)
|
||||
GPU_texture_free(ofs->color);
|
||||
if(ofs->depth)
|
||||
GPU_texture_free(ofs->depth);
|
||||
|
||||
MEM_freeN(ofs);
|
||||
}
|
||||
|
||||
void GPU_offscreen_bind(GPUOffScreen *ofs)
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
GPU_framebuffer_texture_bind(ofs->fb, ofs->color);
|
||||
}
|
||||
|
||||
void GPU_offscreen_unbind(GPUOffScreen *ofs)
|
||||
{
|
||||
GPU_framebuffer_texture_unbind(ofs->fb, ofs->color);
|
||||
GPU_framebuffer_restore();
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
/* GPUShader */
|
||||
|
||||
struct GPUShader {
|
||||
|
||||
@@ -1509,6 +1509,7 @@ void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize
|
||||
Mat4MulMat4(lamp->persmat, persmat, rangemat);
|
||||
|
||||
/* opengl */
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
GPU_framebuffer_texture_bind(lamp->fb, lamp->tex);
|
||||
|
||||
/* set matrices */
|
||||
@@ -1521,6 +1522,7 @@ void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
|
||||
{
|
||||
GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
|
||||
GPU_framebuffer_restore();
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_layer(GPULamp *lamp)
|
||||
|
||||
@@ -535,7 +535,7 @@ static void rna_def_edit_bone(BlenderRNA *brna)
|
||||
|
||||
srna= RNA_def_struct(brna, "EditBone", NULL);
|
||||
RNA_def_struct_sdna(srna, "EditBone");
|
||||
RNA_def_struct_idproperties_func(srna, "rna_Bone_idproperties");
|
||||
RNA_def_struct_idproperties_func(srna, "rna_EditBone_idproperties");
|
||||
RNA_def_struct_ui_text(srna, "Edit Bone", "Editmode bone in an Armature datablock.");
|
||||
RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user