[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36888] branches/soc-2011-onion/source/ blender: GSOC - 2011

Ryakiotakis Antonis kalast at gmail.com
Wed May 25 04:59:02 CEST 2011


Revision: 36888
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36888
Author:   psy-fi
Date:     2011-05-25 02:59:01 +0000 (Wed, 25 May 2011)
Log Message:
-----------
GSOC - 2011

--- first draft of high resolution texture support in 3D view. ---

This commit is still early development proof-of-concept and has a lot of restrictions.
Known at the moment are the following(but, of course the number of issues to increase)
1) Tiled textures are not supported yet and may break

High res textures need float images! Normal 8-bit images do not support high res textures(what would be the point anyway? :))

http://www.pasteall.org/pic/12761 for a sample

n'Joy :)

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/gpu/intern/gpu_draw.c
    branches/soc-2011-onion/source/blender/imbuf/IMB_imbuf.h
    branches/soc-2011-onion/source/blender/imbuf/intern/divers.c

Modified: branches/soc-2011-onion/source/blender/gpu/intern/gpu_draw.c
===================================================================
--- branches/soc-2011-onion/source/blender/gpu/intern/gpu_draw.c	2011-05-24 22:51:46 UTC (rev 36887)
+++ branches/soc-2011-onion/source/blender/gpu/intern/gpu_draw.c	2011-05-25 02:59:01 UTC (rev 36888)
@@ -410,6 +410,10 @@
 	unsigned int *rectrow, *tilerectrow;
 	unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL;
 	short texwindx, texwindy, texwinsx, texwinsy;
+	/*OpenGL internal format, used to set float or high precision integer formats*/
+	unsigned int openGLinternalFormat = GL_RGBA; 
+	/*image format is blender's internal format*/
+	unsigned int imageFormat = GL_UNSIGNED_BYTE;
 
 	/* initialize tile mode and number of repeats */
 	GTS.ima = ima;
@@ -459,10 +463,17 @@
 	if(ibuf==NULL)
 		return 0;
 
-	/* ensure we have a char buffer and not only float */
-	if ((ibuf->rect==NULL) && ibuf->rect_float)
-		IMB_rect_from_float(ibuf);
-
+	if (ibuf->rect_float){
+		/* ensure we have a char buffer too if high precision not suported by hardware*/
+		if(ibuf->rect==NULL){
+			IMB_rect_from_float(ibuf);
+		}
+		/*Use high precision textures. This is relatively harmless because OpenGL gives us
+		a high precision format only if it is available*/
+		openGLinternalFormat = GL_RGBA16;
+		imageFormat = GL_FLOAT;
+	}
+		
 	/* currently, tpage refresh is used by ima sequences */
 	if(ima->tpageflag & IMA_TPAGE_REFRESH) {
 		GPU_free_image(ima);
@@ -532,13 +543,14 @@
 		rect= tilerect;
 	}
 
-	/* scale if not a power of two */
+	/* scale if not a power of two. This is not strictly necessary for newer 
+	GPUs (OpenGL version >= 2.0)since they support non-power-of-two-textures */
 	if (!is_pow2_limit(rectw) || !is_pow2_limit(recth)) {
 		rectw= smaller_pow2_limit(rectw);
 		recth= smaller_pow2_limit(recth);
 		
 		scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
-		gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
+		gluScaleImage(GL_RGBA, tpx, tpy, imageFormat, rect, rectw, recth, imageFormat, scalerect);
 		rect= scalerect;
 	}
 
@@ -547,12 +559,18 @@
 	glBindTexture( GL_TEXTURE_2D, *bind);
 
 	if (!(gpu_get_mipmap() && mipmap)) {
-		glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA,  rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+		if(imageFormat == GL_FLOAT)
+			glTexImage2D(GL_TEXTURE_2D, 0,  openGLinternalFormat,  rectw, recth, 0, GL_RGBA, imageFormat, ibuf->rect_float);			
+		else
+			glTexImage2D(GL_TEXTURE_2D, 0,  openGLinternalFormat,  rectw, recth, 0, GL_RGBA, imageFormat, rect);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
 	}
 	else {
-		gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+		if(imageFormat == GL_FLOAT)
+			gluBuild2DMipmaps(GL_TEXTURE_2D, openGLinternalFormat, rectw, recth, GL_RGBA, imageFormat, ibuf->rect_float);
+		else
+			gluBuild2DMipmaps(GL_TEXTURE_2D, openGLinternalFormat, rectw, recth, GL_RGBA, imageFormat, rect);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
 
@@ -692,7 +710,15 @@
 				IMB_rect_from_float(ibuf);
 			}
             else {
-				IMB_partial_rect_from_float(ibuf, x, y, w, h);
+				float *buffer = (float *)MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
+				IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
+				glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+				glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+					GL_FLOAT, buffer);
+				MEM_freeN(buffer);
+				if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
+					ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+				return;
             }
 		}
 		

Modified: branches/soc-2011-onion/source/blender/imbuf/IMB_imbuf.h
===================================================================
--- branches/soc-2011-onion/source/blender/imbuf/IMB_imbuf.h	2011-05-24 22:51:46 UTC (rev 36887)
+++ branches/soc-2011-onion/source/blender/imbuf/IMB_imbuf.h	2011-05-25 02:59:01 UTC (rev 36888)
@@ -320,8 +320,11 @@
  */
 void IMB_de_interlace(struct ImBuf *ibuf);
 void IMB_interlace(struct ImBuf *ibuf);
+
+/*create char buffer, color corrected if necessary, for ImBufs that lack one*/ 
 void IMB_rect_from_float(struct ImBuf *ibuf);
-void IMB_partial_rect_from_float(struct ImBuf *ibuf, int x, int y, int w, int h);
+/*create char buffer for part of the image, color corrected if necessary, for ImBufs that lack one*/ 
+void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h);
 void IMB_float_from_rect(struct ImBuf *ibuf);
 void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
 /* note, check that the conversion exists, only some are supported */

Modified: branches/soc-2011-onion/source/blender/imbuf/intern/divers.c
===================================================================
--- branches/soc-2011-onion/source/blender/imbuf/intern/divers.c	2011-05-24 22:51:46 UTC (rev 36887)
+++ branches/soc-2011-onion/source/blender/imbuf/intern/divers.c	2011-05-25 02:59:01 UTC (rev 36888)
@@ -199,21 +199,21 @@
 
  
 
-/*converts from linear float to sRGB byte for part of the texture*/
-void IMB_partial_rect_from_float(struct ImBuf *ibuf, int x, int y, int w, int h)
+/*converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part*/
+void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h)
 {
 	/*indices to source and destination image pixels*/
 	float *srcFloatPxl;
 	unsigned char *dstBytePxl;
+	/*buffer index will fill buffer*/
+	float *bufferIndex;
 
 	/*convenience pointers to start of image buffers*/
-	const float *init_srcFloatPxl = (float *)ibuf->rect_float;
-	const unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect;
+	float *init_srcFloatPxl = (float *)ibuf->rect_float;
+	unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect;
 
 	/*Dithering factor*/
 	float dither= ibuf->dither / 255.0f;
-	/*temporary srgb result holder*/
-	float srgb[4];
 	/*respective attributes of image*/
 	short profile= ibuf->profile;
 	int channels= ibuf->channels;
@@ -231,27 +231,31 @@
 	}
 	if(channels==1) {
 			for (j = 0; j < h; j++){
+				bufferIndex = buffer + w*j*4;
 				dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
 				srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-				for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4) {
+				for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
 					dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]);
+					bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0];
 				}
 			}
 	}
 	else if (profile == IB_PROFILE_LINEAR_RGB) {
 		if(channels == 3) {
 			for (j = 0; j < h; j++){
+				bufferIndex = buffer + w*j*4;
 				dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
 				srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-				for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4) {
+				for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex += 4) {
 
-					srgb[0]= linearrgb_to_srgb(srcFloatPxl[0]);
-					srgb[1]= linearrgb_to_srgb(srcFloatPxl[1]);
-					srgb[2]= linearrgb_to_srgb(srcFloatPxl[2]);
+					bufferIndex[0]= linearrgb_to_srgb(srcFloatPxl[0]);
+					bufferIndex[1]= linearrgb_to_srgb(srcFloatPxl[1]);
+					bufferIndex[2]= linearrgb_to_srgb(srcFloatPxl[2]);
+					bufferIndex[3]= 1.0;
 
-					dstBytePxl[0] = FTOCHAR(srgb[0]);
-					dstBytePxl[1] = FTOCHAR(srgb[1]);
-					dstBytePxl[2] = FTOCHAR(srgb[2]);
+					dstBytePxl[0] = FTOCHAR(bufferIndex[0]);
+					dstBytePxl[1] = FTOCHAR(bufferIndex[1]);
+					dstBytePxl[2] = FTOCHAR(bufferIndex[2]);
 					dstBytePxl[3] = 255;
 				}
 			}
@@ -259,36 +263,38 @@
 		else if (channels == 4) {
 			if (dither != 0.f) {
 				for (j = 0; j < h; j++){
+					bufferIndex = buffer + w*j*4;
 					dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
 					srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-					for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4) {
+					for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
 						const float d = (BLI_frand()-0.5f)*dither;
 
-						srgb[0]= d + linearrgb_to_srgb(srcFloatPxl[0]);
-						srgb[1]= d + linearrgb_to_srgb(srcFloatPxl[1]);
-						srgb[2]= d + linearrgb_to_srgb(srcFloatPxl[2]);
-						srgb[3]= d + srcFloatPxl[3];
+						bufferIndex[0]= d + linearrgb_to_srgb(srcFloatPxl[0]);
+						bufferIndex[1]= d + linearrgb_to_srgb(srcFloatPxl[1]);
+						bufferIndex[2]= d + linearrgb_to_srgb(srcFloatPxl[2]);
+						bufferIndex[3]= d + srcFloatPxl[3];
 
-						dstBytePxl[0] = FTOCHAR(srgb[0]);
-						dstBytePxl[1] = FTOCHAR(srgb[1]);
-						dstBytePxl[2] = FTOCHAR(srgb[2]);
-						dstBytePxl[3] = FTOCHAR(srgb[3]);
+						dstBytePxl[0] = FTOCHAR(bufferIndex[0]);
+						dstBytePxl[1] = FTOCHAR(bufferIndex[1]);
+						dstBytePxl[2] = FTOCHAR(bufferIndex[2]);
+						dstBytePxl[3] = FTOCHAR(bufferIndex[3]);
 					}
 				}
 			} else {
 				for (j = 0; j < h; j++){
+					bufferIndex = buffer + w*j*4;
 					dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
 					srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-					for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4) {
-						srgb[0]= linearrgb_to_srgb(srcFloatPxl[0]);
-						srgb[1]= linearrgb_to_srgb(srcFloatPxl[1]);
-						srgb[2]= linearrgb_to_srgb(srcFloatPxl[2]);
-						srgb[3]= srcFloatPxl[3];
+					for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+						bufferIndex[0]= linearrgb_to_srgb(srcFloatPxl[0]);
+						bufferIndex[1]= linearrgb_to_srgb(srcFloatPxl[1]);
+						bufferIndex[2]= linearrgb_to_srgb(srcFloatPxl[2]);
+						bufferIndex[3]= srcFloatPxl[3];
 
-						dstBytePxl[0] = FTOCHAR(srgb[0]);
-						dstBytePxl[1] = FTOCHAR(srgb[1]);
-						dstBytePxl[2] = FTOCHAR(srgb[2]);
-						dstBytePxl[3] = FTOCHAR(srgb[3]);
+						dstBytePxl[0] = FTOCHAR(bufferIndex[0]);
+						dstBytePxl[1] = FTOCHAR(bufferIndex[1]);
+						dstBytePxl[2] = FTOCHAR(bufferIndex[2]);
+						dstBytePxl[3] = FTOCHAR(bufferIndex[3]);
 					}
 				}
 			}
@@ -297,45 +303,49 @@
 	else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
 		if(channels==3) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list