[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49929] branches/soc-2012-bratwurst/source /blender/editors/sculpt_paint/paint_cursor.c: Fix overlay for tiled mapping .

Antony Riakiotakis kalast at gmail.com
Thu Aug 16 05:14:29 CEST 2012


Revision: 49929
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49929
Author:   psy-fi
Date:     2012-08-16 03:14:28 +0000 (Thu, 16 Aug 2012)
Log Message:
-----------
Fix overlay for tiled mapping. This involves separating the overlay
generation code between alpha(brush curve, mask texture) and image
opengl textures and combining the two with multitexture combiners
(ancient functionality that should work everywhere). It still needs some
testing but result is now as expected.

Modified Paths:
--------------
    branches/soc-2012-bratwurst/source/blender/editors/sculpt_paint/paint_cursor.c

Modified: branches/soc-2012-bratwurst/source/blender/editors/sculpt_paint/paint_cursor.c
===================================================================
--- branches/soc-2012-bratwurst/source/blender/editors/sculpt_paint/paint_cursor.c	2012-08-16 02:53:04 UTC (rev 49928)
+++ branches/soc-2012-bratwurst/source/blender/editors/sculpt_paint/paint_cursor.c	2012-08-16 03:14:28 UTC (rev 49929)
@@ -57,6 +57,9 @@
  * removed eventually (TODO) */
 #include "sculpt_intern.h"
 
+#define CURSOR_RESOLUTION 40
+
+
 /* TODOs:
  *
  * Some of the cursor drawing code is doing non-draw stuff
@@ -66,7 +69,12 @@
  * There is also some ugliness with sculpt-specific code.
  */
 
-typedef struct Snapshot {
+typedef struct SnapshotAlpha {
+	int BKE_brush_size_get;
+	int alpha_changed_timestamp;
+} SnapshotAlpha;
+
+typedef struct SnapshotTex {
 	float size[3];
 	float ofs[3];
 	float rot;
@@ -74,10 +82,9 @@
 	int winx;
 	int winy;
 	int brush_map_mode;
-	int curve_changed_timestamp;
-} Snapshot;
+} SnapshotTex;
 
-static int same_snap(Snapshot *snap, Brush *brush, ViewContext *vc)
+static int same_snap_image(SnapshotTex *snap, Brush *brush, ViewContext *vc)
 {
 	MTex *mtex = &brush->mtex;
 
@@ -96,7 +103,7 @@
 	        (vc->ar->winy == snap->winy));
 }
 
-static void make_snap(Snapshot *snap, Brush *brush, ViewContext *vc)
+static void make_snap_image(SnapshotTex *snap, Brush *brush, ViewContext *vc)
 {
 	if (brush->mtex.tex) {
 		snap->brush_map_mode = brush->mtex.brush_map_mode;
@@ -116,59 +123,178 @@
 	snap->winy = vc->ar->winy;
 }
 
-static int load_tex(Brush *br, ViewContext *vc)
+static int load_brush_tex_alpha(Brush *br, ViewContext *vc)
 {
+	static GLuint overlay_texture_alpha = 0;
+	static int init_alpha = 0;
+	static SnapshotAlpha snap;
+	static int old_alpha_size = -1;
+
+	GLubyte *alpha_buffer = NULL;
+
+	/*
+	char do_tiled_texpaint = (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED_TEXPAINT);
+	char do_tiled = (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || do_tiled_texpaint;
+	*/
+	int alpha_size;
+	int j;
+	int refresh;
+
+	//if (do_tiled && !br->mask_mtex.tex) return 0;
+
+	refresh =
+			(snap.BKE_brush_size_get != BKE_brush_size_get(vc->scene, br)) ||
+			!br->curve ||
+			br->curve->changed_timestamp != snap.alpha_changed_timestamp ||
+			!overlay_texture_alpha;
+
+	if (refresh) {
+		int s = BKE_brush_size_get(vc->scene, br);
+		int r = 1;
+
+		if (br->curve)
+			snap.alpha_changed_timestamp = br->curve->changed_timestamp;
+
+		snap.BKE_brush_size_get = BKE_brush_size_get(vc->scene, br);
+
+		for (s >>= 1; s > 0; s >>= 1)
+			r++;
+
+		alpha_size = (1 << r);
+
+		if (alpha_size < 256)
+			alpha_size = 256;
+
+		if (alpha_size < old_alpha_size)
+			alpha_size = old_alpha_size;
+
+		if (old_alpha_size != alpha_size) {
+			if (overlay_texture_alpha) {
+				glDeleteTextures(1, &overlay_texture_alpha);
+				overlay_texture_alpha = 0;
+			}
+
+			init_alpha = 0;
+
+			old_alpha_size = alpha_size;
+		}
+
+		alpha_buffer = MEM_mallocN(sizeof(GLubyte) * alpha_size * alpha_size, "load_tex_curve");
+
+		/* dummy call to avoid generating curve tables in openmp, causes memory leaks since allocation
+		 * is not thread safe */
+		BKE_brush_curve_strength(br, 0.5, 1);
+
+		#pragma omp parallel for schedule(static)
+		for (j = 0; j < alpha_size; j++) {
+			int i;
+			float y;
+			float len;
+
+			for (i = 0; i < alpha_size; i++) {
+				int index = j * alpha_size + i;
+				float x;
+				float avg;
+
+				x = (float)i / alpha_size;
+				y = (float)j / alpha_size;
+
+				x -= 0.5f;
+				y -= 0.5f;
+
+				x *= 2;
+				y *= 2;
+
+				len = sqrtf(x * x + y * y);
+
+				if (len <= 1) {
+					x *= br->mtex.size[0];
+					y *= br->mtex.size[1];
+
+					x += br->mtex.ofs[0];
+					y += br->mtex.ofs[1];
+
+					avg = BKE_brush_curve_strength(br, len, 1);  /* Falloff curve */
+
+					if(br->flag & BRUSH_USE_MASK) {
+						avg *= br->mask_mtex.tex ? paint_get_tex_pixel(br, x, y, TRUE) : 1;
+					}
+					CLAMP(avg, 0.0, 1.0);
+
+					alpha_buffer[index] = (GLubyte)(255 * avg);
+				}
+				else {
+					alpha_buffer[index] = 0;
+				}
+			}
+		}
+
+		if (!overlay_texture_alpha)
+			glGenTextures(1, &overlay_texture_alpha);
+	}
+
+	/* switch to second texture unit */
+	glBindTexture(GL_TEXTURE_2D, overlay_texture_alpha);
+
+	if (refresh) {
+		if (!init_alpha) {
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, alpha_size, alpha_size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_buffer);
+			init_alpha = 1;
+		}
+		else {
+			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, alpha_size, alpha_size, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_buffer);
+		}
+
+		if(alpha_buffer)
+			MEM_freeN(alpha_buffer);
+	}
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+	glEnable(GL_TEXTURE_2D);
+
+	return 1;
+}
+
+static int load_brush_tex_image(Brush *br, ViewContext *vc)
+{
 	static GLuint overlay_texture = 0;
-	static GLuint overlay_texture_curve = 0;
 	static int init = 0;
-	static int init_curve = 0;
 	static int tex_changed_timestamp = -1;
-	static int curve_changed_timestamp = -1;
-	static Snapshot snap;
+	static SnapshotTex snap;
 	static int old_size = -1;
-	static int old_curve_size = -1;
 
 	GLubyte *buffer = NULL;
-	GLubyte *curve_buffer = NULL;
 
 	char do_tiled_texpaint = (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED_TEXPAINT);
 	char do_tiled = (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || do_tiled_texpaint;
 
 	int size;
-	int curve_size;
 	int j;
-	int refresh, refresh_curve;
+	int refresh;
 
-	if (do_tiled && !br->mtex.tex) return 0;
+	if (!br->mtex.tex) return 0;
 	
-	refresh = 
-	    !overlay_texture ||
-	    (br->mtex.tex &&
-	     (!br->mtex.tex->preview ||
-	      br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) ||
-	    !br->curve ||
-	    br->curve->changed_timestamp != curve_changed_timestamp ||
-	    !same_snap(&snap, br, vc);
+	refresh =
+		!overlay_texture ||
+		(br->mtex.tex &&
+		(!br->mtex.tex->preview ||
+		br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) ||
+		!same_snap_image(&snap, br, vc);
 
-	refresh_curve = do_tiled &&
-	        ((snap.BKE_brush_size_get != BKE_brush_size_get(vc->scene, br)) ||
-	        !br->curve ||
-	        br->curve->changed_timestamp != curve_changed_timestamp ||
-	        br->mtex.brush_map_mode != snap.brush_map_mode ||
-	        !overlay_texture_curve);
-
-	if (refresh || refresh_curve) {
+	if (refresh) {
 		int s = BKE_brush_size_get(vc->scene, br);
 		int r = 1;
 
 		if (br->mtex.tex && br->mtex.tex->preview)
 			tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0];
 
-		if (br->curve)
-			curve_changed_timestamp = br->curve->changed_timestamp;
+		make_snap_image(&snap, br, vc);
 
-		make_snap(&snap, br, vc);
-
 		for (s >>= 1; s > 0; s >>= 1)
 			r++;
 
@@ -180,15 +306,6 @@
 		if (size < old_size)
 			size = old_size;
 
-		if(do_tiled) {
-			curve_size = size;
-			size = 512;
-		}
-
-		if(!refresh) {
-			size = old_size;
-		}
-
 		if (old_size != size) {
 			if (overlay_texture) {
 				glDeleteTextures(1, &overlay_texture);
@@ -200,30 +317,8 @@
 			old_size = size;
 		}
 
-		if (old_curve_size != curve_size) {
-			if (overlay_texture_curve) {
-				glDeleteTextures(1, &overlay_texture_curve);
-				overlay_texture_curve = 0;
-			}
-
-			init_curve = 0;
-
-			old_curve_size = curve_size;
-		}
-	}
-
-	/* image texture refresh */
-	if(refresh)
 		buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
 
-	if(refresh_curve)
-		curve_buffer = MEM_mallocN(sizeof(GLubyte) * curve_size * curve_size, "load_tex_curve");
-
-	if(refresh) {
-		/* dummy call to avoid generating curve tables in openmp, causes memory leaks since allocation
-		 * is not thread safe */
-		BKE_brush_curve_strength(br, 0.5, 1);
-
 		#pragma omp parallel for schedule(static)
 		for (j = 0; j < size; j++) {
 			int i;
@@ -263,7 +358,7 @@
 					/* 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 (br->mtex.tex && (rotation > 0.001f || rotation < -0.001f)) {
+					if (rotation > 0.001f || rotation < -0.001f) {
 						const float angle    = atan2f(y, x) + rotation;
 
 						x = len * cosf(angle);
@@ -276,19 +371,11 @@
 					x += br->mtex.ofs[0];
 					y += br->mtex.ofs[1];
 
-					avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y, FALSE) : 1;
+					avg = paint_get_tex_pixel(br, x, y, FALSE);
 
 					avg += br->texture_sample_bias;
 
-					if (!do_tiled) {
-						avg *= BKE_brush_curve_strength(br, len, 1);  /* Falloff curve */
-
-						if(br->flag & BRUSH_USE_MASK) {
-							avg *= br->mask_mtex.tex ? paint_get_tex_pixel(br, x, y, TRUE) : 1;
-						}
-					}
-
-					buffer[index] = 255 - (GLubyte)(255 * avg);
+					buffer[index] = (GLubyte)(255 * avg);
 				}
 				else {
 					buffer[index] = 0;
@@ -300,6 +387,7 @@
 			glGenTextures(1, &overlay_texture);
 	}
 
+	glActiveTexture(GL_TEXTURE1);
 	glBindTexture(GL_TEXTURE_2D, overlay_texture);
 
 	if (refresh) {
@@ -317,8 +405,6 @@
 
 	glEnable(GL_TEXTURE_2D);
 
-	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
@@ -327,98 +413,12 @@
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 	}
 
-	/* view mode doesn't need a separate curve texture */
-	if(!do_tiled)
-		return 1;
-
-	if(refresh_curve) {
-		/* dummy call to avoid generating curve tables in openmp, causes memory leaks since allocation
-		 * is not thread safe */
-		BKE_brush_curve_strength(br, 0.5, 1);
-
-		#pragma omp parallel for schedule(static)
-		for (j = 0; j < curve_size; j++) {
-			int i;
-			float y;
-			float len;
-
-			for (i = 0; i < curve_size; i++) {
-				int index = j * curve_size + i;
-				float x;
-				float avg;
-
-				x = (float)i / curve_size;
-				y = (float)j / curve_size;
-
-				x -= 0.5f;
-				y -= 0.5f;
-
-				x *= 2;
-				y *= 2;
-
-				len = sqrtf(x * x + y * y);
-
-				if (len <= 1) {
-					x *= br->mtex.size[0];
-					y *= br->mtex.size[1];
-
-					x += br->mtex.ofs[0];
-					y += br->mtex.ofs[1];
-
-					avg = BKE_brush_curve_strength(br, len, 1);  /* Falloff curve */
-
-					if(br->flag & BRUSH_USE_MASK) {
-						avg *= br->mask_mtex.tex ? paint_get_tex_pixel(br, x, y, TRUE) : 1;
-					}
-
-					curve_buffer[index] = (GLubyte)(255 * avg);
-				}
-				else {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list