2007年4月14日土曜日

SetBitmapBitsを使った

CreateCompatibleBitmapとSetBitmapBitsを使ってメモリ上に表示イメージを作成して表示デバイスにbltするようにしてみた。ものすごく遅い...なんか嫌になってきた

StretchBltを使わないように拡大縮小も自前で用意してみたつもりなんだけど余計遅くなっただけかも。

src_buf -> m_buf -> m_hbmp > hdc
と転送が繰り返されているように思う

src_buf -> m_buf -> hdc
ぐらいにしたい


bool CPicture::Draw(HDC hdc, RECT rc, int frame)
{
int w = rc.right - rc.left;
int h = rc.bottom - rc.top;

// 表示用のバッファ領域を作成する
if(m_hBmp == NULL)
{
m_hBmp = CreateCompatibleBitmap(hdc,w,h);

m_WidthByte = (w*2+1)&0xfffffffe;
m_buf = (LPBYTE) new WORD[m_WidthByte*h];
}

// イメージ内の表示領域を取得する
KEY src = GetValue(frame);

int srcX = src.sx;
int srcY = src.sy;
int srceX = src.ex;
int srceY = src.ey;
int srcW = src.ex - src.sx;
int srcH = src.ey - src.sy;


int ddx,ddy;
int sy = srcY;
unsigned short rgb;

// 拡大縮小とフェードインアウト画像処理
WORD *dpx;
ddy = h;
for(int y=0;y<h;y++)
{
int sidx = (m_Height-sy)*m_Width + srcX;
dpx = (WORD*)(m_WidthByte*y + m_buf);
ddx = w;
ddy -= srcH;
while(ddy<=0)
{
sy += 1;
ddy+= h;
}

for(int x=0;x<w;x++)
{
if(sidx<m_Width*m_Height)
{
unsigned char r = (src_buf[sidx].rgbRed * src.fader)>>8;
unsigned char g = (src_buf[sidx].rgbGreen * src.fader)>>8;
unsigned char b = (src_buf[sidx].rgbBlue * src.fader)>>8;
rgb = ((r << 8) & 0xf800)
| ((g << 3) & 0x07e0)
| ((b >> 3) & 0x001f);
}
else
{
rgb = 0;
}
*dpx=rgb;

dpx++;
ddx -= srcW;
while(ddx<=0)
{
sidx+=1;
ddx += w;
}
}
}
// バッファのイメージをbitmapにコピーする
SetBitmapBits(m_hBmp,m_WidthByte*h,m_buf);

// ディスプレイにbitmapをコピーする
HDC hBmpDC = CreateCompatibleDC(hdc);
SelectObject(hBmpDC, m_hBmp);
BitBlt(hdc,0,0,w,h,hBmpDC,0,0,SRCCOPY);
DeleteObject(hBmpDC);


return true;
}


0 件のコメント: