[Bf-committers] Preview Render Patch

Matthew H. Plough mplough at Princeton.EDU
Thu May 26 09:31:12 CEST 2005


I don't like replying to my own mails, but there were a couple of issues 
with the last patch (no stupid bugs, though):
1) A spurious fprintf.
2) It was made from the wrong place.

Thus, I have attached the correct patch, created with cvs diff -u.

Since I'm replying to my own mail anyway, I'd like to elaborate on the 
texture-based method of drawing previews.
1) When the preview is partially occluded or partially off screen, it 
draws correctly on all sane graphics cards.
2) There are no more horizontal lines where nothing is drawn.
3) The OpenGL subsystem takes care of resizing using bilinear 
interpolation, so the image looks nice.

If the preview is rendered too slowly, PR_RECTX and PR_RECTY can be 
changed to a smaller power of 2, preferably 128. 

Patching may be accomplished by downloading the patch to the blender/ 
directory, switching to the blender/ directory, and doing:

$ patch -po <preview_patch

I tested this just to make sure.

Matt
-------------- next part --------------
Index: source/blender/src/previewrender.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/previewrender.c,v
retrieving revision 1.58
diff -u -p -r1.58 previewrender.c
--- source/blender/src/previewrender.c	17 Apr 2005 17:43:07 -0000	1.58
+++ source/blender/src/previewrender.c	26 May 2005 07:01:50 -0000
@@ -94,8 +94,9 @@
 #include "blendef.h"	/* CLAMP */
 #include "interface.h"	/* ui_graphics_to_window() SOLVE! (ton) */
 
-#define PR_RECTX	141
-#define PR_RECTY	141
+/* PR_RECTX and PR_RECTY must be powers of 2 and >= 64 */
+#define PR_RECTX	256
+#define PR_RECTY	256
 #define PR_XMIN		10
 #define PR_YMIN		5
 #define PR_XMAX		200
@@ -237,69 +238,6 @@ static unsigned int previewback(int type
 	}
 }
 
-static void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax)
-{
-	float pr_sizex, pr_sizey;
-	
-	prerect.xmin= xmin;
-	prerect.ymin= ymin;
-	prerect.xmax= xmax;
-	prerect.ymax= ymax;
-
-	ui_graphics_to_window(win, &prerect.xmin, &prerect.ymin);
-	ui_graphics_to_window(win, &prerect.xmax, &prerect.ymax);
-	
-	pr_sizex= (prerect.xmax-prerect.xmin);
-	pr_sizey= (prerect.ymax-prerect.ymin);
-
-	pr_facx= ( pr_sizex-1.0)/PR_RECTX;
-	pr_facy= ( pr_sizey-1.0)/PR_RECTY;
-
-	/* correction for gla draw */
-	prerect.xmin-= curarea->winrct.xmin;
-	prerect.ymin-= curarea->winrct.ymin;
-	
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	
-	glaDefine2DArea(&curarea->winrct);
-
-	glPixelZoom(pr_facx, pr_facy);
-	
-}
-
-static void end_previewrect(void)
-{
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-	
-	glPixelZoom(1.0, 1.0);
-	
-	// restore viewport / scissor which was set by glaDefine2DArea
-	glViewport(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy);
-	glScissor(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy);
-
-}
-
-static void display_pr_scanline(unsigned int *rect, int recty)
-{
-	
-	/* we do steps of 4 scanlines. but draw 5, because of errors in some gfx cards (nvidia geforce, ati...) */
-	if( (recty & 3)==3) {
-		
-		if(recty == 3) {
-			glaDrawPixelsSafe(prerect.xmin, prerect.ymin, PR_RECTX, 4, rect);
-		}
-		else {
-			rect+= (recty-4)*PR_RECTX;
-			glaDrawPixelsSafe(prerect.xmin, prerect.ymin + (((float)recty-4.0)*pr_facy), PR_RECTX, 5, rect);
-		}
-	}
-}
 
 static void draw_tex_crop(Tex *tex)
 {
@@ -380,15 +318,42 @@ void BIF_previewdraw(void)
 	
 	if (sbuts->rect==0) BIF_preview_changed(sbuts);
 	else {
-		int y;
-
-		set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX);
+		GLuint texid;
 		
-		for (y=0; y<PR_RECTY; y++) {
-			display_pr_scanline(sbuts->rect, y);
-		}
-
-		end_previewrect();
+		/* generate the texture and bind it */
+		glEnable(GL_TEXTURE_2D);
+		glGenTextures(1, &texid);
+		/* texid is 0 if there is a problem */
+		glBindTexture(GL_TEXTURE_2D, texid);
+
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		
+		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+		glTexImage2D(GL_TEXTURE_2D, 0, 4, PR_RECTX, PR_RECTY, 0, GL_RGBA, 
+			GL_UNSIGNED_BYTE, sbuts->rect);
+		
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+		glDisable(GL_BLEND); /* it looks weird with blending on */
+		
+		glBindTexture(GL_TEXTURE_2D, texid);
+		glColor4f(1, 1, 1, 1);
+		
+		glBegin(GL_POLYGON);
+		glTexCoord2f(0.0, 0.0); glVertex2f(PR_XMIN, PR_YMIN);
+		glTexCoord2f(0.0, 1.0); glVertex2f(PR_XMIN, PR_YMAX);
+		glTexCoord2f(1.0, 1.0); glVertex2f(PR_XMAX, PR_YMAX);
+		glTexCoord2f(1.0, 0.0); glVertex2f(PR_XMAX, PR_YMIN);
+		glEnd();
+		
+		glDisable(GL_TEXTURE_2D);
+		glDeleteTextures(1, &texid);
 		
 		if (sbuts->mainb==CONTEXT_SHADING && sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_TEX) {
 			draw_tex_crop(sbuts->lockpoin);
@@ -592,10 +557,7 @@ static void previewflare(SpaceButs *sbut
 	// not sure why, either waitcursor or renderflare screws up (disabled then)
 	//areawinset(curarea->win);
 	
-	/* draw can just be this way, all settings are OK */
-	for (y=0; y<PR_RECTY; y++) {
-		display_pr_scanline(sbuts->rect, y);
-	}
+	BIF_previewdraw();
 	
 	/* temps */
 	R.ycor= ycor;
@@ -1167,7 +1129,7 @@ void BIF_previewrender(SpaceButs *sbuts)
 
 	uiPanelPush(block);	// sets UImat
 	
-	set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX); // uses UImat
+	/*set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX);*/ // uses UImat
 
 	if(sbuts->rect==NULL) {
 		sbuts->rect= MEM_callocN(sizeof(int)*PR_RECTX*PR_RECTY, "butsrect");
@@ -1291,7 +1253,7 @@ void BIF_previewrender(SpaceButs *sbuts)
 			}
 		}
 
-		display_pr_scanline(sbuts->rect, sbuts->cury);
+		BIF_previewdraw();
 		
 		/* flush opengl for cards with frontbuffer slowness */
 		if(sbuts->cury==PR_RECTY-1 || (PIL_check_seconds_timer() - lasttime > 0.05)) {
@@ -1302,7 +1264,7 @@ void BIF_previewrender(SpaceButs *sbuts)
 		sbuts->cury++;
 	}
 
-	end_previewrect();
+	/*end_previewrect();*/
 	
 	if(sbuts->cury>=PR_RECTY && tex) 
 		if (sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_TEX) 


More information about the Bf-committers mailing list