GBufの生成、開放などの制御を担う関数です。
これらのほとんどは、GBufから情報を引き出すための関数なので、生成と開放のみ詳細の解説を行います。
■ ダウンロード
GBufコア関数
gbuf.h … ヘッダーファイル
gbuf.cpp … GBufコア
■ サンプルプログラム
以下は、
1.100x200のDIBモードのバッファを生成する
2.緑色で埋める
3.ウィンドゥハンドルhwndに示すウィンドゥに描画する
4.バッファを開放する
を行っています。
// 1.
GBUF_STRUCT * gbuf = GBuf_Create(100,200,GF_DIB);
// 2.
G_PIXEL * ptr;
int i,j;
for(i = 0;i < 200;i++){
for(j = 0;j < 100;j++){
ptr = GBuf_GetPtrPosition(gbuf,j,i);
ptr->pixel.green = 255;
}
}
// 3.
HDC dc = GetDC(hwnd);
BitBlt(dc,0,0,100,200,GBuf_GetDC(gbuf),0,0,SRCCOPY);
ReleaseDC(hwnd,dc);
// 4.
GBuf_Release(gbuf);
■ GBuf_Create
GBUF_STRUCT * WINAPI GBuf_Create(
int width,// グラフィックバッファの幅
int height,// 高さ
G_FLAG flags);// 属性
GBufの生成関数です。flagsに属性を定義する事で、任意の性質を持ったグラフィックバッファを生成する事ができます。
flags = GF_MASK // マスクモード
flags = GF_ALPHA // アルファモード
flags = GF_DIB // DIBモード
flags = GF_DEFAULT // デフォルト値(通常値)
GF_MASK,GF_ALPHA,GF_DEFAULTはこのうちいずれかしか定義できません。もし複数定義された場合には、動作が不安定になります。
GF_DIBは他の属性と組み合わせる事ができ、GDIを用いる事でDirectDrawSurface,DCとのデータのやり取りが出きるGBufを生成します。
生成コードは以下の通りです。
GF_DIBの状態によって、DIBSectionもしくはヒープからメモリの確保を行い、操作に必要な情報を設定しています。
GBUF_STRUCT * WINAPI GBuf_Create(int width,int height,G_FLAG flags)
{
// 構造体を確保
GBUF_STRUCT *gbuf = (GBUF_STRUCT *)Malloc(sizeof(GBUF_STRUCT));
gbuf->width = width;
gbuf->height = height;
gbuf->pitch = - width;
gbuf->flags = flags;
gbuf->gbuf = gbuf->gtop = NULL;
if(flags & GF_DIB){
BITMAPINFO bi;ZeroMemory(&bi,sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = gbuf->width;
bi.bmiHeader.biHeight = gbuf->height;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
HDC dc = GetDC(0);
gbuf->dc = CreateCompatibleDC(dc);
gbuf->bitmap = CreateDIBSection(gbuf->dc,&bi,DIB_RGB_COLORS,(void **)&gbuf->gbuf,NULL,0);
ReleaseDC(0,dc);
SelectObject(gbuf->dc,gbuf->bitmap);
}else{
int p = sizeof(G_PIXEL);
gbuf->gbuf = (G_PIXEL *)Malloc(sizeof(G_PIXEL) * gbuf->width * gbuf->height);
gbuf->bitmap = NULL;
gbuf->dc = NULL;
}
gbuf->gtop = gbuf->gbuf + (gbuf->width * (gbuf->height - 1));
return gbuf;
}
DIBSectionビットマップは、32bitモードで生成させます。
DCやBITMAPハンドルは、GetDC(0)でデフォルトのDCを取得、CreateCompatibleDCで互換DCを生成、SelectObjectで関連付けという順番で生成します。
通常モードは、ヒープから生成させます。
DIBSectionと同じアルゴリズムで動作させるために、内部のピクセル構造等は全く同じ物にしています。
gbuf->gtopは、[0,0]位置の計算です。"幅 * 高さ - 1"で求めた位置がそこに当たります。
■ GBuf_Release
void WINAPI GBuf_Release(
GBUF_STRUCT *gbuf); // GBufハンドル
GBufの開放関数です。GBuf_Createで生成されたグラフィックバッファを正しく開放するようになっています。
開放コードは以下の通りです。GF_DIBの状態によって、DeleteObjectとヒープの開放とを振り分けています。
void WINAPI GBuf_Release(GBUF_STRUCT *gbuf)
{
if(gbuf->flags & GF_DIB){
DIBSECTION ds;
GetObject(gbuf->bitmap,sizeof(ds),&ds);
CloseHandle(ds.dshSection);
DeleteObject(gbuf->bitmap);
DeleteDC(gbuf->dc);
gbuf->gbuf = gbuf->gtop = NULL;
}
if(gbuf->gbuf != NULL){
Free(gbuf->gbuf);
gbuf->gbuf = gbuf->gtop = NULL;
}
Free(gbuf);
}
DIBSectionはGetObjectでファイルマッピングハンドルし、開放しなければなりません。また、BITMAP,DCハンドルも同じです。
通常モードは簡単です。ヒープを開放するだけで終わります。
■ GBuf_GetWidth,GBuf_GetHeight,GBuf_GetPitch
int WINAPI GBuf_GetWidth(GBUF_STRUCT *gbuf);
int WINAPI GBuf_GetHeight(GBUF_STRUCT *gbuf);
int WINAPI GBuf_GetPitch(GBUF_STRUCT *gbuf);
GBufからグラフィックバッファの幅、高さ、1ライン移動に必要なデータサイズが取得します。
■ GBuf_GetBitmap
HBITMAP WINAPI GBuf_GetBitmap(GBUF_STRUCT *gbuf);
HDC WINAPI GBuf_GetDC(GBUF_STRUCT *gbuf);
GBufからGDI関数を使うのに必要な、BITMAPハンドル、DCハンドルを取得します。
■ GBuf_GetFlags
G_FLAG WINAPI GBuf_GetFlags(GBUF_STRUCT *gbuf);
GBufからグラフィックバッファの属性を取得します。
GBuf_Createで定義されたflags値が返ります。
■ GBuf_GetPtr,GBuf_GetPtrPosition
G_PIXEL * WINAPI GBuf_GetPtr(GBUF_STRUCT *gbuf);
G_PIXEL * WINAPI GBuf_GetPtrPosition(GBUF_STRUCT *gbuf,int x,int y);
GBufの画像アクセスに必要なポインタを取得します。
GBuf_GetPtrは[0,0]位置のポインタ、GBuf_GetPtrPositionは[x,y]位置のポインタを取得する事ができます。
■ GBuf_SetMask,GBuf_ResetMask,GBuf_GetMask
BOOL WINAPI GBuf_SetMask(GBUF_STRUCT *gbuf,G_LONG mask);
BOOL WINAPI GBuf_ResetMask(GBUF_STRUCT *gbuf);
BOOL WINAPI GBuf_GetMask(GBUF_STRUCT *gbuf,G_PIXEL *retbuf);
マスクモードの設定,解除,マスクカラーの取得します。