[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24142] trunk/blender: OpenGL Render restored.

Brecht Van Lommel brecht at blender.org
Wed Oct 28 19:03:04 CET 2009


Revision: 24142
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24142
Author:   blendix
Date:     2009-10-28 19:03:04 +0100 (Wed, 28 Oct 2009)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/space_info.py
    trunk/blender/source/blender/editors/include/ED_view3d.h
    trunk/blender/source/blender/editors/screen/screen_ops.c
    trunk/blender/source/blender/editors/space_view3d/view3d_draw.c
    trunk/blender/source/blender/editors/space_view3d/view3d_view.c
    trunk/blender/source/blender/gpu/GPU_extensions.h
    trunk/blender/source/blender/gpu/intern/gpu_extensions.c
    trunk/blender/source/blender/gpu/intern/gpu_material.c
    trunk/blender/source/blender/makesrna/intern/rna_armature.c

Modified: trunk/blender/release/scripts/ui/space_info.py
===================================================================
--- trunk/blender/release/scripts/ui/space_info.py	2009-10-28 17:05:11 UTC (rev 24141)
+++ trunk/blender/release/scripts/ui/space_info.py	2009-10-28 18:03:04 UTC (rev 24142)
@@ -206,6 +206,11 @@
 
 		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):

Modified: trunk/blender/source/blender/editors/include/ED_view3d.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_view3d.h	2009-10-28 17:05:11 UTC (rev 24141)
+++ trunk/blender/source/blender/editors/include/ED_view3d.h	2009-10-28 18:03:04 UTC (rev 24142)
@@ -139,5 +139,9 @@
 
 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 */
 

Modified: trunk/blender/source/blender/editors/screen/screen_ops.c
===================================================================
--- trunk/blender/source/blender/editors/screen/screen_ops.c	2009-10-28 17:05:11 UTC (rev 24141)
+++ trunk/blender/source/blender/editors/screen/screen_ops.c	2009-10-28 18:03:04 UTC (rev 24142)
@@ -25,7 +25,10 @@
  */
 
 #include <math.h>
+#include <string.h>
 
+#include <GL/glew.h>
+
 #include "MEM_guardedalloc.h"
 
 #include "BLI_arithb.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 @@
 }
 
 /* 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 @@
 	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 @@
 		}
 	}
 	
-	/* 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 @@
 	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,10 +3018,304 @@
 	
 	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 */

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list