Implements the triangle case in GdiGradientFill

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Now GdiGradientFill should be complete.

a+

Max

ChangeLog:
  * adds the GRADIENT_FILL_TRIANGLE case in GdiGradientFill

-- 
Maxime Bellengà <maxime.bellenge@laposte.net>
Index: wine/graphics/painting.c
===================================================================
RCS file: /home/wine/wine/graphics/painting.c,v
retrieving revision 1.55
diff -u -r1.55 painting.c
--- wine/graphics/painting.c	7 Apr 2003 23:21:03 -0000	1.55
+++ wine/graphics/painting.c	10 Apr 2003 20:57:01 -0000
@@ -1072,10 +1072,18 @@
 BOOL WINAPI GdiGradientFill( HDC hdc, TRIVERTEX *vert_array, ULONG nvert,
                           void * grad_array, ULONG ngrad, ULONG mode )
 {
-  int i,j,y,x;
+  int i,j,y,x,t;
   GRADIENT_RECT *rect;
+  GRADIENT_TRIANGLE *triangle;
   double ired,igreen,iblue;
   double red, green,blue;
+  double dx1,dx2,dx3;
+  double dr1,dr2,dr3;
+  double dg1,dg2,dg3;
+  double db1,db2,db3;
+  double sx,sy,sr,sg,sb;
+  double ex,ey,er,eb,eg;
+  double px,py,pr,pb,pg;
 
   TRACE("vert_array:0x%08lx nvert:%ld grad_array:0x%08lx ngrad:%ld\n",(long)vert_array,nvert,(long)grad_array,ngrad);
 
@@ -1128,7 +1136,128 @@
     }
     break;
   case GRADIENT_FILL_TRIANGLE:
-    FIXME("GRADIENT_FILL_TRIANGLE stub\n");
+    // Based on gouraud shading
+    // Do it for each triangle
+    for(i=0;i<ngrad;i++) {
+      triangle = (GRADIENT_TRIANGLE*)((long)grad_array+i*sizeof(GRADIENT_TRIANGLE));      
+      // Sort the points 
+      if (vert_array[triangle->Vertex1].y>vert_array[triangle->Vertex2].y) {
+	// swap 1 and 2
+	t = triangle->Vertex2;
+	triangle->Vertex2 = triangle->Vertex1;
+	triangle->Vertex1 = t;
+      }
+      if (vert_array[triangle->Vertex2].y>vert_array[triangle->Vertex3].y) {
+	// swap 2 and 3
+	t = triangle->Vertex3;
+	triangle->Vertex3 = triangle->Vertex2;
+	triangle->Vertex2 = t;
+      }
+      if (vert_array[triangle->Vertex1].y>vert_array[triangle->Vertex2].y) {
+	// swap 1 and 2
+	t = triangle->Vertex2;
+	triangle->Vertex2 = triangle->Vertex1;
+	triangle->Vertex1 = t;
+      }
+      // precompute some interpolation stuffs
+      if (vert_array[triangle->Vertex2].y>vert_array[triangle->Vertex1].y) {
+	dx1 = (double)(vert_array[triangle->Vertex2].x - vert_array[triangle->Vertex1].x) / (double)(vert_array[triangle->Vertex2].y - vert_array[triangle->Vertex1].y );
+	dr1 = (double)(vert_array[triangle->Vertex2].Red - vert_array[triangle->Vertex1].Red) / (double)(vert_array[triangle->Vertex2].y - vert_array[triangle->Vertex1].y );
+	dg1 = (double)(vert_array[triangle->Vertex2].Green - vert_array[triangle->Vertex1].Green) / (double)(vert_array[triangle->Vertex2].y - vert_array[triangle->Vertex1].y );
+	db1 = (double)(vert_array[triangle->Vertex2].Blue - vert_array[triangle->Vertex1].Blue) / (double)(vert_array[triangle->Vertex2].y - vert_array[triangle->Vertex1].y );
+      } else
+	dx1=dr1=dg1=db1=0;
+      
+      if (vert_array[triangle->Vertex3].y>vert_array[triangle->Vertex1].y) {
+	dx2 = (double)(vert_array[triangle->Vertex3].x - vert_array[triangle->Vertex1].x) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex1].y );
+	dr2 = (double)(vert_array[triangle->Vertex3].Red - vert_array[triangle->Vertex1].Red) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex1].y );
+	dg2 = (double)(vert_array[triangle->Vertex3].Green - vert_array[triangle->Vertex1].Green) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex1].y );
+	db2 = (double)(vert_array[triangle->Vertex3].Blue - vert_array[triangle->Vertex1].Blue) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex1].y );
+      } else
+	dx2=dr2=dg2=db2=0;
+
+      if (vert_array[triangle->Vertex3].y>vert_array[triangle->Vertex2].y) {
+	dx3 = (double)(vert_array[triangle->Vertex3].x - vert_array[triangle->Vertex2].x) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex2].y );
+	dr3 = (double)(vert_array[triangle->Vertex3].Red - vert_array[triangle->Vertex2].Red) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex2].y );
+	dg3 = (double)(vert_array[triangle->Vertex3].Green - vert_array[triangle->Vertex2].Green) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex2].y );
+	db3 = (double)(vert_array[triangle->Vertex3].Blue - vert_array[triangle->Vertex2].Blue) / (double)(vert_array[triangle->Vertex3].y - vert_array[triangle->Vertex2].y );
+      } else
+	dx3=dr3=dg3=db3=0;
+
+      // backup the topmost point
+      sx=vert_array[triangle->Vertex1].x;sy=vert_array[triangle->Vertex1].y;
+      sr=vert_array[triangle->Vertex1].Red;sg=vert_array[triangle->Vertex1].Green;sb=vert_array[triangle->Vertex1].Blue;
+      ex=sx;ey=sy;er=sr;eg=sg;eb=sb;
+
+      if (dx1 > dx2) {
+	for (;sy<vert_array[triangle->Vertex2].y;sy++,ey++) {
+	  if ((ex-sx)>0) {
+	    ired = (double)(er - sr) / (double)(ex - sx);
+	    igreen = (double)(eg - sg) / (double)(ex - sx);
+	    iblue = (double)(eb - sb) / (double)(ex - sx);
+	  } else
+	    ired=igreen=iblue=0;
+	  px=sx;py=sy;pr=sr;pg=sg;pb=sb;
+	  for(;px<ex;px++) {
+	    SetPixel(hdc,px,py,RGB((int)pr>>8,(int)pg>>8,(int)pb>>8));
+	    pr += ired; pg += igreen; pb += iblue;
+	  }
+	  sx+=dx2;sr+=dr2;sg+=dg2;sb+=db2;
+	  ex+=dx1;er+=dr1;eg+=dg1;eb+=db1;
+	}
+	ex=vert_array[triangle->Vertex2].x;ey=vert_array[triangle->Vertex2].y;
+	er=vert_array[triangle->Vertex2].Red;eg=vert_array[triangle->Vertex2].Green;eb=vert_array[triangle->Vertex2].Blue;
+	for (;sy<=vert_array[triangle->Vertex3].y;sy++,ey++) {
+	  if ((ex-sx)>0) {
+	    ired = (double)(er - sr) / (double)(ex - sx);
+	    igreen = (double)(eg - sg) / (double)(ex - sx);
+	    iblue = (double)(eb - sb) / (double)(ex - sx);
+	  } else
+	    ired=igreen=iblue=0;
+	  px=sx;py=sy;pr=sr;pg=sg;pb=sb;
+	  for(;px<ex;px++) {
+	    SetPixel(hdc,px,py,RGB((int)pr>>8,(int)pg>>8,(int)pb>>8));
+	    pr += ired; pg += igreen; pb += iblue;
+	  }
+	  sx+=dx2;sr+=dr2;sg+=dg2;sb+=db2;
+	  ex+=dx3;er+=dr3;eg+=dg3;eb+=db3;
+	}      
+      } else {
+	for (;sy<vert_array[triangle->Vertex2].y;sy++,ey++) {
+	  if ((ex-sx)>0) {
+	    ired = (double)(er - sr) / (double)(ex - sx);
+	    igreen = (double)(eg - sg) / (double)(ex - sx);
+	    iblue = (double)(eb - sb) / (double)(ex - sx);
+	  } else
+	    ired=igreen=iblue=0;
+	  px=ex;py=ey;pr=er;pg=eg;pb=eb;
+	  for(;px<ex;px++) {
+	    SetPixel(hdc,px,py,RGB((int)pr>>8,(int)pg>>8,(int)pb>>8));
+	    pr += ired; pg += igreen; pb += iblue;
+	  }
+	  sx+=dx1;sr+=dr1;sg+=dg1;sb+=db1;
+	  ex+=dx2;er+=dr2;eg+=dg2;eb+=db2;
+	}
+	sx=vert_array[triangle->Vertex2].x;sy=vert_array[triangle->Vertex2].y;
+	sr=vert_array[triangle->Vertex2].Red;sg=vert_array[triangle->Vertex2].Green;sb=vert_array[triangle->Vertex2].Blue;
+	for (;sy<=vert_array[triangle->Vertex3].y;sy++,ey++) {
+	  if ((ex-sx)<0) {
+	    ired = (double)(er - sr) / (double)(ex - sx);
+	    igreen = (double)(eg - sg) / (double)(ex - sx);
+	    iblue = (double)(eb - sb) / (double)(ex - sx);
+	  } else
+	    ired=igreen=iblue=0;
+	  px=ex;py=ey;pr=er;pg=eg;pb=eb;
+	  for(;px<sx;px++) {
+	    SetPixel(hdc,px,py,RGB((int)pr>>8,(int)pg>>8,(int)pb>>8));
+	    pr += ired; pg += igreen; pb += iblue;
+	  }
+	  sx+=dx3;sr+=dr3;sg+=dg3;sb+=db3;
+	  ex+=dx2;er+=dr2;eg+=dg2;eb+=db2;
+	}
+      }
+    }
+    break;
   default:
     return FALSE;
   }

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux