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

📄 directmanage.cpp

📁 应用程序向导已为您创建了这个 SH 应用程序。此应用程序不仅演示 Microsoft 基础类的基本使用方法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	HRESULT	ddrval;
    m_ddsd.dwSize = sizeof(m_ddsd);
    
	while( 1 )
	{ 
		ddrval = lpSur->Lock( NULL, &m_ddsd, DDLOCK_WAIT, NULL );	//锁定
		if( ddrval == DD_OK )
		{
		    break;
		}
		if( ddrval == DDERR_SURFACELOST )
		{
		    ddrval = restoreAll();
		  	if( ddrval != DD_OK ) return( false );
		} 
	}

  	m_GraphBuffer = (WORD *)m_ddsd.lpSurface;		//内存指针
	m_GraphWidth = m_ddsd.dwWidth;					//宽度
	m_GraphHeight = m_ddsd.dwHeight;				//高度
	m_GraphPitch  = m_ddsd.lPitch >> 1;	//lPitch以Byte为单位计数的,
									//GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
    return TRUE ;
}

//******************
//关闭缓冲区
BOOL CDirectManage::EndDraw(LPDIRECTDRAWSURFACE lpSur)
{
	HRESULT	ddrval;
   	ddrval = lpSur->Unlock( NULL );				//解锁
	if( ddrval != DD_OK ) return( FALSE );
	return TRUE;
}

//--------------------------------------------------------------//
//////////////////////////////////////////////////////////////////
//--------------------------------------------------------------//

//功能:以单色填充页面
//参数:目标表面,颜色
void CDirectManage::FillSurface(LPDIRECTDRAWSURFACE surf, DWORD color)
{
	WORD color16=RGB16(color);				//转化成16色

	if( BeginDraw(surf) )
	{
	for( int i=0; i<m_GraphHeight; i++)
		for(int j=0; j<m_GraphWidth; j++)
			m_GraphBuffer[i*m_GraphPitch+j] = color16;		//直接填充
	EndDraw(surf);
	}
}

//以单色填充页面
void CDirectManage::FillSurface(LPDIRECTDRAWSURFACE surf, WORD color)
{
	if( BeginDraw(surf) )
	{
	for( int i=0; i<m_GraphHeight; i++)
		for(int j=0; j<m_GraphWidth; j++)
			m_GraphBuffer[i*m_GraphPitch+j] = color;		//直接填充
	EndDraw(surf);
	}
}
//16位RGB换算
WORD CDirectManage::RGB16(WORD r, WORD g, WORD b)
{
	//简单
	if( m_bIs555 )
		//rrrrr|ggggg|bbbbb    0xf8 = 11111000b
		return ((r&0xf8)<<7) | ((g&0xf8)<<2) | ((b&0xf8)>>3);
	else
		//rrrrr|gggggg|bbbbb    0xfc = 11111100
		return ((r&0xf8)<<8) | ((g&0xfc)<<3) | ((b&0xf8)>>3);
}

//24位转16位
WORD CDirectManage::RGB16(DWORD color)
{
	WORD r,g,b;
	//也比较简单
	r=(WORD)(color>>16);	
	g=(WORD)(color>>8);
	b=(WORD)color;

	if( m_bIs555 )
		return ((r&0xf8)<<7) | ((g&0xf8)<<2) | ((b&0xf8)>>3);
	else
		return ((r&0xf8)<<8) | ((g&0xfc)<<3) | ((b&0xf8)>>3);
}
//淡出(time=每一帧的时间)
void CDirectManage::ColorOut(LPDIRECTDRAWSURFACE dest, int time)
{
	unsigned int alpha=2, oldtick, newtick;
	WORD *lpSour, *lpDest, *lpBack;

	if( theApp.m_iWindowMode != 0 )	//窗口
	{
		Blt(m_lpDDSSour, 0,0, m_lpDDSPrimary, theApp.m_rectWindow, false);
	}
	else
	{
		Blt(m_lpDDSSour, 0,0, m_lpDDSPrimary, theApp.m_RectScreen, false);
	}

	if( BeginDraw(m_lpDDSSour) )
	{
		lpSour=m_GraphBuffer;
		EndDraw(m_lpDDSSour);
	}

	if( BeginDraw(dest) )
	{
		lpDest=m_GraphBuffer;
		EndDraw(dest);
	}

	if( BeginDraw(m_lpDDSTemp) )
	{
		lpBack=m_GraphBuffer;
		EndDraw(m_lpDDSTemp);
	}

	oldtick=timeGetTime();

	for(int i=0; i<16; i++)
	{
		for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
		{
			//看看上面的函数对比一下
			//这个是从屏幕逐渐变化到dest页面
			lpBack[j]=Alpha_Pixel(lpDest[j], lpSour[j], alpha);
		}

		//延时
		newtick=timeGetTime();
		while( newtick-oldtick < (unsigned int)(time*i) )	
		{
			newtick=timeGetTime();
		}

		//更新屏幕
		_UpdateScreen(m_lpDDSTemp,theApp.m_RectScreen);

		//自动跳桢
		i=(newtick-oldtick)/time;
		alpha=i*2+2;

		if( i >= 15 ) //结束
		{
			alpha=31;
			for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
			{
				lpBack[j]=Alpha_Pixel(lpDest[j], lpSour[j], alpha);
			}
			_UpdateScreen(m_lpDDSTemp,theApp.m_RectScreen);
			break;
		}
	}
}
//*************************
//延时
void CDirectManage::Delay(long time)
{
	static long old_clock, new_clock; //延时变量
	new_clock=old_clock=timeGetTime();

	MSG msg;
	while( new_clock < old_clock + time )
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
            if (!GetMessage(&msg, NULL, 0, 0)) return;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
		}
		else if(theApp.m_bIsActive)
		{
			new_clock=timeGetTime();
			if( GetAsyncKeyState(VK_F4) )		//F4结束
			{
				return;
			}
		}
		else WaitMessage();	//等待消息
	}
}
//功能:更新到屏幕
//参数:目标表面,更新范围
void CDirectManage::_UpdateScreen(LPDIRECTDRAWSURFACE lpSurf, RECT DestRect)
{
	if( theApp.m_iWindowMode==0 )	//全屏
	{
		Blt(m_lpDDSPrimary, 0, 0, lpSurf, DestRect, false);
	}
	else	//窗口
	{
		m_lpDDSPrimary->Blt( &theApp.m_rectWindow, lpSurf, &DestRect, DDBLTFAST_NOCOLORKEY, 0);
		
	}
}
//更新到屏幕或表面lpSurf
void CDirectManage::UpdateScreen(LPDIRECTDRAWSURFACE lpSurf, RECT DestRect)
{
	
}
//淡入(time=每一帧的时间)
void CDirectManage::ColorIn(int time, WORD Color)
{
	unsigned int alpha=2, oldtick, newtick;
	WORD *lpSurf, *lpTemp, BlackColor=Color;

	//建立临时页面
	LPDIRECTDRAWSURFACE Temp;
	CreateBitmap(Temp, theApp.m_iScreenWidth, theApp.m_iScreenHeight);
	//保存到临时页面
	if( theApp.m_iWindowMode==0 )	//全屏
		Blt(Temp, 0, 0, m_lpDDSPrimary, theApp.m_RectScreen, false);
	else
		Blt(Temp, 0, 0, m_lpDDSPrimary, theApp.m_rectWindow, false);

	if( BeginDraw(m_lpDDSBack) )
	{
		lpSurf=m_GraphBuffer;
		EndDraw(m_lpDDSBack);
	}

	if( BeginDraw(Temp) )
	{
		lpTemp=m_GraphBuffer;
		EndDraw(Temp);
	}

	oldtick=timeGetTime();	//起始时间

	for(int i=0; i<16; i++)
	{
		//把主表面的点和传近来的点进行alpha混合到lpDDSBack
		for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
		{
			lpSurf[j]=Alpha_Pixel(BlackColor, lpTemp[j], alpha);
		}

		//延时
		newtick=timeGetTime();
		while( newtick-oldtick < (unsigned int)(time * i) )
		{
			newtick=timeGetTime();
		}
		
		//更新屏幕
		_UpdateScreen(m_lpDDSBack,theApp.m_RectScreen);
		
		//自动跳桢
		i=(newtick-oldtick)/time;
		//alpha增加
		alpha=i*2+2;

		if( i >= 15 ) //结束
		{
			alpha=31;
			for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
			{
				lpSurf[j]=Alpha_Pixel(BlackColor, lpTemp[j], alpha);
			}
			_UpdateScreen(m_lpDDSBack,theApp.m_RectScreen);
			break;
		}
	}
	
	//释放
	_RELEASE( Temp );
}
//****************************
//功能:两个点的ALPHA混合(0-31)
//参数:源点,目标点,ALPHA级别
//返回:混合后的点
WORD CDirectManage::Alpha_Pixel(WORD sour, WORD dest, int alpha)
{
	//C++版 :看下面的汇编版的注释
	m_rgbTemp =  ((((sour<<16)|sour) & m_rgbMask ) * alpha +
						(((dest<<16)|dest) & m_rgbMask ) * (32-alpha) ) >> 5;
	m_rgbTemp = m_rgbTemp & m_rgbMask;
	return (WORD)((m_rgbTemp>>16)|m_rgbTemp);
	
/*
	//汇编版
	int ialpha=32-alpha;
	_asm{
		movzx eax, sour			//零扩展成32位
		mov bx, ax				//把sour放到bx中
		sal eax, 16				//算术左移16位,低位填0
		mov ax, bx				//把sour放到ax中,现在的eax中放的是两个sour
		and eax, rgbMask		//与上rgbMask
		mul alpha				//乘上alpha值
		mov esi, eax			//保存到esi
	
		movzx eax, dest			//同样的方法
		mov bx, ax
		sal eax, 16
		mov ax, bx
		and eax, rgbMask
		mul ialpha
		add eax, esi			//加上刚刚的值
		shr eax, 5				//逻辑右移5位,高位填0
		 
		//rgbTemp = rgbTemp & rgbMask;
		and eax, rgbMask		//与上rgbMask
		mov esi, eax			//放到esi中
		shr eax, 16				//逻辑右移动16位,高位填0
		or  eax, esi			//或上esi
		mov rgbTemp, eax		//返回
	}
	return (WORD)rgbTemp;
	*/
	/*--------------------------------------------------------
	多说点点,看看rgbMask的形式是什么:比如是655格式
	00000|gggggg|00000|rrrrr|000000|bbbbb
	5个0  六位的 5个0 |五位 |6个0  |五位
		  绿掩码      |红掩码      |蓝掩码

	好了,看看是个什么结果
	要是将他与一个数与的话,也只是保留grb位的数
	如果把这个数右移动16位,再与原数或,再去掉高位的话
	结果是什么呢?16位的rgb的值
	明白了就好办多了。:)
	那又是怎么做到alpha混合的呢?
	
	主要是在那个乘法上面,注意先乘了一个alpha,然后有个右移5位
	也就是除以32了。所以各个颜色成分的值算出来了也不会有越位,
	各个颜色还是对齐了的。

	然后就是上面说的那个了,还原成16位的颜色值
	----------------------------------------------------------*/
}

⌨️ 快捷键说明

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