腾飞论坛 发表于 2012-12-15 12:12:14

传奇如何实现游戏截屏功能

现在很多游戏都提供一种截屏的功能
用来截取游戏中的画面
那么这是如何实现的呢?其实就是把游戏当前屏幕的数据存成一个图片文件;在这里我给出一段源程序
它实现了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;
}

论坛一条龙

仙剑水坝 发表于 2014-4-9 13:29:59

支持楼上的!

双河农场 发表于 2014-4-9 13:22:18

楼上的说的很好!

粉红情书 发表于 2014-4-9 13:38:49

楼主很有艺术范!

黑龙江残疾人 发表于 2014-4-9 13:27:42

看了这么多帖子,第一次看到这么经典的!

伤心俱乐部 发表于 2014-4-9 13:41:18

楼上的心情不错啊!

郑三宝 发表于 2014-6-4 11:00:43

在这个版块混了这么久了,第一次看见这么给你的帖子!

冬天的雪 发表于 2014-6-4 11:08:18

鸟大了,什么林子都敢进啊!

郑三宝 发表于 2014-6-4 10:18:12

求加金币!

天才老大 发表于 2014-6-4 10:44:06

你觉得该怎么做呢?
页: [1] 2 3
查看完整版本: 传奇如何实现游戏截屏功能