使用IDirectDrawClipper进行裁剪

来源:互联网 发布:mac里的照片导出到u盘 编辑:程序博客网 时间:2024/05/17 08:40

原文地址::http://blog.csdn.net/chain2012/article/details/6796931

 

 

  1. // DEMO7_9.CPP 8-bit clipping demo   
  2.   
  3. // INCLUDES ///////////////////////////////////////////////  
  4.   
  5. #define WIN32_LEAN_AND_MEAN  // just say no to MFC  
  6.   
  7. #define INITGUID   
  8.   
  9. #include <windows.h>   // include important windows stuff  
  10. #include <windowsx.h>    
  11. #include <mmsystem.h>   
  12. #include <iostream.h> // include important C/C++ stuff  
  13. #include <conio.h>   
  14. #include <stdlib.h>   
  15. #include <malloc.h>   
  16. #include <memory.h>   
  17. #include <string.h>   
  18. #include <stdarg.h>   
  19. #include <stdio.h>    
  20. #include <math.h>   
  21. #include <io.h>   
  22. #include <fcntl.h>   
  23.   
  24. #include <ddraw.h> // include directdraw  
  25.   
  26. // DEFINES ////////////////////////////////////////////////  
  27.   
  28. // defines for windows    
  29. #define WINDOW_CLASS_NAME "WINCLASS1"  
  30.   
  31. // default screen size   
  32. #define SCREEN_WIDTH    640  // size of screen  
  33. #define SCREEN_HEIGHT   480  
  34. #define SCREEN_BPP      8    // bits per pixel  
  35.   
  36. #define MAX_COLORS_PALETTE 256 // maximum colors in 256 color palette  
  37.   
  38. // TYPES //////////////////////////////////////////////////////  
  39.   
  40. // basic unsigned types   
  41. typedef unsigned short USHORT;  
  42. typedef unsigned short WORD;  
  43. typedef unsigned char  UCHAR;  
  44. typedef unsigned char  BYTE;  
  45.   
  46. // MACROS //////////////////////////////////////////////////////  
  47.   
  48. #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)  
  49. #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)  
  50.   
  51. // this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)  
  52. #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))  
  53.   
  54. // this builds a 16 bit color value in 5.6.5 format (green dominate mode)  
  55. #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))  
  56.   
  57. // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)  
  58. #define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))  
  59.   
  60. // initializes a direct draw struct   
  61. #define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }  
  62.   
  63. // PROTOTYPES /////////////////////////////////////////////////  
  64.   
  65. LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,  
  66.                                          int num_rects,  
  67.                                          LPRECT clip_list);  
  68.   
  69. // GLOBALS ////////////////////////////////////////////////////  
  70.   
  71. HWND      main_window_handle = NULL; // globally track main window  
  72. int       window_closed      = 0;    // tracks if window is closed  
  73. HINSTANCE hinstance_app      = NULL; // globally track hinstance  
  74.   
  75. // directdraw stuff   
  76. LPDIRECTDRAW7         lpdd         = NULL;   // dd4 object  
  77. LPDIRECTDRAWSURFACE7  lpddsprimary = NULL;   // dd primary surface  
  78. LPDIRECTDRAWSURFACE7  lpddsback    = NULL;   // dd back surface  
  79. LPDIRECTDRAWPALETTE   lpddpal      = NULL;   // a pointer to the created dd palette  
  80. LPDIRECTDRAWCLIPPER   lpddclipper  = NULL;   // dd clipper  
  81. PALETTEENTRY          palette[256];          // color palette  
  82. PALETTEENTRY          save_palette[256];     // used to save palettes  
  83. DDSURFACEDESC2        ddsd;                  // a direct draw surface description struct  
  84. DDBLTFX               ddbltfx;               // used to fill  
  85. DDSCAPS2              ddscaps;               // a direct draw surface capabilities struct  
  86. HRESULT               ddrval;                // result back from dd calls  
  87. DWORD                 start_clock_count = 0; // used for timing  
  88.   
  89. char buffer[80];                             // general printing buffer  
  90.   
  91. // FUNCTIONS //////////////////////////////////////////////  
  92.   
  93. LRESULT CALLBACK WindowProc(HWND hwnd,   
  94.                             UINT msg,   
  95.                             WPARAM wparam,   
  96.                             LPARAM lparam)  
  97. {  
  98. // this is the main message handler of the system  
  99. PAINTSTRUCT     ps;     // used in WM_PAINT  
  100. HDC             hdc;    // handle to a device context  
  101. char buffer[80];        // used to print strings  
  102.   
  103. // what is the message    
  104. switch(msg)  
  105.     {     
  106.     case WM_CREATE:   
  107.         {  
  108.         // do initialization stuff here   
  109.         // return success   
  110.         return(0);  
  111.         } break;  
  112.      
  113.     case WM_PAINT:   
  114.         {  
  115.         // simply validate the window   
  116.         hdc = BeginPaint(hwnd,&ps);    
  117.           
  118.         // end painting   
  119.         EndPaint(hwnd,&ps);  
  120.   
  121.         // return success   
  122.         return(0);  
  123.         } break;  
  124.   
  125.     case WM_DESTROY:   
  126.         {  
  127.   
  128.         // kill the application, this sends a WM_QUIT message   
  129.         PostQuitMessage(0);  
  130.   
  131.         // return success   
  132.         return(0);  
  133.         } break;  
  134.   
  135.     default:break;  
  136.   
  137.     } // end switch   
  138.   
  139. // process any messages that we didn't take care of   
  140. return (DefWindowProc(hwnd, msg, wparam, lparam));  
  141.   
  142. // end WinProc   
  143.   
  144. ///////////////////////////////////////////////////////////  
  145.   
  146. int Game_Main(void *parms = NULL, int num_parms = 0)  
  147. {  
  148. // this is the main loop of the game, do all your processing  
  149. // here   
  150.   
  151. RECT source_rect, // used to hold the destination RECT  
  152.      dest_rect;  // used to hold the destination RECT  
  153.   
  154. // make sure this isn't executed again   
  155. if (window_closed)  
  156.    return(0);  
  157.   
  158. // for now test if user is hitting ESC and send WM_CLOSE  
  159. if (KEYDOWN(VK_ESCAPE))  
  160.    {  
  161.    PostMessage(main_window_handle,WM_CLOSE,0,0);  
  162.    window_closed = 1;  
  163.    } // end if   
  164.   
  165. // get a random rectangle for source  
  166. int x1 = rand()%SCREEN_WIDTH;  
  167. int y1 = rand()%SCREEN_HEIGHT;  
  168. int x2 = rand()%SCREEN_WIDTH;  
  169. int y2 = rand()%SCREEN_HEIGHT;  
  170.   
  171. // get a random rectangle for destination  
  172. int x3 = rand()%SCREEN_WIDTH;  
  173. int y3 = rand()%SCREEN_HEIGHT;  
  174. int x4 = rand()%SCREEN_WIDTH;  
  175. int y4 = rand()%SCREEN_HEIGHT;  
  176.   
  177. // now set up the RECT structure to fill the region from  
  178. // (x1,y1) to (x2,y2) on the source surface  
  179. source_rect.left   = x1;  
  180. source_rect.top    = y1;  
  181. source_rect.right  = x2;  
  182. source_rect.bottom = y2;  
  183.   
  184. // now set up the RECT structure to fill the region from  
  185. // (x3,y3) to (x4,y4) on the destination surface  
  186. dest_rect.left   = x3;  
  187. dest_rect.top    = y3;  
  188. dest_rect.right  = x4;  
  189. dest_rect.bottom = y4;  
  190.   
  191. // make the blitter call   
  192. if (FAILED(lpddsprimary->Blt(&dest_rect,  // pointer to dest RECT  
  193.                              lpddsback,   // pointer to source surface  
  194.                              &source_rect,// pointer to source RECT  
  195.                              DDBLT_WAIT,  // control flags  
  196.                              NULL)))      // pointer to DDBLTFX holding info  
  197.    return(0);  
  198.   
  199. // return success or failure or your own return code here  
  200. return(1);  
  201.   
  202. // end Game_Main   
  203.   
  204. ////////////////////////////////////////////////////////////  
  205.   
  206. int Game_Init(void *parms = NULL, int num_parms = 0)  
  207. {  
  208. // this is called once after the initial window is created and  
  209. // before the main event loop is entered, do all your initialization  
  210. // here   
  211.   
  212. // create IDirectDraw interface 7.0 object and test for error  
  213. if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))  
  214.    return(0);  
  215.   
  216. // set cooperation to full screen   
  217. if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,   
  218.                                       DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |   
  219.                                       DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))  
  220.    return(0);  
  221.   
  222. // set display mode    
  223. if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))  
  224.    return(0);  
  225.   
  226. // clear ddsd and set size   
  227. DDRAW_INIT_STRUCT(ddsd);   
  228.   
  229. // enable valid fields   
  230. ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;  
  231.   
  232. // set the backbuffer count field to 1, use 2 for triple buffering  
  233. ddsd.dwBackBufferCount = 1;  
  234.   
  235. // request a complex, flippable  
  236. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;  
  237.   
  238. // create the primary surface   
  239. if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))  
  240.    return(0);  
  241.   
  242. // now query for attached surface from the primary surface  
  243.   
  244. // this line is needed by the call   
  245. ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;  
  246.   
  247. // get the attached back buffer surface  
  248. if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))  
  249.   return(0);  
  250.   
  251. // clear all entries defensive programming  
  252. memset(palette,0,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));  
  253.   
  254. // create a R,G,B,GR gradient palette   
  255. for (int index=0; index < MAX_COLORS_PALETTE; index++)  
  256.     {  
  257.     // set each entry   
  258.     if (index < 64)  // shades of red  
  259.         palette[index].peRed = index*4;   
  260.     else            // shades of green  
  261.     if (index >= 64 && index < 128)   
  262.         palette[index].peGreen = (index-64)*4;  
  263.     else            // shades of blue  
  264.     if (index >= 128 && index < 192)   
  265.        palette[index].peBlue = (index-128)*4;  
  266.     else            // shades of grey  
  267.     if (index >= 192 && index < 256)   
  268.         palette[index].peRed = palette[index].peGreen =   
  269.         palette[index].peBlue = (index-192)*4;  
  270.       
  271.     // set flag to force directdraw to leave alone  
  272.     palette[index].peFlags = PC_NOCOLLAPSE;  
  273.     } // end for index   
  274.   
  275.   
  276. // draw a color gradient in back buffer   
  277. DDRAW_INIT_STRUCT(ddsd);  
  278.   
  279. // lock the back buffer   
  280. if (FAILED(lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))  
  281.    return(0);  
  282.   
  283. // get alias to start of surface memory for fast addressing  
  284. UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface;  
  285.   
  286. // draw the gradient   
  287. for (int index_y=0; index_y < SCREEN_HEIGHT; index_y++)  
  288.      {  
  289.      // fill next line with color  
  290.      memset((void *)video_buffer,index_y % 256,SCREEN_WIDTH);  
  291.   
  292.      // advance pointer   
  293.      video_buffer+=ddsd.lPitch;  
  294.      
  295.      } // end for index_y   
  296.   
  297. // unlock the back buffer   
  298. if (FAILED(lpddsback->Unlock(NULL)))  
  299.    return(0);  
  300.   
  301. // now create and attach clipper  
  302. RECT rect_list[3] = {{10,10,50,50},  
  303.                      {100,100,200,200},  
  304.                      {300,300, 500, 450}};  
  305.   
  306. if (FAILED(lpddclipper = DDraw_Attach_Clipper(lpddsprimary,3,rect_list)))  
  307.    return(0);  
  308.   
  309. // return success or failure or your own return code here  
  310. return(1);  
  311.   
  312. // end Game_Init   
  313.   
  314. /////////////////////////////////////////////////////////////  
  315.   
  316. int Game_Shutdown(void *parms = NULL, int num_parms = 0)  
  317. {  
  318. // this is called after the game is exited and the main event  
  319. // loop while is exited, do all you cleanup and shutdown here  
  320.   
  321. // first the palette   
  322. if (lpddpal)  
  323.    {  
  324.    lpddpal->Release();  
  325.    lpddpal = NULL;  
  326.    } // end if   
  327.   
  328. // now the back buffer surface   
  329. if (lpddsback)  
  330.    {  
  331.    lpddsback->Release();  
  332.    lpddsback = NULL;  
  333.    } // end if   
  334.   
  335. // now the primary surface   
  336. if (lpddsprimary)  
  337.    {  
  338.    lpddsprimary->Release();  
  339.    lpddsprimary = NULL;  
  340.    } // end if   
  341.   
  342. // now blow away the IDirectDraw4 interface  
  343. if (lpdd)  
  344.    {  
  345.    lpdd->Release();  
  346.    lpdd = NULL;  
  347.    } // end if   
  348.   
  349. // return success or failure or your own return code here  
  350. return(1);  
  351.   
  352. // end Game_Shutdown   
  353.   
  354. ///////////////////////////////////////////////////////////  
  355.   
  356. LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,  
  357.                                          int num_rects,  
  358.                                          LPRECT clip_list)  
  359.   
  360. {  
  361. // this function creates a clipper from the sent clip list and attaches  
  362. // it to the sent surface   
  363.   
  364. int index;                         // looping var  
  365. LPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipper  
  366. LPRGNDATA region_data;             // pointer to the region data that contains  
  367.                                    // the header and clip list  
  368.   
  369. // first create the direct draw clipper  
  370. if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))  
  371.    return(NULL);  
  372.   
  373. // now create the clip list from the sent data  
  374.   
  375. // first allocate memory for region data  
  376. region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));  
  377.   
  378. // now copy the rects into region data   
  379. memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);  
  380.   
  381. // set up fields of header   
  382. region_data->rdh.dwSize          = sizeof(RGNDATAHEADER);  
  383. region_data->rdh.iType           = RDH_RECTANGLES;  
  384. region_data->rdh.nCount          = num_rects;  
  385. region_data->rdh.nRgnSize        = num_rects*sizeof(RECT);  
  386.   
  387. region_data->rdh.rcBound.left    =  64000;  
  388. region_data->rdh.rcBound.top     =  64000;  
  389. region_data->rdh.rcBound.right   = -64000;  
  390. region_data->rdh.rcBound.bottom  = -64000;  
  391.   
  392. // find bounds of all clipping regions   
  393. for (index=0; index<num_rects; index++)  
  394.     {  
  395.     // test if the next rectangle unioned with the current bound is larger  
  396.     if (clip_list[index].left < region_data->rdh.rcBound.left)  
  397.        region_data->rdh.rcBound.left = clip_list[index].left;  
  398.   
  399.     if (clip_list[index].right > region_data->rdh.rcBound.right)  
  400.        region_data->rdh.rcBound.right = clip_list[index].right;  
  401.   
  402.     if (clip_list[index].top < region_data->rdh.rcBound.top)  
  403.        region_data->rdh.rcBound.top = clip_list[index].top;  
  404.   
  405.     if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)  
  406.        region_data->rdh.rcBound.bottom = clip_list[index].bottom;  
  407.   
  408.     } // end for index   
  409.   
  410. // now we have computed the bounding rectangle region and set up the data  
  411. // now let's set the clipping list  
  412.   
  413. if (FAILED(lpddclipper->SetClipList(region_data, 0)))  
  414.    {  
  415.    // release memory and return error  
  416.    free(region_data);  
  417.    return(NULL);  
  418.    } // end if   
  419.   
  420. // now attach the clipper to the surface   
  421. if (FAILED(lpdds->SetClipper(lpddclipper)))  
  422.    {  
  423.    // release memory and return error  
  424.    free(region_data);  
  425.    return(NULL);  
  426.    } // end if   
  427.   
  428. // all is well, so release memory and send back the pointer to the new clipper  
  429. free(region_data);  
  430. return(lpddclipper);  
  431.   
  432. // end DDraw_Attach_Clipper   
  433.   
  434.   
  435. // WINMAIN ////////////////////////////////////////////////  
  436.   
  437. int WINAPI WinMain( HINSTANCE hinstance,  
  438.                     HINSTANCE hprevinstance,  
  439.                     LPSTR lpcmdline,  
  440.                     int ncmdshow)  
  441. {  
  442.   
  443. WNDCLASSEX winclass; // this will hold the class we create  
  444. HWND       hwnd;     // generic window handle  
  445. MSG        msg;      // generic message  
  446. HDC        hdc;      // graphics device context  
  447.   
  448. // first fill in the window class stucture  
  449. winclass.cbSize         = sizeof(WNDCLASSEX);  
  450. winclass.style          = CS_DBLCLKS | CS_OWNDC |   
  451.                           CS_HREDRAW | CS_VREDRAW;  
  452. winclass.lpfnWndProc    = WindowProc;  
  453. winclass.cbClsExtra     = 0;  
  454. winclass.cbWndExtra     = 0;  
  455. winclass.hInstance      = hinstance;  
  456. winclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);  
  457. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);   
  458. winclass.hbrBackground  = (HBRUSH)GetStockObject(BLACK_BRUSH);  
  459. winclass.lpszMenuName   = NULL;  
  460. winclass.lpszClassName  = WINDOW_CLASS_NAME;  
  461. winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);  
  462.   
  463. // save hinstance in global   
  464. hinstance_app = hinstance;  
  465.   
  466. // register the window class   
  467. if (!RegisterClassEx(&winclass))  
  468.     return(0);  
  469.   
  470. // create the window   
  471. if (!(hwnd = CreateWindowEx(NULL,                  // extended style  
  472.                             WINDOW_CLASS_NAME,     // class  
  473.                             "DirectDraw Clipping Demo"// title  
  474.                             WS_POPUP | WS_VISIBLE,  
  475.                             0,0,      // initial x,y  
  476.                             SCREEN_WIDTH,SCREEN_HEIGHT,  // initial width, height  
  477.                             NULL,     // handle to parent   
  478.                             NULL,     // handle to menu  
  479.                             hinstance,// instance of this application  
  480.                             NULL))) // extra creation parms  
  481. return(0);  
  482.   
  483. // save main window handle   
  484. main_window_handle = hwnd;  
  485.   
  486. // initialize game here   
  487. Game_Init();  
  488.   
  489. // enter main event loop   
  490. while(TRUE)  
  491.     {  
  492.     // test if there is a message in queue, if so get it  
  493.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))  
  494.        {   
  495.        // test if this is a quit  
  496.        if (msg.message == WM_QUIT)  
  497.            break;  
  498.       
  499.        // translate any accelerator keys  
  500.        TranslateMessage(&msg);  
  501.   
  502.        // send the message to the window proc  
  503.        DispatchMessage(&msg);  
  504.        } // end if   
  505.       
  506.        // main game processing goes here   
  507.        Game_Main();  
  508.          
  509.     } // end while   
  510.   
  511. // closedown game here   
  512. Game_Shutdown();  
  513.   
  514. // return to Windows like this   
  515. return(msg.wParam);  
  516.   
  517. // end WinMain   
  518.   
  519. ///////////////////////////////////////////////////////////  
  520.   
  521. void Blit_clipped(int x, int y,          // position to draw bitmap  
  522.                   int width, int height, // size of bitmap in pixels  
  523.                   UCHAR *bitmap,         // pointer to bitmap data  
  524.                   UCHAR *video_buffer)   // pointer to video buffer surface  
  525.                   
  526. {  
  527. // this function blits and clips the image sent in bitmap to the   
  528. // destination surface pointed to by video_buffer  
  529. // the function assumes a 640x480x8 mode with linear pitch  
  530.   
  531. // first do trivial rejections of bitmap, is it totally invisible?  
  532. if ((x >= SCREEN_WIDTH) || (y>= SCREEN_HEIGHT) ||  
  533.     ((x + width) <= 0) || ((y + height) <= 0))  
  534. return;  
  535.   
  536. // clip source rectangle   
  537. // pre-compute the bounding rect to make life easy  
  538. int x1 = x;  
  539. int y1 = y;  
  540. int x2 = x1 + width - 1;  
  541. int y2 = y1 + height -1;  
  542.   
  543. // upper left hand corner first  
  544. if (x1 < 0)  
  545.    x1 = 0;  
  546.   
  547. if (y1 < 0)  
  548.    y1 = 0;  
  549.   
  550. // now lower left hand corner   
  551. if (x2 >= SCREEN_WIDTH)  
  552.     x2 = SCREEN_WIDTH-1;  
  553.   
  554. if (y2 >= SCREEN_HEIGHT)  
  555.     y2 = SCREEN_HEIGHT-1;  
  556.   
  557. // now we know to draw only the portions of the bitmap from (x1,y1) to (x2,y2)  
  558. // compute offsets into bitmap on x,y axes, we need this to compute starting point  
  559. // to rasterize from   
  560. int x_off = x1 - x;  
  561. int y_off = y1 - y;  
  562.   
  563. // compute number of columns and rows to blit  
  564. int dx = x2 - x1 + 1;  
  565. int dy = y2 - y1 + 1;  
  566.   
  567. // compute starting address in video_buffer   
  568. video_buffer += (x1 + y1*640);  
  569.   
  570. // compute starting address in bitmap to scan data from  
  571. bitmap += (x_off + y_off*width);  
  572.   
  573. // at this point bitmap is pointing to the first pixel in the bitmap that needs to  
  574. // be blitted, and video_buffer is pointing to the memory location on the destination  
  575. // buffer to put it, so now enter rasterizer loop  
  576.   
  577. UCHAR pixel; // used to read/write pixels  
  578.   
  579. for (int index_y = 0; index_y < dy; index_y++)  
  580.      {  
  581.      // inner loop, where the action takes place  
  582.      for (int index_x = 0; index_x < dx; index_x++)  
  583.           {  
  584.           // read pixel from source bitmap, test for transparency and plot  
  585.           if ((pixel = bitmap[index_x]))  
  586.               video_buffer[index_x] = pixel;  
  587.   
  588.           } // end for index_x   
  589.        
  590.           // advance pointers   
  591.           video_buffer+=640;   // bytes per scanline  
  592.           bitmap      +=width; // bytes per bitmap row  
  593.   
  594.      } // end for index_y   
  595.   
  596. // end Blit_Clipped  



    //==============================================================================
    备注::
    1>见很多地方转过这篇文章,但我试了怎么不行呢?难道用的不对?得好好研究一下.

    现在只能贴整个OVERLAY过去了,但OVERLAY上不全部贴图,只贴那部分要显示的图片。不知道有没什么后遗症!!!


 

原创粉丝点击