今天封装16位位图,例子上是把24位位图变为16位位图,去掉了调色板,
// get video pointer to primary surfce
USHORT *primary_buffer = (USHORT *)ddsd.lpSurface;
// process each line and copy it into the primary buffer
for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
{
for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
{
// get BGR values, note the scaling down of the channels, so that they
// fit into the 5.6.5 format
UCHAR blue = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]) >> 3,
green = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]) >> 3,
red = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]) >> 3;
// this builds a 16 bit color value in 5.6.5 format (green dominant mode)
USHORT pixel = _RGB16BIT565(red,green,blue);
// write the pixel
primary_buffer[index_x + (index_y*ddsd.lPitch >> 1)] = pixel;
} // end for index_x
} // end for index_y
图画如下:“
C++ DEMO中,应该没什么可封装的了。只是在GAME_MAIN()中使用。 把uchar改为ushort即可。
再进行24位,由于都是位图,一起总结吧。填充24位为32位,(加上alpha通道),数据类型改为dword,只是这么改就可以了
DWORD * primary_buffer = ( DWORD * )ddsd.lpSurface;
for( int index_y = 0; index_y < SCREEN_HEIGHT; index_y ++ )
{
for( int index_x = 0; index_x < SCREEN_WIDTH; index_x ++ )
{
UCHAR blue = ( bitmap.buffer[index_y * SCREEN_WIDTH * 3 + index_x * 3 + 0 ] ),
green = ( bitmap.buffer[index_y * SCREEN_WIDTH * 3 + index_x * 3 + 1 ] ),
red = ( bitmap.buffer[index_y * SCREEN_WIDTH * 3 + index_x * 3 + 2 ] ) ;
UCHAR pixel = _RGB32BIT( 0,red, green, blue );
primary_buffer[index_x + ( index_y * ddsd.lPitch >> 2 )] = pixel;
}
}
根据demo改类,OK,现在根据T3DLIB1,去改,我删除了INITDRAW()中的调色板部分和后备缓冲部分,因为不灵活。感觉,似乎T3DLIB1中的相关部分更加灵活些,
现在回过头来想想,灵活性表现主要在于窗口化与否影响了哪些要素,T3DLIB中,对窗口与否都分段处理各部分 应该更灵活些。比如,先根据窗口否判断显示模式这个属性,然后后备缓冲为1(全屏)或者0(窗口)。然后创建主表面(公共部分),接下来是象素格式,暂时还没有涉及到,略过,创建窗口的离屏表面也暂时略过,下一步就是主缓冲连接后备缓冲(全屏)或者直接创建双缓冲(窗口模式),下一步进行调色板,也是分为窗口模式和全屏,目前也是只看全屏。调色板部分用加载文件方式,不过估计不会再用了。
int DDRAW_Interface::Load_Palette_From_File(char * filename, LPPALETTEENTRY palette )
{
FILE * fp_file;
if( ( fp_file = fopen( filename,"r" )) == NULL )
return ( 0 );
for( int index = 0; index < MAX_COLORS_PALETTE; index ++ )
{
fscanf( fp_file, "%d %d %d", & palette[index].peRed, & palette[index].peGreen, & palette[index].peBlue, & palette[index].peFlags );
}
fclose( fp_file );
return ( 1 );
}
#define DEFAULT_PALETTE_FILE "PALDATA2,PAL"
在这里,默认调色板文件是”PALDATA2.PAL”,
加载之,这个文件其实都是一群数字。在全屏模式下,创建调色板
m_lpdd->CreatePalette( DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256, palette, & m_lpddpal, NULL );
窗口模式下,稍微有些不同,前10个和后10个稍微有些不同。即
for( int index = 0; index < 10; index ++ )
palette[index].peFlags = palette[index + 246].peFlags= PC_EXPLICIT;
m_lpdd->CreatePalette( DDPCAPS_8BIT | DDPCAPS_INITIALIZE, palette, & m_lpddpal, NULL );
再将调色板与主缓冲关联
m_lpddsprimary->SetPalette( m_lpddpal );
接下来,清除缓冲,窗口只后备缓冲,全屏需要清除后备和主
if( m_bWindowd == true )
{
DDraw_Fill_Surface( m_lpddsback, 0 );
}
else
{
DDraw_Fill_Surface( m_lpddsprimary, 0 );
DDraw_Fill_Surface( m_lpddsback, 0 );
}
下面进行裁减器,后备缓冲裁减器是一直建立的。
RECT screen_rect = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
m_lpddclipper = DDraw_Attach_Clipper( m_lpddsback, 1, & screen_rect );
窗口模式裁减器暂时不弄。
(在这里发现一个问题,就是如果创建后备缓冲后,不能直接在主表面绘制,否则出错)。
突然发现,ddbltfx已经用过了,都忘记了,重新看下ddraw_init().得到象素可以,函数指针不通,不过也没用得到。
下一步看下一个函数,应该是对于各色位图的加载。在t3dlib中,已经把加载的具体过程分为8,16一组,24位一组,用临时缓冲。
else if( bitmap->bitmapinfoheader.biBitCount == 24 )
{
//按照字节为位位图分配内存
if( ! ( temp_buffer = ( UCHAR * ) malloc( bitmap->bitmapinfoheader.biSizeImage ) ) )
{
_lclose( file_handle );
return ( 0 );
}
//分配最后位存储缓冲
if( ! ( bitmap->buffer = ( UCHAR * ) malloc( 2 * bitmap->bitmapinfoheader.biWidth * bitmap->bitmapinfoheader.biHeight ) ) )
{
_lclose( file_handle );
free( temp_buffer );
return ( 0 );
}
_lread( file_handle, bitmap->buffer, bitmap->bitmapinfoheader.biSizeImage );
for( int index = 0; index < bitmap->bitmapinfoheader.biWidth * bitmap->bitmapinfoheader.biHeight; index ++ )
{
UCHAR color;
if( m_pixelformat == DD_PIXEL_FORMAT555 )
{
UCHAR blue = ( temp_buffer[index * 3 + 0] >> 3 ),
green = ( temp_buffer[index * 3 + 1] >> 3 ),
red = ( temp_buffer[index * 3 + 2] >> 3 );
color = _RGB16BIT555( red, green, blue );
}
else if( m_pixelformat == DD_PIXEL_FORMAT565 )
{
UCHAR blue = ( temp_buffer[index * 3 + 0] >> 3 ),
green = ( temp_buffer[index * 3 + 1] >> 2 ),
red = ( temp_buffer[index * 3 + 2] >> 3 );
color = _RGB16BIT565( red, green, blue );
}
( ( USHORT * ) bitmap->buffer )[index] = color;
}
bitmap->bitmapinfoheader.biBitCount = 16;
free( temp_buffer );
}