[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29871] branches/soc-2010-jwilkins/source/ blender: * overlay texture now only updates when the texture has changed

Jason Wilkins Jason.A.Wilkins at gmail.com
Fri Jul 2 14:39:39 CEST 2010


Revision: 29871
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29871
Author:   jwilkins
Date:     2010-07-02 14:39:39 +0200 (Fri, 02 Jul 2010)

Log Message:
-----------
* overlay texture now only updates when the texture has changed
* overlay does not delete/recreate the texture slot, but uses glTexSubImage to update the existing texture
* overlay texture now has alpha so that blacker areas are also more transparent
* overlay texture size increased to 512x512
* added a 'changed_timestamp' field to the texture preview structure to allow notification if the preview has changed to be monitored by more parts of the program than just the icon renderer
* All of this is the first step in unifying the overlay with a new texcache
* Also first steps in making the overlay a seperate operator

Modified Paths:
--------------
    branches/soc-2010-jwilkins/source/blender/blenkernel/intern/brush.c
    branches/soc-2010-jwilkins/source/blender/blenkernel/intern/icons.c
    branches/soc-2010-jwilkins/source/blender/editors/interface/interface_icons.c
    branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c
    branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/sculpt.c
    branches/soc-2010-jwilkins/source/blender/makesdna/DNA_ID.h
    branches/soc-2010-jwilkins/source/blender/makesdna/DNA_brush_types.h

Modified: branches/soc-2010-jwilkins/source/blender/blenkernel/intern/brush.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/blenkernel/intern/brush.c	2010-07-02 11:26:12 UTC (rev 29870)
+++ branches/soc-2010-jwilkins/source/blender/blenkernel/intern/brush.c	2010-07-02 12:39:39 UTC (rev 29871)
@@ -101,8 +101,6 @@
 	/* BRUSH TEXTURE SETTINGS */
 	brush->texture_sample_bias = 0; /* value to added to texture samples */
 
-	brush->overlay_texture = 0; /* toggles whether the texture is shown as an overlay when not sculpting 0 is off */
-
 	brush->autosmooth_factor = 0;
 
 	brush->crease_pinch_factor = 2.0f/3.0f;
@@ -957,7 +955,7 @@
 
 	memset(&texres, 0, sizeof(TexResult));
 	
-	if(mtex && mtex->tex) {
+	if(mtex->tex) {
 		float x, y, step = 2.0 / side, co[3];
 
 		texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");

Modified: branches/soc-2010-jwilkins/source/blender/blenkernel/intern/icons.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/blenkernel/intern/icons.c	2010-07-02 11:26:12 UTC (rev 29870)
+++ branches/soc-2010-jwilkins/source/blender/blenkernel/intern/icons.c	2010-07-02 12:39:39 UTC (rev 29871)
@@ -121,6 +121,7 @@
 
 	for (i=0; i<PREVIEW_MIPMAPS; ++i) {
 		prv_img->changed[i] = 1;
+		prv_img->changed_timestamp[i] = 0;
 	}
 	return prv_img;
 }
@@ -248,6 +249,7 @@
 			int i;
 			for (i=0; i<PREVIEW_MIPMAPS; ++i) {
 				prv->changed[i] = 1;
+				prv->changed_timestamp[i]++;
 			}
 		}
 	}	

Modified: branches/soc-2010-jwilkins/source/blender/editors/interface/interface_icons.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/editors/interface/interface_icons.c	2010-07-02 11:26:12 UTC (rev 29870)
+++ branches/soc-2010-jwilkins/source/blender/editors/interface/interface_icons.c	2010-07-02 12:39:39 UTC (rev 29871)
@@ -767,6 +767,7 @@
 		prv_img->w[miplevel] = size;
 		prv_img->h[miplevel] = size;
 		prv_img->changed[miplevel] = 1;
+		prv_img->changed_timestamp[miplevel] = 0;
 		prv_img->rect[miplevel] = MEM_callocN(size*size*sizeof(unsigned int), "prv_rect"); 
 	}
 }

Modified: branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c	2010-07-02 11:26:12 UTC (rev 29870)
+++ branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c	2010-07-02 12:39:39 UTC (rev 29871)
@@ -171,13 +171,13 @@
 
 static void load_grid(Brush* brush)
 {
-	static int loaded = 0;
+	static GLint overlay_texture;
 
-	if (!loaded) {
+	if (!overlay_texture) {
 		//GLfloat largest_supported_anisotropy;
 
-		glGenTextures(1, (GLint*)(&(brush->overlay_texture)));
-		glBindTexture(GL_TEXTURE_2D, brush->overlay_texture);
+		glGenTextures(1, &overlay_texture);
+		glBindTexture(GL_TEXTURE_2D, overlay_texture);
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture0);
 		glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB,  8,  8, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture1);
 		glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB,  4,  4, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture2);
@@ -193,77 +193,142 @@
 
 		//glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
 		//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
-
-		loaded = 1;
 	}
 }
 
 extern float get_tex_pixel(Brush* br, float u, float v);
 
-static void load_tex(Brush* brush, ViewContext* vc)
+typedef struct Snapshot {
+	float size[3];
+	float ofs[3];
+	float rot;
+	int brush_size;
+	int winx;
+	int winy;
+} Snapshot;
+
+static int same_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
 {
-	float* buffer;
+	MTex* mtex = &brush->mtex;
+
+	return 
+		mtex->ofs[0] == snap->ofs[0] &&
+		mtex->ofs[1] == snap->ofs[1] &&
+		mtex->ofs[2] == snap->ofs[2] &&
+		mtex->size[0] == snap->size[0] &&
+		mtex->size[1] == snap->size[1] &&
+		mtex->size[2] == snap->size[2] &&
+		mtex->rot == snap->rot &&
+		brush->size == snap->brush_size &&
+		vc->ar->winx == snap->winx &&
+		vc->ar->winy == snap->winy;
+}
+
+static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
+{
+	copy_v3_v3(snap->ofs, brush->mtex.ofs);
+	copy_v3_v3(snap->size, brush->mtex.size);
+	snap->rot = brush->mtex.rot;
+	snap->brush_size = brush->size;
+	snap->winx = vc->ar->winx;
+	snap->winy = vc->ar->winy;
+}
+
+static int load_tex(Brush* brush, ViewContext* vc)
+{
+	static GLint overlay_texture = 0;
+	static int init = 0;
+	static int changed_timestamp = -1;
+	static Snapshot snap;
+
+	float* buffer = 0;
 	float* p;
 
 	int width, height;
 	float x, y;
 	int i, j;
 	float xlim, ylim;
+	int refresh;
 
-	if (brush->overlay_texture) glDeleteTextures(1, (GLint*)(&brush->overlay_texture));
+	if (!brush->mtex.tex) return 0;
 
-	width = height = 256;
+	refresh = 
+		!overlay_texture ||
+		!brush->mtex.tex->preview ||
+		brush->mtex.tex->preview->changed_timestamp[0] != changed_timestamp ||
+		!same_snap(&snap, brush, vc);
 
-	p = buffer = MEM_mallocN(sizeof(float)*width*height, "load_tex");
+	if (refresh) {
+		if (brush->mtex.tex->preview)
+			changed_timestamp = brush->mtex.tex->preview->changed_timestamp[0];
 
-	xlim = brush->size / (float)vc->ar->winx  *  width;
-	ylim = brush->size / (float)vc->ar->winy  *  height;
+		make_snap(&snap, brush, vc);
 
-	for (j = 0, y = 0; j < height; j++, y = j/ylim) {
-		for (i = 0, x = 0; i < width; i++, x = i/xlim) {
+		width = height = 512;
 
-			// largely duplicated from tex_strength
+		p = buffer = MEM_mallocN(2*sizeof(float)*width*height, "load_tex");
 
-			const float rotation = -brush->mtex.rot;
-			float diameter = brush->size;
+		xlim = brush->size / (float)vc->ar->winx  *  width;
+		ylim = brush->size / (float)vc->ar->winy  *  height;
 
-			x = (float)i/width;
-			y = (float)j/height;
+		for (j = 0, y = 0; j < height; j++, y = j/ylim) {
+			for (i = 0, x = 0; i < width; i++, x = i/xlim) {
 
-			x -= 0.5f;
-			y -= 0.5f;
-			
-			x *= vc->ar->winx / diameter;
-			y *= vc->ar->winy / diameter;
+				// largely duplicated from tex_strength
 
-			/* it is probably worth optimizing for those cases where 
-			   the texture is not rotated by skipping the calls to
-			   atan2, sqrtf, sin, and cos. */
-			if (rotation > 0.001 || rotation < -0.001) {
-				const float angle    = atan2(y, x) + rotation;
-				const float flen     = sqrtf(x*x + y*y);
+				const float rotation = -brush->mtex.rot;
+				float diameter = brush->size;
 
-				x = flen * cos(angle);
-				y = flen * sin(angle);
-			}
+				x = (float)i/width;
+				y = (float)j/height;
 
-			x *= brush->mtex.size[0];
-			y *= brush->mtex.size[1];
+				x -= 0.5f;
+				y -= 0.5f;
+				
+				x *= vc->ar->winx / diameter;
+				y *= vc->ar->winy / diameter;
 
-			x += brush->mtex.ofs[0];
-			y += brush->mtex.ofs[1];
+				/* it is probably worth optimizing for those cases where 
+				   the texture is not rotated by skipping the calls to
+				   atan2, sqrtf, sin, and cos. */
+				if (rotation > 0.001 || rotation < -0.001) {
+					const float angle    = atan2(y, x) + rotation;
+					const float flen     = sqrtf(x*x + y*y);
 
-			*p = get_tex_pixel(brush, x, y);
+					x = flen * cos(angle);
+					y = flen * sin(angle);
+				}
 
-			p++;
+				x *= brush->mtex.size[0];
+				y *= brush->mtex.size[1];
+
+				x += brush->mtex.ofs[0];
+				y += brush->mtex.ofs[1];
+
+				*p = *(p+1) = get_tex_pixel(brush, x, y);
+
+				p += 2;
+			}
 		}
+
+		if (!overlay_texture)
+			glGenTextures(1, &overlay_texture);
 	}
 
-	glGenTextures(1, (GLint*)(&(brush->overlay_texture)));
+	glBindTexture(GL_TEXTURE_2D, overlay_texture);
 
-	glBindTexture(GL_TEXTURE_2D, brush->overlay_texture);
+	if (refresh) {
+		if (!init) {
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_FLOAT, buffer);
+			init = 1;
+		}
+		else {
+			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE_ALPHA, GL_FLOAT, buffer);
+		}
 
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE, GL_FLOAT, buffer);
+		if (buffer)
+			MEM_freeN(buffer);
+	}
 
 	glEnable(GL_TEXTURE_2D);
 
@@ -271,7 +336,7 @@
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
-	MEM_freeN(buffer);
+	return 1;
 }
 
 /* Convert a point in model coordinates to 2D screen coordinates. */
@@ -643,48 +708,34 @@
 					GL_VIEWPORT_BIT|
 					GL_TEXTURE_BIT);
 
-				glColor4f(col[0], col[1], col[2], alpha);
+				if (load_tex(brush, &vc)) {
+					glColor4f(col[0], col[1], col[2], alpha);
 
-				glEnable(GL_BLEND);
+					glEnable(GL_BLEND);
 
-				load_tex(brush, &vc);
+					glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+					glDepthMask(GL_FALSE);
+					glDepthFunc(GL_ALWAYS);
 
-				glEnable(GL_TEXTURE_2D);
-				glBindTexture(GL_TEXTURE_2D, brush->overlay_texture);
+					glMatrixMode(GL_TEXTURE);
+					glLoadIdentity();
 
-				glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
-				glDepthMask(GL_FALSE);
-				glDepthFunc(GL_ALWAYS);
+					glColor4f(1.0f, 1.0f, 1.0f, brush->texture_overlay_alpha / 100.0f);
+					glBegin(GL_QUADS);
+						glTexCoord2f(0, 0);
+						glVertex2f(0, 0);
 
-				glMatrixMode(GL_TEXTURE);
-				glLoadIdentity();
+						glTexCoord2f(1, 0);
+						glVertex2f(viewport[2], 0);
 
-				glColor4f(1.0f, 1.0f, 1.0f, brush->texture_overlay_alpha / 100.0f);
-				glBegin(GL_QUADS);
-					glTexCoord2f(0, 0);
-					glVertex2f(0, 0);
+						glTexCoord2f(1, 1);
+						glVertex2f(viewport[2], viewport[3]);
 
-					glTexCoord2f(1, 0);
-					glVertex2f(viewport[2], 0);
+						glTexCoord2f(0, 1);
+						glVertex2f(0, viewport[3]);
+					glEnd();
+				}
 
-					glTexCoord2f(1, 1);
-					glVertex2f(viewport[2], viewport[3]);
-
-					glTexCoord2f(0, 1);
-					glVertex2f(0, viewport[3]);
-				glEnd();
-
-				glLoadIdentity();
-
-				glMatrixMode(GL_MODELVIEW);
-
-				glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
-				glDisable(GL_TEXTURE_2D);
-
-				glDepthMask(GL_TRUE);
-				glDepthFunc(GL_LEQUAL);
-
 				glPopAttrib();
 			}
 		}

Modified: branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/sculpt.c	2010-07-02 11:26:12 UTC (rev 29870)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list