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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-28 21:03:04 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-28 21:03:04 +0300
commitb6459105b47526cd33851d4e00740fbd9d050ea4 (patch)
treededbd4c93fdb22f040f6740f2d13dc6dc4ce19ed
parent044f7c5f331209d6f274a7d73a411fbe15746ea3 (diff)
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.
-rw-r--r--release/scripts/ui/space_info.py5
-rw-r--r--source/blender/editors/include/ED_view3d.h4
-rw-r--r--source/blender/editors/screen/SConscript2
-rw-r--r--source/blender/editors/screen/screen_ops.c319
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c152
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c38
-rw-r--r--source/blender/gpu/GPU_extensions.h11
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c74
-rw-r--r--source/blender/gpu/intern/gpu_material.c2
-rw-r--r--source/blender/makesrna/intern/rna_armature.c2
10 files changed, 556 insertions, 53 deletions
diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py
index 52d5876a46b..d62ab5b759d 100644
--- a/release/scripts/ui/space_info.py
+++ b/release/scripts/ui/space_info.py
@@ -206,6 +206,11 @@ class INFO_MT_render(bpy.types.Menu):
layout.itemS()
+ layout.itemO("screen.opengl_render", text="OpenGL Render Image")
+ layout.item_booleanO("screen.opengl_render", "animation", True, text="OpenGL Render Animation")
+
+ layout.itemS()
+
layout.itemO("screen.render_view_show")
class INFO_MT_help(bpy.types.Menu):
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index be2822d8c49..2ec9ddf6c52 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -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 */
diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript
index 847a1cddfb4..afd6ce68b68 100644
--- a/source/blender/editors/screen/SConscript
+++ b/source/blender/editors/screen/SConscript
@@ -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'
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index e65ad221501..a1537b2ddf5 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -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);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 487c55bec9b..64ea574b011 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -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;
-
- /* 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);
+ RegionView3D *rv3d= ar->regiondata;
+
+ /* setup window matrices */
+ if(winmat)
+ Mat4CpyMat4(rv3d->winmat, winmat);
+ else
+ setwinmatrixview3d(ar, v3d, NULL); /* NULL= no pickrect */
- 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;
}
+ /* 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) {
- 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();
+ v3d->zbuf= TRUE;
+ glEnable(GL_DEPTH_TEST);
}
- 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);
+ 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);
+ }
+ }
}
- wmLoadMatrix(rv3d->viewmat);
+ /* 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);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 300825bfe7d..e2b22afae62 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -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);
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index a910ff9c3e7..c2af4e8fcb1 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -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! */
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 5c8157be789..5deef4a5200 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -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 {
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 0dc17da93a1..0650a0bfa19 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -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)
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 889f23e0d39..96dde186260 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -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);