2013年6月21日星期四(载入16位位图和24位位图)

来源:互联网 发布:怎么进行网络直播 编辑:程序博客网 时间:2024/04/30 18:02

今天封装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 );

 

}

 

原创粉丝点击