Large change to the way sculptmode drawing works. The default is now to draw

using the standard drawing functions. Enabling the "Partial Redraw" item in the
sculpt menu will turn on the optimizations which stores unmodified parts of the
color buffer and only redraws the polygons that are within the modified area(s).

The Partial Redraw option uses the accumulation buffer to store the copy, and
unfortunately this is not accelerated on older cards. There are alternatives,
e.g. drawing to an auxiliary buffer or downloading the data from the graphics
card with glReadPixels, but there's no guarantee that these will run at an
acceptable speed on older graphics cards either. For the cards that do
accelerate the accumulation buffer (for nvidia cards, I would assume that is at
least FX5200 and up, and maybe earlier) it provides a very significant speedup.
This commit is contained in:
Nicholas Bishop
2006-12-04 05:36:50 +00:00
parent c520a2a6b2
commit 0cc76d831c
5 changed files with 25 additions and 20 deletions

View File

@@ -419,11 +419,12 @@ typedef struct SculptData
short texscale;
short texact, texnr;
short spacing;
char pad;
char texrept;
char texfade;
char averaging;
char draw_mode;
} SculptData;
#define SCULPTREPT_DRAG 1

View File

@@ -4032,13 +4032,9 @@ static void editing_panel_links(Object *ob)
uiDefBut(block, BUT,B_MATASS, "Assign", 292,47,162,26, 0, 0, 0, 0, 0, "In EditMode, assigns the active index to selected faces");
uiBlockBeginAlign(block);
if(!(G.f & G_SCULPTMODE) || ((G.f & G_SCULPTMODE) && G.obedit))
{
uiDefBut(block, BUT,B_SETSMOOTH,"Set Smooth", 291,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'smooth' rendering of selected faces");
uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 373,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'solid' rendering of selected faces");
}
uiDefBut(block, BUT,B_SETSMOOTH,"Set Smooth", 291,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'smooth' rendering of selected faces");
uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 373,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'solid' rendering of selected faces");
uiBlockEndAlign(block);

View File

@@ -2159,7 +2159,8 @@ static int draw_mesh_object(Base *base, int dt, int flag)
cageDM->release(cageDM);
finalDM->release(finalDM);
}
else if(!G.obedit && G.scene->sculptdata.active_ob == ob && !modifiers_getVirtualModifierList(ob)) {
else if(!G.obedit && G.scene->sculptdata.draw_mode &&
G.scene->sculptdata.active_ob == ob && !modifiers_getVirtualModifierList(ob)) {
sculptmode_draw_mesh(0);
}
else {

View File

@@ -4035,6 +4035,9 @@ void do_view3d_sculptmenu(void *arg, int event)
if(G.vd)
G.vd->pivot_last= !G.vd->pivot_last;
break;
case 14:
sd->draw_mode= !sd->draw_mode;
break;
}
allqueue(REDRAWBUTSEDIT, 0);
@@ -4051,6 +4054,7 @@ uiBlock *view3d_sculptmenu(void *arg_unused_so_why_have_it/*?*/)
block= uiNewBlock(&curarea->uiblocks, "view3d_sculptmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_view3d_sculptmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, (sd->draw_mode ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Partial Redraw", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
if(G.vd)
uiDefIconTextBut(block, BUTM, 1, (G.vd->pivot_last ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Pivot last", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mouse averaging", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");

View File

@@ -175,6 +175,7 @@ void sculptmode_init(Scene *sce)
sd->averaging= 1;
sd->texscale= 100;
sd->texrept= SCULPTREPT_DRAG;
sd->draw_mode= 0;
}
/* Free G.sculptdata->vertexusers */
@@ -428,7 +429,7 @@ void sculptmode_undo_update(SculptUndoStep *newcur)
set_sculpt_object(ob);
if(modifiers_getVirtualModifierList(ob))
if(!sd->draw_mode || modifiers_getVirtualModifierList(ob))
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
if(G.vd->depths) G.vd->depths->damaged= 1;
@@ -1558,7 +1559,8 @@ void sculpt()
e.layer_store= NULL;
/* Capture original copy */
glAccum(GL_LOAD, 1);
if(sd->draw_mode)
glAccum(GL_LOAD, 1);
while (get_mbut() & mousebut) {
getmouseco_areawin(mouse);
@@ -1604,14 +1606,17 @@ void sculpt()
if(modifier_calculations)
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
if(modifier_calculations || sd->brush_type == GRAB_BRUSH) {
if(modifier_calculations || sd->brush_type == GRAB_BRUSH || !sd->draw_mode) {
calc_damaged_verts(&damaged_verts,e.grabdata);
scrarea_do_windraw(curarea);
screen_swapbuffers();
} else {
} else { /* Optimized drawing */
calc_damaged_verts(&damaged_verts,e.grabdata);
/* Draw the stored image to the screen */
glAccum(GL_RETURN, 1);
/* Clear each of the area(s) modified by the brush */
for(rn=damaged_rects.first; rn; rn= rn->next) {
float col[3];
rcti clp= rn->r;
@@ -1636,21 +1641,19 @@ void sculpt()
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
}
glDisable(GL_SCISSOR_TEST);
/* Draw all the polygons that are inside the modified area(s) */
glDisable(GL_SCISSOR_TEST);
sculptmode_draw_mesh(1);
glAccum(GL_LOAD, 1);
glEnable(GL_SCISSOR_TEST);
/* Draw cursor */
persp(PERSP_WIN);
glDisable(GL_DEPTH_TEST);
fdrawXORcirc((float)mouse[0],(float)mouse[1],sculptmode_brush()->size);
glRasterPos2i(0, 0);
myswapbuffers();
glAccum(GL_RETURN, 1);
glEnable(GL_SCISSOR_TEST);
myswapbuffers();
}
BLI_freelistN(&damaged_rects);