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:
Brecht Van Lommel
2009-10-28 18:03:04 +00:00
parent 044f7c5f33
commit b6459105b4
10 changed files with 559 additions and 56 deletions

View File

@@ -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 */

View File

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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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! */

View File

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

View File

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

View File

@@ -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);