⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddfade.htm

📁 关于windows游戏编程的一些文章还有相关图形
💻 HTM
📖 第 1 页 / 共 2 页
字号:
</FONT></PRE>
</BLOCKQUOTE>

<P>The first type of fade we'll implement is cross-fading, which is the basic fade directly from one image on screen to another.  
What your basically trying to do is combine the two desired images through blending.  Where during each iteration the initial 
image becomes more transparent and the final image becomes more opaque (although, transparency_initial_img + transparency_final_img = 100%).

<P>What the next function presented does is perform a cross-fade (Alpha Transition) on the two given surfaces.

<BLOCKQUOTE>
<PRE><FONT SIZE=2 COLOR=RED>
	/*
	 * AlphaTransition:
	 *    Does an alpha transition from Src -> Des
	 */
	void AlphaTransition(LPDIRECTDRAWSURFACE Src, LPDIRECTDRAWSURFACE Des)
	{	
		long i;							 // index into surfaces
		int alpha;                  // Holds current alpha value
		int dpitch, spitch, tpitch, ppitch; // surface pitch for destination, source, temp surfaces
		WORD *AlphaPTR;              // pointer to the current AlphaMap level (Source)
		WORD *InvAlphaPTR;           // the inverted pointer to the current AlphaMap level (Destination)
		WORD *src, *des, *tmp, *prm;
		WORD *fastsrc, *fastdes, *fasttmp;      // Surface memory pointer for source, destination, and temporary surfaces
		RECT SrcRect, DesRect;      // Source and destination rectangles

		// Set source and destination rectangles to the screen size
		SetRect(&SrcRect, 0, 0, 640, 480);
		SetRect(&DesRect, 0, 0, 640, 480);

		// Create the three surface we are going to use
		lpDDSTmp = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // The temporary surface
		lpDDSSrc = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // The source surface
		lpDDSDes = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // The destination surface

		// Blit the transition surfaces into out newly created source/destination surfaces
		lpDDSSrc->Blt(&DesRect, Src, &SrcRect, DDBLT_WAIT, NULL); // Blit Src->lpDDSSrc
		lpDDSDes->Blt(&DesRect, Des, &SrcRect, DDBLT_WAIT, NULL); // Blit Des->lpDDSDes

		// lock all three surfaces temporary, source, and destination
		des = DDLockSurface(lpDDSDes, &dpitch);
		src = DDLockSurface(lpDDSSrc, &spitch);
		tmp = DDLockSurface(lpDDSTmp, &tpitch);
		prm = DDLockSurface(lpDDSPrimary, &ppitch);

		// for each alpha level
		for(alpha=31;alpha>=0;alpha--)
		{
			// set AlphaMap pointers to appropriate levels
			AlphaPTR = PixelShade[alpha];
			InvAlphaPTR = PixelShade[31-alpha];

			// "reset" the *fast* pointers to the locked surfaces
			fastsrc = src;
			fastdes = des;
			fasttmp = tmp;

			// loop through every pixel
			for(i=0;i&lt;307200;i++,fasttmp++,fastsrc++,fastdes++)
			{
				// Set the new pixel value in temporary surface
				*fasttmp = AlphaPTR[*fastsrc] + InvAlphaPTR[*fastdes];
			}
			
			// copy the temp surface to the primary surface
			// (640*480) = 307200 (words) * 2 = 614400 (bytes)
			memcpy(prm, tmp, 614400);
		}
		
		// Unlock our temporary, source, and destination surfaces
		DDUnlockSurface(lpDDSPrimary);
		DDUnlockSurface(lpDDSTmp);
		DDUnlockSurface(lpDDSDes);
		DDUnlockSurface(lpDDSSrc);

		// Release our temporary, source, and destination surfaces
		lpDDSTmp->Release();
		lpDDSTmp = NULL;
		lpDDSSrc->Release();
		lpDDSSrc = NULL;
		lpDDSDes->Release();
		lpDDSDes = NULL;
	}
</FONT></PRE>
</BLOCKQUOTE>

<P>Ok, the next fade we are going to want to perform is a fade from black to a surface.  Since all three fading methods use 
the same basic algorithm, and given the fact that <i>PixelShade[0]</i> would be black for any color, in each iteration we're 
simply going to fill the screen with that level pixel color until we hit <i>PixelShade[31]</i> which will be the desired image 
at full color.

<P>Here's the code:

<BLOCKQUOTE>
<PRE><FONT SIZE=2 COLOR=RED>
	/*
	 * FadeToSurface:
	 *    Fades into a surface from black
	 */
	void FadeToSurface(LPDIRECTDRAWSURFACE lpDDS)
	{
		int c;                 // counter variable
		long i;                // incrementing variable
		WORD *tmp, *ref, *prm;
		WORD *fasttmp, *fastref;       // temporary and destination surface mem pointers
		RECT SrcRect, DesRect; // Source and destination rectangles
		int tpitch, rpitch, ppitch;    // temporary and destination surface pitch
		WORD *shade;
	
		// Set the source and destination rectangles to the size of the screen
		SetRect(&SrcRect, 0, 0, 640, 480);
		SetRect(&DesRect, 0, 0, 640, 480);

		// Create the surfaces
		lpDDSTmp = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // the temporary surface
		lpDDSRef = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // the temporary surface
		lpDDSRef->Blt(&DesRect, lpDDS, &SrcRect, DDBLT_WAIT, NULL); // blit the desired surface into our destination surface

		// Lock our surfaces temporary, and destination
		tmp = DDLockSurface(lpDDSTmp, &tpitch);
		prm = DDLockSurface(lpDDSPrimary, &ppitch);
		ref = DDLockSurface(lpDDSRef, &rpitch);

		// This can be changed, but it worx out nice to do 10 iterations
		for(c=1;c&lt;=30;c++)
		{
			// get pointer indexed to the start of the current shade level
			shade = PixelShade[c];

			// "reset" our *fast* surface pointers
			fasttmp = tmp;
			fastref = ref;

			// for every pixel on the screen (640*480=307200)
			for(i=0;i&lt;307200;i++,fasttmp++,fastref++)
			{
				// new pixel please.....
				*fasttmp = shade[*fastref];
			}

			// copy the temp surface to the primary surface
			// (640*480) = 307200 (words) * 2 = 614400 (bytes)
	   		systovid_memcpy(prm, tmp, 614400);
		}

		// unlock the temporary surface and destination surface
		DDUnlockSurface(lpDDSTmp);
		DDUnlockSurface(lpDDSPrimary);
		DDUnlockSurface(lpDDSRef);

		// blit the actual destination surface to the primary surface so we're sure
		// the screen is where it should be
		lpDDSPrimary->Blt(&DesRect, lpDDS, &SrcRect, DDBLT_WAIT, NULL);

		// release the temporary and destination surfaces
		lpDDSTmp->Release();
		lpDDSTmp = NULL;
		lpDDSRef->Release();
		lpDDSRef = NULL;
	}
</FONT></PRE>
</BLOCKQUOTE>

<P>And the final fade we're going to perform is the classic fade to black.  What we want is to have a desired initial image 
already on the screen and simply do the opposite of what we did with the <i>FadeToSurface()</i>, starting with <i>PixelShade[31]</i> 
and ending with <i>PixelShade[0]</i>.

<p>Again, here's the implementation:

<BLOCKQUOTE>
<PRE><FONT SIZE=2 COLOR=RED>
	/*
	 * FadeToBlack:
	 *		Fades a screen to black
	 */
	void FadeToBlack(void)
	{
		RECT SrcRect, DesRect; // Source and Destination Rectangles
		WORD *tmp;             // temporary surface memory pointer
		WORD *ref;
		WORD *prm;
		WORD *fastref, *fasttmp;
		int c, tpitch, rpitch, ppitch;         // incrementing variable, temporary surface pitch
		long i;                // another incrementing variable
		WORD *shade;

		// Set source and destination rectangles to size of screen
		SetRect(&SrcRect, 0, 0, 640, 480);
		SetRect(&DesRect, 0, 0, 640, 480);

		// Create our temporary surface
		lpDDSTmp = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY);
		lpDDSRef = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY);

		// Blit our primary surface into our temporary SYSTEM MEMORY surface
		lpDDSRef->Blt(&DesRect, lpDDSPrimary, &SrcRect, DDBLT_WAIT, NULL);

		// Lock our temporary surface
		tmp = DDLockSurface(lpDDSTmp, &tpitch);
		ref = DDLockSurface(lpDDSRef, &rpitch);
		prm = DDLockSurface(lpDDSPrimary, &ppitch);

		for(c=30;c>=1;c--)
		{
			// get a pointer indexed to the start of the current shade level
			shade = PixelShade[c];

			// "reset" our *fast* surface pointers
			fastref = ref;
			fasttmp = tmp;

			// for every pixel on the screen (640*480=307200)
			for(i=0;i&lt;307200;i++,fasttmp++,fastref++)
			{
				// new pixel please....
				*fasttmp = shade[*fastref];
			}

			// copy the temp surface to the primary surface
			// (640*480) = 307200 (words) * 2 = 614400 (bytes)
	   		systovid_memcpy(prm, tmp, 614400);
		}

		// unlock our temporary surface
		DDUnlockSurface(lpDDSTmp);
		DDUnlockSurface(lpDDSRef);
		DDUnlockSurface(lpDDSPrimary);

		// just to make sure the screen is black when this routine is over, fill it with 0
		DDFillSurface(lpDDSPrimary,0);

		// release our temporary surface
		lpDDSTmp->Release();
		lpDDSTmp = NULL;
		lpDDSRef->Release();
		lpDDSRef = NULL;
	}
</FONT></PRE>
</BLOCKQUOTE>

<P>Before I offer the download to the demo application, just a couple things to keep in mind.  It's obvious that you should 
never attempt to do pixel manipulations directly on the primary (Video Memory) surface.  That's the reason for the creation of 
system memory surfaces and then the copying of the working surfaces into them in each of the three functions.  After that, you 
can do all the pixel manipulations you want and then blast it into the primary surface with a memcpy.  The functions also attempt 
to minimize surface locking, another potential slowdown.  But, as always, nothing is every "optimized" as new ways to speed 
things up can always be found...

<H4 ALIGN=CENTER>Download: <A HREF="ddfade.zip">ddfade.zip (Executable, Source C++)</A></H4>

<!--Bottom Navigation-->
<A NAME="bottom"></A>
<!--End Bottom Navigation-->
</STRONG>
</FONT>
<!--End Body-->
<!--Bottom-->
<BR>
<IMG SRC="gradbar.jpg">
<BR>
<FONT SIZE=2 COLOR=#8B8B8B FACE=Helvetica>
<I><font color="#FBFBFB">T</font><font color="#F7F7F7">h</font><font color="#F3F3F3">e</font><font color="#EFEFEF"> </font><font color="#EBEBEB">G</font><font color="#E7E7E7">a</font><font color="#E3E3E3">m</font><font color="#DFDFDF">e</font><font color="#DBDBDB"> </font><font color="#D7D7D7">P</font><font color="#D3D3D3">r</font><font color="#CFCFCF">o</font><font color="#CBCBCB">g</font><font color="#C7C7C7">r</font><font color="#C3C3C3">a</font><font color="#BFBFBF">m</font><font color="#BBBBBB">m</font><font color="#B7B7B7">i</font><font color="#B3B3B3">n</font><font color="#AFAFAF">g</font><font color="#ABABAB"> </font><font color="#A7A7A7">M</font><font color="#A3A3A3">e</font><font color="#9F9F9F">g</font><font color="#9B9B9B">a</font><font color="#979797">S</font><font color="#939393">i</font><font color="#8F8F8F">t</font><font color="#8B8B8B">e</font> - 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -