[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37874] branches/soc-2011-cucumber/source: Experimental DDS texture patch from Mitchell Stokes that allows DDS texture to be used uncompressed in OpenGL .

Daniel Stokes kupomail at gmail.com
Mon Jun 27 21:40:43 CEST 2011


Revision: 37874
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37874
Author:   kupoman
Date:     2011-06-27 19:40:42 +0000 (Mon, 27 Jun 2011)
Log Message:
-----------
Experimental DDS texture patch from Mitchell Stokes that allows DDS texture to be used uncompressed in OpenGL. Since OpenGL uses a different coordinate system than DirectX, DDS textures are upside down in OpenGL. That means this patch could cause some problems with people already using DDS textures. A UI option and a do version could address this.

Modified Paths:
--------------
    branches/soc-2011-cucumber/source/blender/gpu/CMakeLists.txt
    branches/soc-2011-cucumber/source/blender/gpu/GPU_draw.h
    branches/soc-2011-cucumber/source/blender/gpu/SConscript
    branches/soc-2011-cucumber/source/blender/gpu/intern/gpu_draw.c
    branches/soc-2011-cucumber/source/blender/imbuf/IMB_imbuf_types.h
    branches/soc-2011-cucumber/source/blender/imbuf/intern/allocimbuf.c
    branches/soc-2011-cucumber/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
    branches/soc-2011-cucumber/source/blender/imbuf/intern/dds/DirectDrawSurface.h
    branches/soc-2011-cucumber/source/blender/imbuf/intern/dds/dds_api.cpp
    branches/soc-2011-cucumber/source/gameengine/Ketsji/BL_Texture.cpp
    branches/soc-2011-cucumber/source/gameengine/Ketsji/BL_Texture.h
    branches/soc-2011-cucumber/source/gameengine/Ketsji/CMakeLists.txt

Modified: branches/soc-2011-cucumber/source/blender/gpu/CMakeLists.txt
===================================================================
--- branches/soc-2011-cucumber/source/blender/gpu/CMakeLists.txt	2011-06-27 18:31:34 UTC (rev 37873)
+++ branches/soc-2011-cucumber/source/blender/gpu/CMakeLists.txt	2011-06-27 19:40:42 UTC (rev 37874)
@@ -58,5 +58,10 @@
 
 add_definitions(-DGLEW_STATIC)
 
+if(WITH_DDS)
+	add_definitions(-DWITH_DDS)
+endif()
+
+
 blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}")
 

Modified: branches/soc-2011-cucumber/source/blender/gpu/GPU_draw.h
===================================================================
--- branches/soc-2011-cucumber/source/blender/gpu/GPU_draw.h	2011-06-27 18:31:34 UTC (rev 37873)
+++ branches/soc-2011-cucumber/source/blender/gpu/GPU_draw.h	2011-06-27 19:40:42 UTC (rev 37874)
@@ -124,6 +124,8 @@
 void GPU_update_images_framechange(void);
 int GPU_update_image_time(struct Image *ima, double time);
 int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, int compare, int mipmap);
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, int rectw, int recth, int mipmap, struct Image *ima);
+void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x, int y, int mipmap, struct Image *ima, struct ImBuf *ibuf);
 void GPU_free_image(struct Image *ima);
 void GPU_free_images(void);
 void GPU_free_images_anim(void);
@@ -140,4 +142,3 @@
 #endif
 
 #endif
-

Modified: branches/soc-2011-cucumber/source/blender/gpu/SConscript
===================================================================
--- branches/soc-2011-cucumber/source/blender/gpu/SConscript	2011-06-27 18:31:34 UTC (rev 37873)
+++ branches/soc-2011-cucumber/source/blender/gpu/SConscript	2011-06-27 19:40:42 UTC (rev 37874)
@@ -13,4 +13,8 @@
 
 incs += ' ' + env['BF_OPENGL_INC']
 
+
+if env['WITH_BF_DDS']:
+	defs.append('WITH_DDS')
+
 env.BlenderLib ( 'bf_gpu', sources, Split(incs), defines = defs, libtype=['core','player'], priority=[160,110] )

Modified: branches/soc-2011-cucumber/source/blender/gpu/intern/gpu_draw.c
===================================================================
--- branches/soc-2011-cucumber/source/blender/gpu/intern/gpu_draw.c	2011-06-27 18:31:34 UTC (rev 37873)
+++ branches/soc-2011-cucumber/source/blender/gpu/intern/gpu_draw.c	2011-06-27 19:40:42 UTC (rev 37874)
@@ -429,7 +429,7 @@
 	unsigned int *bind = NULL;
 	int rectw, recth, tpx=0, tpy=0, y;
 	unsigned int *rectrow, *tilerectrow;
-	unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL;
+	unsigned int *tilerect= NULL, *rect= NULL;
 	short texwindx, texwindy, texwinsx, texwinsy;
 
 	/* initialize tile mode and number of repeats */
@@ -552,15 +552,34 @@
 			
 		rect= tilerect;
 	}
+#ifdef WITH_DDS
+	if (ibuf->ftype & DDS)
+		GPU_create_gl_tex_compressed(bind, rect, rectw, recth, mipmap, ima, ibuf);
+	else
+#endif
+		GPU_create_gl_tex(bind, rect, rectw, recth, mipmap, ima);
 
+	/* clean up */
+	if (tilerect)
+		MEM_freeN(tilerect);
+
+	return *bind;
+}
+
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, int rectw, int recth, int mipmap, Image *ima)
+{
+	unsigned int *scalerect = NULL;
+
 	/* scale if not a power of two */
 	if (!is_pow2_limit(rectw) || !is_pow2_limit(recth)) {
+		int oldw= rectw;
+		int oldh= 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);
-		rect= scalerect;
+		gluScaleImage(GL_RGBA, oldw, oldh, GL_UNSIGNED_BYTE, pix, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
+		pix= scalerect;
 	}
 
 	/* create image */
@@ -568,12 +587,12 @@
 	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);
+		glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA,  rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix);
 		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);
+		gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, pix);
 		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));
 
@@ -584,16 +603,70 @@
 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
 	/* set to modulate with vertex color */
 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-		
-	/* clean up */
-	if (tilerect)
-		MEM_freeN(tilerect);
+
 	if (scalerect)
 		MEM_freeN(scalerect);
+}
 
-	return *bind;
+void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x, int y, int mipmap, Image *ima, ImBuf *ibuf)
+{
+#ifndef WITH_DDS
+	// Fall back to uncompressed if DDS isn't enabled
+	GPU_create_gl_tex(bind, pix, x, y, mipmap, ima);
+#else
+	GLint format=0;
+	int offset =0, i=0;
+	int blocksize, width, height;
+	int size;
+	GLint err;
+
+	if (ibuf->dds_data.fourcc == FOURCC_DXT1)
+		format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+	else if (ibuf->dds_data.fourcc == FOURCC_DXT3)
+		format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+	else if (ibuf->dds_data.fourcc == FOURCC_DXT5)
+		format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+	else
+	{
+		printf("Unable to find a suitable DXT compression, falling back to uncompressed\n");
+		GPU_create_gl_tex(bind, pix, x, y, mipmap, ima);
+		return;
+	}
+
+	glGenTextures(1, (GLuint *)bind);
+	glBindTexture(GL_TEXTURE_2D, *bind);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+
+	height = ibuf->x;
+	width = ibuf->y;
+	blocksize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
+	for (i=0; i<ibuf->dds_data.nummipmaps && (width||height); ++i)
+	{
+		if (width == 0)
+			width = 1;
+		if (height == 0)
+			height = 1;
+
+		size = ((width+3)/4)*((height+3)/4)*blocksize;
+
+		glCompressedTexImage2D(GL_TEXTURE_2D, i, format, width, height,
+			0, size, ibuf->dds_data.data + offset);
+
+		err = glGetError();
+
+		if (err != GL_NO_ERROR)
+			printf("OpenGL error: %s\nFormat: %x\n", gluErrorString(err), format);
+
+		offset += size;
+		width >>= 1;
+		height >>= 1;
+	}
+
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+#endif
 }
-
 static void gpu_verify_repeat(Image *ima)
 {
 	/* set either clamp or repeat in X/Y */
@@ -1791,4 +1864,3 @@
 	gpu_get_print("GL_ZOOM_X", GL_ZOOM_X);
 	gpu_get_print("GL_ZOOM_Y", GL_ZOOM_Y);
 }
-

Modified: branches/soc-2011-cucumber/source/blender/imbuf/IMB_imbuf_types.h
===================================================================
--- branches/soc-2011-cucumber/source/blender/imbuf/IMB_imbuf_types.h	2011-06-27 18:31:34 UTC (rev 37873)
+++ branches/soc-2011-cucumber/source/blender/imbuf/IMB_imbuf_types.h	2011-06-27 19:40:42 UTC (rev 37874)
@@ -53,6 +53,13 @@
 #define IB_MIPMAP_LEVELS	20
 #define IB_FILENAME_SIZE	1023
 
+typedef struct DDSData {
+	unsigned int fourcc; /* DDS fourcc info */
+	unsigned int nummipmaps; /* The number of mipmaps in the dds file */
+	unsigned char *data; /* The compressed image data */
+	unsigned int size; /* The size of the compressed data */
+} DDSData;
+
 /**
  * \ingroup imbuf
  * This is the abstraction of an image.  ImBuf is the basic type used for all
@@ -127,6 +134,9 @@
 	unsigned char *encodedbuffer;     /* Compressed image only used with png currently */
 	unsigned int   encodedsize;       /* Size of data written to encodedbuffer */
 	unsigned int   encodedbuffersize; /* Size of encodedbuffer */
+
+	/* information for compressed textures */
+	struct DDSData dds_data;
 } ImBuf;
 
 /* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */
@@ -222,9 +232,31 @@
 #define IB_PROFILE_SRGB			2
 #define IB_PROFILE_CUSTOM		3
 
+
+/* dds */
+#ifdef WITH_DDS
+#ifndef MAKEFOURCC
+#define MAKEFOURCC(ch0, ch1, ch2, ch3)\
+	((unsigned long)(unsigned char)(ch0) | \
+	((unsigned long)(unsigned char)(ch1) << 8) | \
+	((unsigned long)(unsigned char)(ch2) << 16) | \
+	((unsigned long)(unsigned char)(ch3) << 24))
+#endif //MAKEFOURCC
+
+/*
+ * FOURCC codes for DX compressed-texture pixel formats
+ */
+
+#define FOURCC_DDS   (MAKEFOURCC('D','D','S',' '))
+#define FOURCC_DXT1  (MAKEFOURCC('D','X','T','1'))
+#define FOURCC_DXT2  (MAKEFOURCC('D','X','T','2'))
+#define FOURCC_DXT3  (MAKEFOURCC('D','X','T','3'))
+#define FOURCC_DXT4  (MAKEFOURCC('D','X','T','4'))
+#define FOURCC_DXT5  (MAKEFOURCC('D','X','T','5'))
+
+#endif // DDS
 extern const char *imb_ext_image[];
 extern const char *imb_ext_image_qt[];
 extern const char *imb_ext_movie[];
 extern const char *imb_ext_audio[];
-
 #endif

Modified: branches/soc-2011-cucumber/source/blender/imbuf/intern/allocimbuf.c
===================================================================
--- branches/soc-2011-cucumber/source/blender/imbuf/intern/allocimbuf.c	2011-06-27 18:31:34 UTC (rev 37873)
+++ branches/soc-2011-cucumber/source/blender/imbuf/intern/allocimbuf.c	2011-06-27 19:40:42 UTC (rev 37874)
@@ -167,6 +167,8 @@
 			freeencodedbufferImBuf(ibuf);
 			IMB_cache_limiter_unmanage(ibuf);
 			IMB_metadata_free(ibuf);
+			if (ibuf->dds_data.data != NULL)
+				free(ibuf->dds_data.data);
 			MEM_freeN(ibuf);
 		}
 	}
@@ -511,4 +513,3 @@
 
 	return 0;
 }
-

Modified: branches/soc-2011-cucumber/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
===================================================================
--- branches/soc-2011-cucumber/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp	2011-06-27 18:31:34 UTC (rev 37873)
+++ branches/soc-2011-cucumber/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp	2011-06-27 19:40:42 UTC (rev 37874)
@@ -1,39 +1,3 @@
-/*
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list