2012-01-02 17 views
7

Tôi có một chương trình sử dụng lệnh gọi Sleep Win32 API để tạo một chuỗi chờ một khoảng thời gian cụ thể.
Tóm lại, nó mô phỏng máy ảnh bằng cách gửi hình ảnh được tìm nạp trước trong bộ nhớ. Tôi đang sử dụng Sleep để mô phỏng tốc độ khung hình - Sleep(1000/fps)Hành vi lạ 'Ngủ' giữa các hệ thống

Điều này làm việc tốt trong hệ thống phát triển của tôi (Intel i5 (thế hệ thứ nhất), Win7 64), nhưng khi chạy trên hệ thống khác (Intel i7-2600 - SandyBridge), thời gian ngủ hoàn toàn khác và không chính xác.

Ví dụ, Sleep(16) ngủ khoảng 32ms
Sleep(3) ngủ cho 16ms

Trong quá khứ tôi nghĩ đã có một thời gian ngủ tối thiểu trong các cửa sổ của 15ms nhưng tôi không nhận được rằng giới hạn trên hệ thống dev của tôi.

Bất kỳ ý tưởng nào?

Ngoài ra, có cách nào tốt hơn để đạt được tốc độ khung hình của trình mô phỏng của tôi không?

+0

Bạn đang nói về Win32 [ 'Sleep'] (Hàm http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298.aspx) hoặc hàm C ['ngủ'] (http://pubs.opengroup.org/onlinepubs/009604599/functions/sleep.html) (lưu ý vỏ của 's')? Mô tả của bạn gợi ý ở đầu tiên, thẻ chính tả/đặt tên và (thay vì chung chung) ở thẻ còn lại. –

+0

@ Christian.K - Win32 'Sleep' – Itsik

Trả lời

7

Chức năng sleep đảm bảo rằng bạn sẽ ngủ ít nhất số tiền được chỉ định trong cuộc gọi. Nó khiến cho chuỗi bị treo, cho phép chuyển sang các luồng khác (được điều chỉnh bởi các ưu tiên luồng) khi giải trí của bộ lập lịch. Nói cách khác, chủ đề ngủ là không phải được bảo đảm để chạy ngay lập tức sau thời gian đã chỉ định đã trôi qua, do đó, nên sử dụng sleep để tránh thời gian chính xác trong trường hợp chung.

Có nhiều cách để ngủ chính xác hơn trên Windows. Bạn có thể gọi timeGetDevCaps để xác định độ phân giải bộ hẹn giờ được hỗ trợ tối thiểu, sau đó gọi timeBeginPeriod một lần trong ứng dụng của bạn để đặt độ phân giải bộ hẹn giờ ở mức tối thiểu. Hãy chắc chắn gọi timeEndPeriod trước khi ứng dụng của bạn thoát.

Để biết thêm thông tin, hãy xem the Sleep function on MSDN.

+0

Tôi đã thử chạy' timeBeginPeriod' nhưng nó không ảnh hưởng đến thời lượng. – Itsik

+0

Bạn có chắc chắn rằng nó đã thành công, tức là trả về 'TIMERR_NOERROR' [như được mô tả trên MSDN] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624 (v = vs.85) .aspx)? –

1

Thay vì dựa vào hành vi ngủ không chính xác hoặc nền tảng chức năng hẹn giờ cụ thể (có thể hoạt động tốt, tôi không biết), bạn có thể cấu trúc như vòng lặp trò chơi.

Bên trong vòng lặp, bạn gọi hàm để cung cấp cho bạn thời gian hiện tại. Bạn tìm ra thời gian đã trôi qua kể từ khi bạn vẽ khung hình cuối cùng và quyết định thời điểm hiển thị chính xác khung tiếp theo vào đúng thời điểm. Trong quá trình phát triển, bạn nên đo số khung hình thực tế mỗi giây và hiển thị nó.

Với cách tiếp cận này, tt dễ dàng hơn để làm cho nền tảng mã chéo của bạn và chính xác hơn. Ngoài ra vòng lặp của bạn là trong kiểm soát hơn là cấu trúc mã của bạn như là callbacks hẹn giờ mà bạn cũng có thể thích.

Điểm bất lợi là vòng lặp "bận chờ" có nghĩa là quá trình của bạn sẽ sử dụng CPU mọi lúc không cần thiết. Để giảm thiểu mà bạn có thể mang lại cho CPU trong vòng lặp của bạn bằng cách bơm một cách rõ ràng các sự kiện giao diện người dùng theo một cách nào đó hoặc có thể sử dụng một giấc ngủ ngắn hơn :-).

Nếu bạn muốn tìm hiểu thêm về cách tiếp cận này, hãy bắt đầu googling cho tài liệu trên các vòng trò chơi.

Dưới đây là một số liên kết cần thiết:

http://www.koonsolo.com/news/dewitters-gameloop/

http://gafferongames.com/game-physics/fix-your-timestep/

Và một cuộc thảo luận về SO:

https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step