Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 13 kết quả

Đề tài: Làm sao để ko bị nháy khi cập nhập thông tin của 1 cửa sổ win32

  1. #1
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,006

    Mặc định Làm sao để ko bị nháy khi cập nhập thông tin của 1 cửa sổ win32

    Mình làm 1 cửa số win32 đơn giản và viết thông tin lên đó,
    Nhưng vấn đề mình gặp đó là khi thông tin được cập nhập thì bị nháy do cơ chế của thằng nvalidateRect , nó xóa màn hình , flush, rồi vẽ lại flush , do có 2 cái flush đó nên sẽ có cảm giác nháy nháy.
    Đây là code của mình, bạn có thể chỉ mình có cách nào để loại bỏ tình trạng này ko?
    C Code:
    1. #include <windows.h>
    2. #include <vmlog.h>
    3. #include <stdio.h>
    4. static VMINT   xdebug; //x      //for debug solution
    5. static VMINT   ydebug; //y      //for debug solution
    6. static VMUINT16   cdebug; //color     //for debug solution
    7. static VMINT   pdebug; //pen     //for debug solution
    8. static VMINT   kedebug;//key event    //for debug solution
    9. static VMINT   kcdebug;//key code    //for debug solution
    10. static VMINT   pgfdebug;//pointer game frame //for debug solution
    11. static VMINT   pmmdebug;//pointer main menu //for debug solution
    12. static VMINT   phodebug;//pointer hold on  //for debug solution
    13. static VMWCHAR   debugbuff[200];     //for debug solution
    14. static HWND    hwnd;       //for debug solution
    15. static HWND    hw_pgf;
    16. static struct _debugnode
    17. {
    18.  WCHAR name[30];
    19.  void *data;
    20.  int  type;
    21. } dnode[20];
    22. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    23. {
    24.  PAINTSTRUCT ps;
    25.  HDC hdc;
    26.  RECT rt;
    27.  static WCHAR xau[100];
    28.  HFONT font;
    29.  PLOGFONT plf;
    30.  int y;
    31.  static WCHAR peneventxt[][30]={
    32.   L"0",
    33.   L"Tap",
    34.   L"Release",
    35.   L"Move",
    36.   L"Long",
    37.   L"Double",
    38.   L"Repeat",
    39.  };
    40.  static WCHAR keyeventtxt[][30]={
    41.   L"0",
    42.   L"E.Up",
    43.   L"E.Down",
    44.   L"E.Long",
    45.   L"E.Repeat",
    46.  };
    47.  
    48.  switch (message)
    49.  {
    50.  case WM_COMMAND:
    51.   break;
    52.  case WM_TIMER:
    53.   {
    54.    //HANDLE h=FindWindowA("V","V");
    55.   // if (h==NULL) WndProc(hWnd,WM_DESTROY,0,0);
    56.   }
    57.   InvalidateRect(hwnd,NULL,TRUE);
    58.   //SendMessage(hwnd,WM_NCPAINT,1,0);
    59.   break;
    60.  case WM_PAINT:
    61.  
    62.   hdc = BeginPaint(hWnd, &ps);
    63.   GetClientRect(hWnd, &rt);
    64.   SetBkMode(hdc,TRANSPARENT);
    65.  
    66.   plf=(PLOGFONT)LocalAlloc(LPTR, sizeof(LOGFONT));
    67.   lstrcpyA(plf->lfFaceName, "Arial");
    68.   plf->lfWeight = FW_NORMAL;
    69.   plf->lfHeight=26;
    70.   font = CreateFontIndirect(plf);
    71.   SelectObject(hdc,font);
    72.   //title
    73.   wcscpy(xau,L"Th\xF4ng tin g\x1EE1 r\x1ED1i");
    74.   SetTextColor(hdc,RGB(255,0,0));
    75.   ExtTextOutW(hdc,(rt.right-rt.left-150)/2,10,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    76.  
    77.   //line under title
    78.   MoveToEx(hdc, 0, 40, NULL);
    79.   LineTo(hdc, rt.right-rt.left, 40);
    80.  
    81.   //reset font
    82.   plf=(PLOGFONT)LocalAlloc(LPTR, sizeof(LOGFONT));
    83.   lstrcpyA(plf->lfFaceName, "Arial");
    84.   plf->lfWeight = FW_BOLD;
    85.   plf->lfHeight=16;
    86.   font = CreateFontIndirect(plf);
    87.   SelectObject(hdc,font);
    88.   SetTextColor(hdc,RGB(166,42,44));
    89.   //Ve trai
    90.   y=50;
    91.   wcscpy(xau,L"Pointer game frame");
    92.   ExtTextOutW(hdc,rt.left+5,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    93.   wcscpy(xau,L":");
    94.   ExtTextOutW(hdc,rt.left+135,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    95.   wsprintfW(xau,L"%d",pgfdebug);
    96.   ExtTextOutW(hdc,rt.left+145,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    97.   y+=20;
    98.   wcscpy(xau,L"Pointer main menu");
    99.   ExtTextOutW(hdc,rt.left+5,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    100.   wcscpy(xau,L":");
    101.   ExtTextOutW(hdc,rt.left+135,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    102.   wsprintfW(xau,L"%d",pmmdebug);
    103.   ExtTextOutW(hdc,rt.left+145,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    104.   y+=20;
    105.   wcscpy(xau,L"Pointer hold on");
    106.   ExtTextOutW(hdc,rt.left+5,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    107.   wcscpy(xau,L":");
    108.   ExtTextOutW(hdc,rt.left+135,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    109.   wsprintfW(xau,L"%d",phodebug);
    110.   ExtTextOutW(hdc,rt.left+145,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    111.   y+=20;
    112.   wcscpy(xau,L"Key event/Key code");
    113.   ExtTextOutW(hdc,rt.left+5,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    114.   wcscpy(xau,L":");
    115.   ExtTextOutW(hdc,rt.left+135,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    116.   wsprintfW(xau,L"%s/%d",keyeventtxt[kedebug],kcdebug);
    117.   ExtTextOutW(hdc,rt.left+145,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    118.   y+=20;
    119.  
    120.   //ve phai
    121.   y=50;
    122.   wcscpy(xau,L"Pen");
    123.   ExtTextOutW(hdc,rt.right-100,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    124.   wcscpy(xau,L":");
    125.   ExtTextOutW(hdc,rt.right-60,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    126.    wsprintfW(xau,L"%s",peneventxt[pdebug]);
    127.   ExtTextOutW(hdc,rt.right-50,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    128.   y+=20;
    129.  
    130.   wcscpy(xau,L"X");
    131.   ExtTextOutW(hdc,rt.right-100,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    132.   wcscpy(xau,L":");
    133.   ExtTextOutW(hdc,rt.right-60,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    134.   wsprintfW(xau,L"%d",xdebug);
    135.   ExtTextOutW(hdc,rt.right-50,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    136.   y+=20;
    137.   wcscpy(xau,L"Y");
    138.   ExtTextOutW(hdc,rt.right-100,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    139.   wcscpy(xau,L":");
    140.   ExtTextOutW(hdc,rt.right-60,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    141.   wsprintfW(xau,L"%d",ydebug);
    142.   ExtTextOutW(hdc,rt.right-50,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    143.   y+=20;
    144.   wcscpy(xau,L"Color");
    145.   ExtTextOutW(hdc,rt.right-100,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    146.   wcscpy(xau,L":");
    147.   ExtTextOutW(hdc,rt.right-60,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    148.   wsprintfW(xau,L"0x%X",cdebug);
    149.   ExtTextOutW(hdc,rt.right-50,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    150.   y+=20;
    151.   MoveToEx(hdc,rt.right-105, 40, NULL);
    152.   LineTo(hdc, rt.right-105, y);
    153.   //line under
    154.   MoveToEx(hdc, 0, y, NULL);
    155.   LineTo(hdc, rt.right-rt.left, y);
    156.  
    157.   {
    158.    int i;
    159.    
    160.    for (i=0,y=140;i<20;i++,y+=20)
    161.    {
    162.     switch(dnode[i].type)
    163.     {
    164.     case DEBUG_CARE_INT:
    165.      wsprintfW(xau,L"%d. %s %d",i+1,dnode[i].name,*((int *)dnode[i].data));
    166.      break;
    167.     case DEBUG_CARE_CHAR:
    168.      wsprintfW(xau,L"%d. %s %d",i+1,dnode[i].name,*((char *)dnode[i].data));
    169.      break;
    170.     case DEBUG_CARE_WCHAR:
    171.      wsprintfW(xau,L"%d. %s %d",i+1,dnode[i].name,*((WCHAR *)dnode[i].data));
    172.      break;
    173.     case DEBUG_CARE_FLOAT:
    174.      wsprintfW(xau,L"%d. %s %f",i+1,dnode[i].name,*((float *)dnode[i].data));
    175.      break;
    176.     case DEBUG_CARE_DOUBLE:
    177.      wsprintfW(xau,L"%d. %s %lf",i+1,dnode[i].name,*((double *)dnode[i].data));
    178.      break;
    179.     case DEBUG_CARE_STR:
    180.      wsprintfW(xau,L"%d. %s %s",i+1,dnode[i].name,(char *)dnode[i].data);
    181.      break;
    182.     case DEBUG_CARE_WSTR:
    183.      wsprintfW(xau,L"%d. %s %s",i+1,dnode[i].name,(WCHAR *)dnode[i].data);
    184.      break;
    185.     default:
    186.      wsprintfW(xau,L"%d.",i+1);
    187.      break;
    188.     }
    189.     ExtTextOutW(hdc,rt.left+5,y,ETO_CLIPPED,&rt,xau,wcslen(xau),NULL);
    190.    }
    191.   }
    192.  
    193.  
    194.   EndPaint(hWnd, &ps);
    195.   break;
    196.  case WM_DESTROY:
    197.   {
    198.    DWORD pid;
    199.    HANDLE hdl;
    200.    GetWindowThreadProcessId(hwnd, &pid);
    201.    hdl=OpenProcess(PROCESS_TERMINATE,FALSE,pid);
    202.    TerminateProcess(hdl, 0);
    203.    CloseHandle(hdl);
    204.   }
    205.   vm_exit_app();
    206.   PostQuitMessage(0);
    207.   break;
    208.  default:
    209.   return DefWindowProc(hWnd, message, wParam, lParam);
    210.  }
    211.  return 0;
    212. }
    213. void StartDebugScreen(void)
    214. {
    215.  if (hwnd==NULL)
    216.  {
    217.   MSG msg;
    218.   WNDCLASSA wcex;
    219.   HINSTANCE hInstance=0;
    220.  
    221.  
    222.   wcex.style   = CS_HREDRAW | CS_VREDRAW;
    223.   wcex.lpfnWndProc = (WNDPROC)WndProc;
    224.   wcex.cbClsExtra  = 0;
    225.   wcex.cbWndExtra  = 0;
    226.   wcex.hInstance  = hInstance;
    227.   wcex.hIcon   = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
    228.   wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
    229.   wcex.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);
    230.   wcex.lpszMenuName = NULL;
    231.   wcex.lpszClassName = "Debug Screen by QuangBT";
    232.   RegisterClassA(&wcex);
    233.   hwnd = CreateWindow("Debug Screen by QuangBT", "Debug Screen by QuangBT", WS_OVERLAPPEDWINDOW,
    234.    800, 100, 400, 600, NULL, NULL, hInstance, NULL);
    235.   if (!hwnd)
    236.   {
    237.    return ;
    238.   }
    239.   ShowWindow(hwnd, SW_SHOWDEFAULT);
    240.   UpdateWindow(hwnd);
    241.   SetTimer(hwnd,1,20,NULL);
    242.   while (GetMessage(&msg, NULL, 0, 0))
    243.   {
    244.    TranslateMessage(&msg);
    245.    DispatchMessage(&msg);
    246.   }
    247.  }
    248. }
    ^_,^

    Tổng hợp các câu chuyện hài hước vui nhộn, sử dụng Speech Synthesis để đọc : https://www.youtube.com/channel/UCLk...Tjrg/playlists


    Bùi Tấn Quang

  2. #2
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    Trong hàm WndProc, bạn bắt thêm sự kiện như thế này :
    C Code:
    1.  case  WM_ERASEBKGND:
    2.      return 1;
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

  3. #3
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,006

    Hi Mèo,
    nếu làm như thế thì ko ổn, vì khi có 1 cái gì đó di chuyển qua của sổ đó, nó sẽ vấn còn
    ^_,^

    Tổng hợp các câu chuyện hài hước vui nhộn, sử dụng Speech Synthesis để đọc : https://www.youtube.com/channel/UCLk...Tjrg/playlists


    Bùi Tấn Quang

  4. #4
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    Trường hợp của bạn khá đặc thù vì timer cập nhật liên tục trong khoảng thời gian rất ngắn. Cho dù sự kiện xóa nền ko xảy ra thì cũng đã có timer buộc nó phải vẽ lại rồi.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

  5. #5
    Ngày gia nhập
    03 2010
    Nơi ở
    My Home
    Bài viết
    772

    InvalidateRect không đạt được high performance đâu. Cái này chỉ "lừa" được mắt người trên một vùng chữ nhật nhỏ thui. Nếu gọi xóa toàn bộ cửa sổ khác to thì nháy là điều chắc chắn.

    Tốt nhất là lưu chuỗi khi trước vừa hiển thị ra, khi muốn vẽ chữ mới thì vẽ đè chữ cũ với màu trùng với màu nền, sau đó vẽ thông tin mới bằng màu mới và lưu lại để lần sau xóa (vẽ đè lên)

    Demo

    C Code:
    1. #include <windows.h>
    2. #include <stdlib.h>
    3. #include <time.h>
    4.  
    5. #define x_block     6
    6. #define y_block     6
    7.  
    8. char msg[x_block * y_block][200] = {0};
    9. void paint(HWND wd, HDC hdc)
    10. {
    11.     int x, y, z;
    12.     int x_step, y_step;
    13.     int len;   
    14.     RECT rect;
    15.     int count = 0;
    16.  
    17.     GetClientRect(wd, &rect);
    18.     x_step = (rect.right - rect.left) / x_block;
    19.     y_step = (rect.bottom - rect.top) / y_block;   
    20.     for(x = 0; x < x_block; x++)
    21.     {
    22.         MoveToEx(hdc, x * x_step, rect.top, NULL);
    23.         LineTo(hdc, x * x_step, rect.bottom);
    24.     }
    25.     for(y = 0; y < y_block; y++)
    26.     {
    27.         MoveToEx(hdc, rect.left, y * y_step, NULL);
    28.         LineTo(hdc, rect.right, y * y_step);
    29.     }
    30.  
    31.     for(y = 0; y < y_block; y++)
    32.     {
    33.         for(x = 0; x < x_block; x++)
    34.         {
    35.             SetRect(&rect, x * x_step, y * y_step, (x + 1) * x_step, (y + 1) * y_step);
    36.             //clear prevous message
    37.             SetTextColor(hdc,RGB(0xff, 0xff, 0xff));
    38.             DrawText(hdc, msg[count + x], -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    39.  
    40.             //make a random message
    41.             len = rand() % 5 + 4;
    42.             for(z = 0; z < len; z++)
    43.                 msg[count + x][z] = rand() % 128;
    44.             msg[count + x][len] = 0;
    45.  
    46.             //show the new message
    47.             SetTextColor(hdc, RGB(0x00, 0x00, 0x00));
    48.             DrawText(hdc, msg[count + x], -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    49.         }
    50.         count += y_block;
    51.     }
    52. }
    53. LRESULT __stdcall windowprocedure(HWND wd, UINT message, WPARAM wp, LPARAM lp)
    54. {
    55.     char msg[20] = {0};
    56.     switch(message)
    57.     {
    58.     case WM_CREATE:
    59.         srand(time(NULL));
    60.         SetTimer(wd, 1, 100, NULL);
    61.         break;
    62.     case WM_TIMER:
    63.         {
    64.             HDC hdc = GetDC(wd);
    65.             paint(wd, hdc);
    66.             ReleaseDC(wd, hdc);
    67.         }
    68.         break;
    69.     case WM_DESTROY:
    70.         KillTimer(wd, 1);
    71.         PostQuitMessage(0);
    72.         break;
    73.     default:
    74.         break;
    75.     }
    76.     return DefWindowProc(wd, message, wp, lp);
    77. }
    78. int __stdcall WinMain(HINSTANCE inst, HINSTANCE pre_inst, char* cmdline, int cmdshow)
    79. {
    80.     MSG msg;
    81.     HWND wd;
    82.     WNDCLASS wc = {0};
    83.     static TCHAR clname[] = "Test";
    84.     unsigned long w_default = CW_USEDEFAULT;
    85.  
    86.     wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    87.     wc.hInstance = inst;
    88.     wc.hCursor = LoadCursor(NULL, NULL);
    89.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    90.     wc.lpfnWndProc = windowprocedure;
    91.     wc.lpszClassName = clname;
    92.     wc.hbrBackground = (HBRUSH)GetStockObject(COLOR_3DFACE);
    93.    
    94.     RegisterClass(&wc);
    95.     wd = CreateWindow(clname, "Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, w_default, w_default, w_default,
    96.                       NULL, NULL, inst, NULL);
    97.     UpdateWindow(wd);
    98.     ShowWindow(wd, cmdshow);
    99.     while(GetMessage(&msg, NULL, 0, 0) > 0)
    100.     {
    101.         TranslateMessage(&msg);
    102.         DispatchMessage(&msg);
    103.     }
    104.     return (int)msg.wParam;
    105. }

  6. #6
    Ngày gia nhập
    03 2008
    Bài viết
    71

    Mặc định Làm sao để ko bị nháy khi cập nhập thông tin của 1 cửa sổ win32

    Thường người ta phải vẽ vào một bitmap trong bộ nhớ, rồi copy nguyên cái bitmap đó ra màn hình. Tức chỉ có 1 thao tác vẽ ra màn hình mà thôi. Thậm chí có thể là double buffer, tức dùng 2 bitmap, thao tác vẽ và copy ra màn hình được làm xen kẽ, trong lúc vẽ lên bitmap1 thì copy bitmap2 ra màn hình, rồi đổi lại.

  7. #7
    Ngày gia nhập
    03 2010
    Nơi ở
    My Home
    Bài viết
    772

    Trích dẫn Nguyên bản được gửi bởi namdh Xem bài viết
    Thường người ta phải vẽ vào một bitmap trong bộ nhớ, rồi copy nguyên cái bitmap đó ra màn hình. Tức chỉ có 1 thao tác vẽ ra màn hình mà thôi. Thậm chí có thể là double buffer, tức dùng 2 bitmap, thao tác vẽ và copy ra màn hình được làm xen kẽ, trong lúc vẽ lên bitmap1 thì copy bitmap2 ra màn hình, rồi đổi lại.
    Đó là cậu đang nói ở High performance thế thì dùng OpenGL, DirectX luôn cho xong. Còn cái mà cậu làm 2 bitmap (thực ra là front buffer & backbuffer) mà định xài trên Device Context (DC) của Windows này thì còn .... chậm hơn

  8. #8
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    Cơ chế double buffering kết hợp với chia thành các widget là một cách rất hiệu quả mà nhiều frameworks có tiếng như GTK, QT áp dụng. Để hiểu rõ hơn có thể đọc thêm về GTK+ Drawing Model và QT Paint Engine sẽ có nhiều phần, nhiều tác giả nói về việc này rất chi tiết.

    Về cơ bản để xử lý việc giật hình bạn cần tạo ra một offscreen bitmap bằng hàm CreateCompatibleBitmap, một memory DC bằng CreateCompatibleDC. Tất cả việc draw của bạn được tiến hành trên cái Memory DC này, cuối cùng sử dụng BitBlt để đưa sang Window DC, cái DC mà bạn muốn hiển thị lên màn hình.

    Để có thể giải quyết vấn đề về performance thì nên sử dụng một cơ chế caching nữa. bạn cần chú ý xử lý khi resize window nếu sử dụng caching.
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  9. #9
    Ngày gia nhập
    03 2008
    Bài viết
    71

    Trích dẫn Nguyên bản được gửi bởi namdq2k Xem bài viết
    Đó là cậu đang nói ở High performance thế thì dùng OpenGL, DirectX luôn cho xong. Còn cái mà cậu làm 2 bitmap (thực ra là front buffer & backbuffer) mà định xài trên Device Context (DC) của Windows này thì còn .... chậm hơn
    Nếu không dùng buffer thì sẽ tồn tại 2 thao tác vẽ trên màn hình, mắt người sẽ cảm nhận 2 hình ảnh khác nhau, đó là lý do làm hình ảnh bị nháy, vì bạn phải có 1 thao tác xóa nền, rồi mới tới vẽ. Khi vùng được vẽ đủ nhỏ, tốc độ vẽ nhanh bạn sẽ không nhìn thấy, nhưng khi xóa và vẽ lại cả cửa số, nó sẽ bị nhấp nháy.
    Dùng buffer là cách thông thường trong trường hợp này, chẳng có gì cao siêu hay high performance cả. Nên nhớ khi vẽ trong buffer, bạn chỉ truyền dữ liệu từ memory -> memory, vốn nhanh hơn rất nhiều so với memory -> graphics memory.
    Buffer trong các cơ chế khác như DirectX có hiệu năng cao hơn rất nhiều, không so sánh với cách dùng buffer trong memory và vẽ vào DC được. Ở đó, bạn sẽ map thẳng vào graphics memory (video memory), vẽ ảnh trên đó, khi cần hiển thị ảnh nào, chỉ việc yêu cầu GPU chuyển window đến vùng nhớ đó (hoàn toàn không cần copy dữ liệu). Bạn có thể vẽ trước hàng chục ảnh (tùy vào kích thước bộ nhớ của video card), đồng thời yêu cầu video card chuyển window để hiển thị các hình ảnh tốc độ cao (game, video...)

  10. #10
    Ngày gia nhập
    03 2010
    Nơi ở
    My Home
    Bài viết
    772

    Trích dẫn Nguyên bản được gửi bởi namdh Xem bài viết
    Nếu không dùng buffer thì sẽ tồn tại 2 thao tác vẽ trên màn hình, mắt người sẽ cảm nhận 2 hình ảnh khác nhau, đó là lý do làm hình ảnh bị nháy, vì bạn phải có 1 thao tác xóa nền, rồi mới tới vẽ. Khi vùng được vẽ đủ nhỏ, tốc độ vẽ nhanh bạn sẽ không nhìn thấy, nhưng khi xóa và vẽ lại cả cửa số, nó sẽ bị nhấp nháy.
    Nguyên tắc thì là thế!!!
    Dùng buffer là cách thông thường trong trường hợp này, chẳng có gì cao siêu hay high performance cả. Nên nhớ khi vẽ trong buffer, bạn chỉ truyền dữ liệu từ memory -> memory, vốn nhanh hơn rất nhiều so với memory -> graphics memory.
    Và sẽ kèm theo một đống thứ nảy sinh nếu không case hết trường hợp. Lúc làm cái memory bitmap kích cỡ A, lúc đẩy ra thì cửa sổ nó có kích cỡ là B. Các font chữ ở trên cửa sổ thì không bị resize với bất kỳ kích cỡ cửa sổ như nào. Nhưng dữ liệu đưa ra là một bức ảnh đẩy lên màn hình khác với lúc đầu tạo memory bitmap thì việc này xử lý hơi khoai đấy ... Vì lúc này font chữ viết ra sẽ bị to hay nhỏ không đúng kích cỡ chữ...

    Cái chuyện nhanh chậm của việc làm 2 bitmap là từ thời trung cổ rùi. Vấn đề xử lý những tình huống phát sinh như tui nêu kia mới chuối kìa. Và không khéo nó còn làm chậm hơn (không hi vọng như thế) là tui muốn nói ở trên đó.

    Làm được, nhưng mà chưa chắc đã hay. Chỉ với text không thôi thì chưa chắc cần thiết. Đôi khi còn chậm.

    Buffer trong các cơ chế khác như DirectX có hiệu năng cao hơn rất nhiều, không so sánh với cách dùng buffer trong memory và vẽ vào DC được. Ở đó, bạn sẽ map thẳng vào graphics memory (video memory), vẽ ảnh trên đó, khi cần hiển thị ảnh nào, chỉ việc yêu cầu GPU chuyển window đến vùng nhớ đó (hoàn toàn không cần copy dữ liệu). Bạn có thể vẽ trước hàng chục ảnh (tùy vào kích thước bộ nhớ của video card), đồng thời yêu cầu video card chuyển window để hiển thị các hình ảnh tốc độ cao (game, video...)
    Còn nếu phải làm double buffering thì thà làm trên OpenGL, DirectX luôn cho nó lành mạnh. Về cơ bản nó xử lý ngon cách tình huống và đạt high performance

    *Cái high performance ở đây không phải là cái gì quá xa xôi, mà nó chỉ ở mức: Không nhức mắt mà thui

Các đề tài tương tự

  1. Mã nguồn C Lỗi Hàm WIN32 API- Truy nhập sector trên đĩa
    Gửi bởi mask_of_zorro trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 4
    Bài viết cuối: 20-04-2012, 07:19 PM
  2. có ứng dụng nào mà win32 api làm được mà c# ko làm được ko?
    Gửi bởi ChickenInTech trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 5
    Bài viết cuối: 28-02-2012, 09:13 PM
  3. Dẫn nhập vào lập trình Win32 api
    Gửi bởi langman trong diễn đàn Tutorials và Thủ thuật Visual C++
    Trả lời: 9
    Bài viết cuối: 28-07-2011, 08:54 PM
  4. Lập trình win32 API | Xử lý nhấp chuột vào các item trong listbox?
    Gửi bởi haba trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 1
    Bài viết cuối: 08-04-2009, 12:45 PM
  5. Win32.DLL ???
    Gửi bởi gabygabby trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 2
    Bài viết cuối: 23-03-2009, 04:21 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn