[Scummvm-cvs-logs] SF.net SVN: scummvm: [33042] residual/trunk/engine

aquadran at users.sourceforge.net aquadran at users.sourceforge.net
Sun Jul 13 23:03:12 CEST 2008


Revision: 33042
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33042&view=rev
Author:   aquadran
Date:     2008-07-13 14:03:12 -0700 (Sun, 13 Jul 2008)

Log Message:
-----------
implement alpha channel for tinygl renderer

Modified Paths:
--------------
    residual/trunk/engine/backend/sdl/driver_tinygl.cpp
    residual/trunk/engine/tinygl/image_util.cpp
    residual/trunk/engine/tinygl/texture.cpp
    residual/trunk/engine/tinygl/zgl.h
    residual/trunk/engine/tinygl/ztriangle.cpp

Modified: residual/trunk/engine/backend/sdl/driver_tinygl.cpp
===================================================================
--- residual/trunk/engine/backend/sdl/driver_tinygl.cpp	2008-07-13 20:41:39 UTC (rev 33041)
+++ residual/trunk/engine/backend/sdl/driver_tinygl.cpp	2008-07-13 21:03:12 UTC (rev 33042)
@@ -523,11 +523,12 @@
 			for (int x = 0; x < material->_width; x++) {
 				int col = *(uint8 *)(data);
 				if (col == 0)
-					memset(texdatapos, 0, 3); // transparent
+					memset(texdatapos, 0, 4); // transparent
 				else {
 					memcpy(texdatapos, cmap->_colors + 3 * (*(uint8 *)(data)), 3);
+					texdatapos[3] = '\xff'; // fully opaque
 				}
-				texdatapos += 3;
+				texdatapos += 4;
 				data++;
 			}
 		}
@@ -537,7 +538,7 @@
 		tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_REPEAT);
 		tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
 		tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
-		tglTexImage2D(TGL_TEXTURE_2D, 0, 3, material->_width, material->_height, 0, TGL_RGB, TGL_UNSIGNED_BYTE, texdata);
+		tglTexImage2D(TGL_TEXTURE_2D, 0, 3, material->_width, material->_height, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, texdata);
 		data += 24;
 	}
 	delete[] texdata;

Modified: residual/trunk/engine/tinygl/image_util.cpp
===================================================================
--- residual/trunk/engine/tinygl/image_util.cpp	2008-07-13 20:41:39 UTC (rev 33041)
+++ residual/trunk/engine/tinygl/image_util.cpp	2008-07-13 21:03:12 UTC (rev 33042)
@@ -3,16 +3,19 @@
 
 // image conversion
 
-void gl_convertRGB_to_5R6G5B(unsigned short *pixmap, unsigned char *rgb,
-                             int xsize, int ysize) {
+void gl_convertRGB_to_5R6G5B8A(unsigned short *pixmap, unsigned char *rgba, int xsize, int ysize) {
 	int i, n;
-	unsigned char *p;
+	unsigned char *p, *p2;
 
-	p = rgb;
+	p = rgba;
 	n = xsize * ysize;
+	p2 = (unsigned char *)pixmap;
 	for (i = 0; i < n; i++) {
-		pixmap[i] = ((p[0] & 0xF8) << 8) | ((p[1] & 0xFC) << 3) | ((p[2] & 0xF8) >> 3); 
-		p += 3;
+		unsigned short pixel = ((p[0] & 0xF8) << 8) | ((p[1] & 0xFC) << 3) | ((p[2] & 0xF8) >> 3);
+		p2[3 * i + 1] = pixel >> 8;
+		p2[3 * i + 0] = pixel & 0xff;
+		p2[3 * i + 2] = p[3];
+		p += 4;
 	}
 }
 
@@ -30,6 +33,7 @@
 void gl_resizeImage(unsigned char *dest, int xsize_dest, int ysize_dest,
                     unsigned char *src, int xsize_src, int ysize_src) {
 	unsigned char *pix, *pix_src;
+	int point1_offset, point2_offset, point3_offset;
 	float x1, y1, x1inc, y1inc;
 	int xi, yi, j, xf, yf, x, y;
 
@@ -50,22 +54,47 @@
 
 			if ((xf + yf) <= INTERP_NORM) {
 				for (j = 0; j < 3; j++) {
-					pix[j] = interpolate(pix_src[(yi * xsize_src + xi) * 3 + j],
-								pix_src[(yi * xsize_src + xi + 1) * 3 + j],
-								pix_src[((yi + 1) * xsize_src + xi) * 3 + j],
-								xf, yf);
+					point1_offset = (yi * xsize_src + xi) * 4 + j;
+					if ((xi + 1) < xsize_src)
+						point2_offset = (yi * xsize_src + xi + 1) * 4 + j;
+					else
+						point2_offset = point1_offset;
+					if ((yi + 1) < ysize_src)
+						point3_offset = ((yi + 1) * xsize_src + xi) * 4 + j;
+					else
+						point3_offset = point1_offset;
+					pix[j] = interpolate(pix_src[point1_offset], pix_src[point2_offset], pix_src[point3_offset], xf, yf);
 				}
+				pix[3] = pix_src[(yi * xsize_src + xi) * 4 + 3];
 			} else {
-					xf = INTERP_NORM - xf;
-					yf = INTERP_NORM - yf;
-					for (j = 0; j < 3; j++) {
-						pix[j] = interpolate(pix_src[((yi + 1) * xsize_src + xi + 1) * 3 + j],
-						pix_src[((yi + 1) * xsize_src + xi) * 3 + j],
-						pix_src[(yi * xsize_src + xi + 1) * 3 + j],
-						xf, yf);
+				xf = INTERP_NORM - xf;
+				yf = INTERP_NORM - yf;
+				for (j = 0; j < 3; j++) {
+					pix[j] = interpolate(pix_src[point1_offset], pix_src[point2_offset], pix_src[point3_offset], xf, yf);
+					if ((xi + 1) < xsize_src) {
+						if ((yi + 1) < ysize_src)
+							point1_offset = ((yi + 1) * xsize_src + xi + 1) * 4 + j;
+						else
+							point1_offset = (yi * xsize_src + xi + 1) * 4 + j;
+					} else {
+						if ((yi + 1) < ysize_src)
+							point1_offset = ((yi + 1) * xsize_src + xi) * 4 + j;
+						else
+							point1_offset = (yi * xsize_src + xi) * 4 + j;
 					}
+					if ((yi + 1) < ysize_src)
+						point2_offset = ((yi + 1) * xsize_src + xi) * 4 + j;
+					else
+						point2_offset = (yi * xsize_src + xi) * 4 + j;
+					if ((xi + 1) < xsize_src)
+						point3_offset = (yi * xsize_src + xi + 1) * 4 + j;
+					else
+						point3_offset = (yi * xsize_src + xi) * 4 + j;
+					pix[j] = interpolate(pix_src[point1_offset], pix_src[point2_offset], pix_src[point3_offset], xf, yf);
+				}
+				pix[3] = pix_src[(yi * xsize_src + xi) * 4 + 3];
 			}
-			pix += 3;
+			pix += 4;
 			x1 += x1inc;
 		}
 		y1 += y1inc;
@@ -93,13 +122,14 @@
 		for (x = 0; x < xsize_dest; x++) {
 			xi = x1 >> FRAC_BITS;
 			yi = y1 >> FRAC_BITS;
-			pix1 = pix_src + (yi * xsize_src + xi) * 3;
+			pix1 = pix_src + (yi * xsize_src + xi) * 4;
 
 			pix[0] = pix1[0];
 			pix[1] = pix1[1];
 			pix[2] = pix1[2];
+			pix[3] = pix1[3];
 
-			pix += 3;
+			pix += 4;
 			x1 += x1inc;
 		}
 		y1 += y1inc;

Modified: residual/trunk/engine/tinygl/texture.cpp
===================================================================
--- residual/trunk/engine/tinygl/texture.cpp	2008-07-13 20:41:39 UTC (rev 33041)
+++ residual/trunk/engine/tinygl/texture.cpp	2008-07-13 21:03:12 UTC (rev 33042)
@@ -120,50 +120,50 @@
   c->current_texture=t;
 }
 
-void glopTexImage2D(GLContext *c,TGLParam *p)
-{
-  int target=p[1].i;
-  int level=p[2].i;
-  int components=p[3].i;
-  int width=p[4].i;
-  int height=p[5].i;
-  int border=p[6].i;
-  int format=p[7].i;
-  int type=p[8].i;
-  void *pixels=p[9].p;
-  GLImage *im;
-  unsigned char *pixels1;
-  int do_free;
+void glopTexImage2D(GLContext *c, TGLParam *p) {
+	int target = p[1].i;
+	int level = p[2].i;
+	int components = p[3].i;
+	int width = p[4].i;
+	int height = p[5].i;
+	int border = p[6].i;
+	int format = p[7].i;
+	int type = p[8].i;
+	void *pixels = p[9].p;
+	GLImage *im;
+	unsigned char *pixels1;
+	int do_free;
 
-  if (!(target == TGL_TEXTURE_2D && level == 0 && components == 3 && 
-        border == 0 && format == TGL_RGB &&
-        type == TGL_UNSIGNED_BYTE)) {
-    gl_fatal_error("glTexImage2D: combinaison of parameters not handled");
-  }
+	if (!(target == TGL_TEXTURE_2D && level == 0 && components == 3 && 
+			border == 0 && format == TGL_RGBA &&
+			type == TGL_UNSIGNED_BYTE)) {
+		gl_fatal_error("glTexImage2D: combination of parameters not handled");
+	}
   
-  do_free=0;
-  if (width != 256 || height != 256) {
-    pixels1 = (unsigned char *)gl_malloc(256 * 256 * 3);
-    /* no interpolation is done here to respect the original image aliasing ! */
-    //gl_resizeImageNoInterpolate(pixels1,256,256,(unsigned char *)pixels,width,height);
-    // used interpolation anyway, it look much better :) --- aquadran
-	gl_resizeImage(pixels1,256,256,(unsigned char *)pixels,width,height);
-    do_free=1;
-    width=256;
-    height=256;
+	do_free = 0;
+	if (width != 256 || height != 256) {
+		pixels1 = (unsigned char *)gl_malloc(256 * 256 * 4);
+		// no interpolation is done here to respect the original image aliasing !
+		//gl_resizeImageNoInterpolate(pixels1, 256, 256, (unsigned char *)pixels, width, height);
+		// used interpolation anyway, it look much better :) --- aquadran
+		gl_resizeImage(pixels1, 256, 256, (unsigned char *)pixels, width, height);
+		do_free = 1;
+		width = 256;
+		height = 256;
   } else {
-    pixels1=(unsigned char *)pixels;
+		pixels1 = (unsigned char *)pixels;
   }
 
-  im=&c->current_texture->images[level];
-  im->xsize=width;
-  im->ysize=height;
-  if (im->pixmap!=NULL) gl_free(im->pixmap);
-  im->pixmap=gl_malloc(width*height*2);
-  if(im->pixmap) {
-      gl_convertRGB_to_5R6G5B((unsigned short *)im->pixmap,pixels1,width,height);
-  }
-  if (do_free) gl_free(pixels1);
+  im = &c->current_texture->images[level];
+  im->xsize = width;
+  im->ysize = height;
+  if (im->pixmap)
+	  gl_free(im->pixmap);
+  im->pixmap = gl_malloc(width * height * 3);
+  if (im->pixmap)
+		gl_convertRGB_to_5R6G5B8A((unsigned short *)im->pixmap, pixels1, width, height);
+  if (do_free)
+		gl_free(pixels1);
 }
 
 

Modified: residual/trunk/engine/tinygl/zgl.h
===================================================================
--- residual/trunk/engine/tinygl/zgl.h	2008-07-13 20:41:39 UTC (rev 33041)
+++ residual/trunk/engine/tinygl/zgl.h	2008-07-13 21:03:12 UTC (rev 33042)
@@ -313,8 +313,7 @@
 GLTexture *alloc_texture(GLContext *c,int h);
 
 // image_util.c
-void gl_convertRGB_to_5R6G5B(unsigned short *pixmap, unsigned char *rgb,
-                             int xsize, int ysize);
+void gl_convertRGB_to_5R6G5B8A(unsigned short *pixmap, unsigned char *rgba, int xsize, int ysize);
 void gl_resizeImage(unsigned char *dest, int xsize_dest, int ysize_dest,
                     unsigned char *src, int xsize_src, int ysize_src);
 void gl_resizeImageNoInterpolate(unsigned char *dest, int xsize_dest, int ysize_dest,

Modified: residual/trunk/engine/tinygl/ztriangle.cpp
===================================================================
--- residual/trunk/engine/tinygl/ztriangle.cpp	2008-07-13 20:41:39 UTC (rev 33041)
+++ residual/trunk/engine/tinygl/ztriangle.cpp	2008-07-13 21:03:12 UTC (rev 33042)
@@ -371,22 +371,25 @@
 					for (int _a = 0; _a < 8; _a++) {
 						zz = z >> ZB_POINT_Z_FRAC_BITS;
 						if ((ZCMP(zz, pz[_a])) && (ZCMP(z, pz_2[_a]))) {
-							tmp = rgb & 0xF81F07E0;
-							unsigned int light = tmp | (tmp >> 16);
-							PIXEL pixel = *(PIXEL *)((char *)texture +
-									(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));
-							unsigned int c_r = (pixel & 0xF800) >> 8;
-							unsigned int c_g = (pixel & 0x07E0) >> 3;
-							unsigned int c_b = (pixel & 0x001F) << 3;
-							unsigned int l_r = (light & 0xF800) >> 8;
-							unsigned int l_g = (light & 0x07E0) >> 3;
-							unsigned int l_b = (light & 0x001F) << 3;
-							c_r = (c_r * l_r) / 256;
-							c_g = (c_g * l_g) / 256;
-							c_b = (c_b * l_b) / 256;
-							pixel = ((c_r & 0xF8) << 8) | ((c_g & 0xFC) << 3) | (c_b >> 3);
-							pp[_a] = pixel;
-							pz_2[_a] = z;
+							char *ptr = (char *)(texture) + (((((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)) >> 1) * 3);
+							PIXEL pixel = *(PIXEL *)ptr;
+							char alpha = *(ptr + 2);
+							if (alpha == '\xff') {
+								tmp = rgb & 0xF81F07E0;
+								unsigned int light = tmp | (tmp >> 16);
+								unsigned int c_r = (pixel & 0xF800) >> 8;
+								unsigned int c_g = (pixel & 0x07E0) >> 3;
+								unsigned int c_b = (pixel & 0x001F) << 3;
+								unsigned int l_r = (light & 0xF800) >> 8;
+								unsigned int l_g = (light & 0x07E0) >> 3;
+								unsigned int l_b = (light & 0x001F) << 3;
+								c_r = (c_r * l_r) / 256;
+								c_g = (c_g * l_g) / 256;
+								c_b = (c_b * l_b) / 256;
+								pixel = ((c_r & 0xF8) << 8) | ((c_g & 0xFC) << 3) | (c_b >> 3);
+								pp[_a] = pixel;
+								pz_2[_a] = z;
+							}
 						}
 						z += dzdx;
 						s += dsdx;
@@ -416,22 +419,25 @@
 					{
 						zz = z >> ZB_POINT_Z_FRAC_BITS;
 						if ((ZCMP(zz, pz[0])) && (ZCMP(z, pz_2[0]))) {
-							tmp = rgb & 0xF81F07E0;
-							unsigned int light = tmp | (tmp >> 16);
-							PIXEL pixel = *(PIXEL *)((char *)texture +
-									(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));
-							unsigned int c_r = (pixel & 0xF800) >> 8;
-							unsigned int c_g = (pixel & 0x07E0) >> 3;
-							unsigned int c_b = (pixel & 0x001F) << 3;
-							unsigned int l_r = (light & 0xF800) >> 8;
-							unsigned int l_g = (light & 0x07E0) >> 3;
-							unsigned int l_b = (light & 0x001F) << 3;
-							c_r = (c_r * l_r) / 256;
-							c_g = (c_g * l_g) / 256;
-							c_b = (c_b * l_b) / 256;
-							pixel = ((c_r & 0xF8) << 8) | ((c_g & 0xFC) << 3) | (c_b >> 3);
-							pp[0] = pixel;
-							pz_2[0] = z;
+							char *ptr = (char *)(texture) + (((((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)) >> 1) * 3);
+							PIXEL pixel = *(PIXEL *)ptr;
+							char alpha = *(ptr + 2);
+							if (alpha == '\xff') {
+								tmp = rgb & 0xF81F07E0;
+								unsigned int light = tmp | (tmp >> 16);
+								unsigned int c_r = (pixel & 0xF800) >> 8;
+								unsigned int c_g = (pixel & 0x07E0) >> 3;
+								unsigned int c_b = (pixel & 0x001F) << 3;
+								unsigned int l_r = (light & 0xF800) >> 8;
+								unsigned int l_g = (light & 0x07E0) >> 3;
+								unsigned int l_b = (light & 0x001F) << 3;
+								c_r = (c_r * l_r) / 256;
+								c_g = (c_g * l_g) / 256;
+								c_b = (c_b * l_b) / 256;
+								pixel = ((c_r & 0xF8) << 8) | ((c_g & 0xFC) << 3) | (c_b >> 3);
+								pp[0] = pixel;
+								pz_2[0] = z;
+							}
 						}
 						z += dzdx;
 						s += dsdx;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list