调色板在现代图形处理中可能已经过时,但在某些特定场合,它仍然发挥着作用。本文将介绍如何将调色板与动画结合,制作出吸引眼球的效果。虽然代码简单,但可以根据个人需求进行调整,使其更加强大和实用。
在闲暇之余,编写了这段代码。非常喜欢Codeproject.com,只是遗憾发现它太晚了。
使用这段代码非常简单:
以下是类的定义:
C++
class PalAnimClass
{
public:
BOOL GetDirection();
BOOL SetType(int nType);
BOOL SetDirect(BOOL dir);
BOOL SetColor(int r, int g, int b);
BOOL SetSize(int iWidth, int iHeight);
void UpdateData(HDC hdc);
BOOL Init();
PalAnimClass();
virtual ~PalAnimClass();
private:
BOOL m_bDirection;
int m_nKind;
HBRUSH hBrush;
void DrawBackground(HDC hdc, int type);
void TimerRoutine(HPALETTE hPalette);
HPALETTE CreatePal();
RECT rt;
HPALETTE hPalette,hOldPal;
int m_nHeight;
int m_nWidth;
LOGPALETTE *plp;
int m_r,m_g,m_b;
int i,j;
};
调色板动画的原理非常简单,总共只有三个步骤:
非常简单,不是吗?让开始实现它。
以下是创建调色板的代码:
C++
HPALETTE PalAnimClass::CreatePal()
{
HPALETTE hPalette;
if (hPalette)
::DeleteObject (hPalette);
plp=(LOGPALETTE *)malloc(sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*64);
plp->palVersion = 0x300;
plp->palNumEntries = 64;
for (int i=0; i<64; i++)
{
plp->palPalEntry[i].peRed = m_r * sin(PI*i/64);
plp->palPalEntry[i].peGreen = m_g * sin(PI*i/64);
plp->palPalEntry[i].peBlue = m_b * sin(PI*i/64);
plp->palPalEntry[i].peFlags = PC_RESERVED;
}
hPalette = ::CreatePalette(plp);
return hPalette;
}
现在使用刚刚创建的调色板绘制背景。请记住使用刚刚创建的调色板中的颜色。这一步很简单,如下所示:
hBrush = CreateSolidBrush(PALETTEINDEX(min(64*sin(PI*j/64), 64*sin(PI*i/64))));
使用 PALETTEINDEX 或 PALETTERGB 来使用新调色板中的颜色。这里的正弦函数很多,这只是个数学问题。可以很好地理解它。在背景中绘制形状后,现在让去改变调色板的值。代码片段如下:
void PalAnimClass::TimerRoutine(HPALETTE hPalette)
{
PALETTEENTRY temp;
for (j=0; j<3; j++)
{
if (m_bDirection)
{
temp = plp->palPalEntry[0];
for (i=0; i<64; i++)
plp->palPalEntry[i] = plp->palPalEntry[i+1];
plp->palPalEntry[63] = temp;
}
else
{
temp = plp->palPalEntry[63];
for (i=63; i>0; i--)
plp->palPalEntry[i] = plp->palPalEntry[i-1];
plp->palPalEntry[0] = temp;
}
}
AnimatePalette(hPalette, 0, 64, plp->palPalEntry);
}
AnimatePalette 函数替换指定逻辑调色板中的条目。
应用程序可以通过调用 GetDeviceCaps 函数并指定 RASTERCAPS 常量来确定设备是否支持调色板操作。AnimatePalette 函数只更改在 LOGPALETTE 结构的 palPalEntry 成员中设置了 PC_RESERVED 标志的条目。如果给定的调色板与活动窗口关联,则调色板中的颜色会立即被替换。