demo7-4,后备缓冲

来源:互联网 发布:情系探花头像psd源码 编辑:程序博客网 时间:2024/03/28 17:53

双缓冲就是开辟一个后备缓冲(不要忘了给它分配内存),然后锁定它,绘制之,再解锁,再逐行复制给主表面,(因为每行都有多余空间,所以必须逐行)

 

书上的源代码

定义后备缓冲指针和主缓存指针,主缓存指针只是在主表面锁定时只想主表面,并不分配空间。

UCHAR                  * double_buffer = NULL;

UCHAR *primary_buffer = NULL;

初始化时:

     double_buffer = new UCHAR[SCREEN_WIDTH *SCREEN_HEIGHT];

主程序上,-》分配后备缓存->绘制->锁定主表面->复制->解锁主表面

memset( ( void *) double_buffer, 0, SCREEN_WIDTH * SCREEN_HEIGHT );

 

     // plot 1000 random pixels with random colors on the

     // primary surface, they will be instantly visible

     for (intindex=0; index < 1000;index++)

     {

         // select random position and color for 640x480x8

         UCHAR color = rand()%256;

         int x = rand()%640;

         int y = rand()%480;

 

         // plot the pixel

         double_buffer[x+y*SCREEN_WIDTH] =color;       

 

     } // end for index

     // plot 1000 random pixels to the primary surface and return

     // clear ddsd and set size, never assume it's clean

     memset(&ddsd,0,sizeof(ddsd));

     ddsd.dwSize =sizeof(ddsd);

 

     if (FAILED(lpddsprimary->Lock(NULL, &ddsd,

         DDLOCK_SURFACEMEMORYPTR |DDLOCK_WAIT,

         NULL)))

     {

         // error

         return(0);

     } // end if

//锁定主表面后主缓存指针指向主表面

     primary_buffer = ( UCHAR * )ddsd.lpSurface;

     if( ddsd.lPitch == SCREEN_WIDTH )

     {

         memcpy( ( void * ) primary_buffer, ( void *) double_buffer,SCREEN_WIDTH *SCREEN_HEIGHT );

     }

     else

     {

         UCHAR * dest_ptr = primary_buffer;

         UCHAR * src_ptr = double_buffer;

         for( int y = 0; y < SCREEN_HEIGHT; y ++ )

         {

              memcpy( ( void *) dest_ptr, ( void * ) src_ptr, SCREEN_WIDTH );

              dest_ptr += ddsd.lPitch;

              src_ptr += SCREEN_WIDTH;

         }

 

     }

 

 

     // now unlock the primary surface

     if (FAILED(lpddsprimary->Unlock(NULL)))

         return(0);

 

最后再释放缓存

if ( double_buffer )

     {

         delete double_buffer;

         double_buffer = NULL;

     }

现在可以封装引擎了,其中老是出错,尤其是推出时,说是内存写入错误,只好用exit(0)了

Game_main()中

 

     UCHAR *primary_buffer =NULL; // used as alias to primary surface buffer

 

     // make sure this isn't executed again

 

 

     // for now test if user is hitting ESC and send WM_CLOSE

     if (KEYDOWN(VK_ESCAPE))

     {

         exit( 0 );

         //PostMessage(main_window_handle,WM_CLOSE,0,0);

     } // end if

 

     // erase double buffer

     memset((void *)double_buffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);

 

     // you would perform game logic...

 

     // draw the next frame into the double buffer

     // plot 5000 random pixels

     for (intindex=0; index < 1000;index++)

     {

         int   x   = rand()%SCREEN_WIDTH;

         int   y   = rand()%SCREEN_HEIGHT;

         UCHAR col = rand()%256;

         double_buffer[x+y*SCREEN_WIDTH] =col;

     } // end for index

 

     DDSURFACEDESC2        ddsd;   

 

     // copy the double buffer into the primary buffer

     DDRAW_INIT_STRUCT(ddsd);

 

     // lock the primary surface

     ddraw->getPrimarySurface()->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

 

     // get video pointer to primary surfce

     primary_buffer = (UCHAR *)ddsd.lpSurface;      

 

     // test if memory is linear

     if (ddsd.lPitch ==SCREEN_WIDTH)

     {

         // copy memory from double buffer to primary buffer

         memcpy((void *)primary_buffer, (void *)double_buffer,SCREEN_WIDTH*SCREEN_HEIGHT);

     } // end if

     else

     { // non-linear

 

         // make copy of source and destination addresses

         UCHAR *dest_ptr =primary_buffer;

         UCHAR *src_ptr  =double_buffer;

 

         // memory is non-linear, copy line by line

         for (inty=0; y < SCREEN_HEIGHT; y++)

         {

              // copy line

              memcpy((void *)dest_ptr, (void *)src_ptr,SCREEN_WIDTH);

 

              // advance pointers to next line

              dest_ptr+=ddsd.lPitch;

              src_ptr +=SCREEN_WIDTH;

 

              // note: the above code code be replaced with the simpler

              // memcpy(&primary_buffer[y*ddsd.lPitch], double_buffer[y*SCREEN_WIDTH], SCREEN_WIDTH);

              // but it is much slower due to the recalculation and multiplication each cycle

 

         } // end for

 

     } // end else

 

     // now unlock the primary surface

     if (FAILED(ddraw->getPrimarySurface()->Unlock(NULL)))

         return(0);

在后备缓冲中,定义时必须

UCHAR                            *   double_buffer          = NULL;

在Init()中,才能

double_buffer = newUCHAR[SCREEN_WIDTH *SCREEN_HEIGHT];

否则会出事

在释放资源中,要记住释放

     // loop while is exited, do all you cleanup and shutdown here

     if ( double_buffer )

     {

         delete double_buffer;

         double_buffer = NULL;

     }

 

     if( ddraw)

     {

         delete ddraw;

         ddraw = NULL;

     }

根据T3DLIB,暂时没有可以修改的地方,

原创粉丝点击