| 如何實現遊戲截屏功能 |
|
|
| SoftBoy gameres 2006-08-11 |
|
|
現在很多遊戲都提供一種截屏的功能,用來截取遊戲中的畫面,那麼這是如何實現的呢?其實就是把遊戲當前屏幕的數據存成一個圖片文件;在這裡我給出一段源程序,它實現了DirectDraw(16位模式)下的的遊戲截屏。生成的文件格式為BMP,程序有比較詳細的注釋,請各位自己看吧。
現在很多遊戲都提供一種截屏的功能,用來截取遊戲中的畫面,那麼這是如何實現的呢?其實就是把遊戲當前屏幕的數據存成一個圖片文件;在這裡我給出一段源程序,它實現了DirectDraw(16位模式)下的的遊戲截屏。生成的文件格式為BMP,程序有比較詳細的注釋,請各位自己看吧。
bool Is555; // 是否是565模式,這個變量需要用者填寫
// 功能:將一個16位的DirectDraw表面,存為一張24位BMP位圖 (傳入主表面即截屏) // 輸入:表面指針,輸出的文件名 // 輸出:是否成功 bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename) { WORD* lpBuffer; // 表面指針 int nPitch; // 表面跨距 int nWidth, nHeight; // 表面寬高
// 打開文件s FILE* fp; if( (fp=fopen(filename, "wb")) != NULL ) { // 鎖定表面 DDSURFACEDESC ddsd; ddsd.dwSize = sizeof(ddsd); HRESULT ddrval = lpSurface->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL ); if( ddrval == DD_OK ) { lpBuffer = (WORD *)ddsd.lpSurface; nWidth = ddsd.dwWidth; nHeight = ddsd.dwHeight; nPitch = ddsd.lPitch >> 1; //lPitch以Byte為單位,GraphPitch以WORD為單位。所以GraphPitch = lPitch / 2; }
// 保存文件頭 BITMAPFILEHEADER FileHeader; FileHeader.bfType = 'BM'; FileHeader.bfSize = nWidth * nHeight * 3 + 0x36; FileHeader.bfReserved1 = 0; FileHeader.bfReserved2 = 0; FileHeader.bfOffBits = 0x36; fwrite(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
// 保存文件信息 BITMAPINFOHEADER Header; Header.biSize = sizeof(BITMAPINFOHEADER); // 結構的大小 Header.biWidth = nWidth; // 寬 Header.biHeight = nHeight; // 高 Header.biPlanes = 1; // 固定 Header.biBitCount = 24; // 顏色數 Header.biCompression = BI_RGB; // 是否壓縮 Header.biSizeImage = nWidth * nHeight * 3; // 圖片的大小 Header.biXPelsPerMeter = 0; Header.biYPelsPerMeter = 0; Header.biClrUsed = 0; Header.biClrImportant = 0; fwrite(&Header, Header.biSize, 1, fp);
// 寫入具體內容(從下向上存放) fseek(fp, 0x36, SEEK_SET); WORD word; lpBuffer += nWidth * (nHeight - 1); for(int i=0; i { for(int j=0; j { word = *lpBuffer; fputc( GetBlue( word ), fp); // 藍 fputc( GetGreen( word ), fp); // 綠 fputc( GetRed( word ), fp); // 紅 lpBuffer++; } lpBuffer -= nPitch*2; // 指針轉到上一行的開始 }
fclose(fp);
// 解鎖表面 ddrval = lpSurface->Unlock( NULL ); return true; }
return false; }
inline unsigned char GetRed(WORD color) { if( Is555 ) return (color>>7) & 0xff; else return (color>>8) & 0xff; }
inline unsigned char GetGreen(WORD color) { if( Is555 ) return (color>>2) & 0xff; else return (color>>3) & 0xff; }
inline unsigned char GetBlue(WORD color) { return (color & 0x1f) << 3; }
------------------------ 金點時空 softboy 2001.5.9 http://www.gpgame.com ------------------------
| | | |
|
|
|
|
 |
|
|
 |
|
|
|
|