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. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to