C++遊戲介面不流暢的問題

來源:互聯網
上載者:User

標籤:void   font   鍛煉   開頭   count   一點   double   著色器   世界   

或許是我遊戲玩多了,我突然發現,我的C++程式畫面畫面一頓一頓的,不流暢.肯定哪裡不正確,要改.奇怪啊,為什麼我曾經,在我電腦上就不這麼卡,就看不出畫面一頓一頓的呢?

百度了,狗狗了,必應了,然而,並沒有什麼卵用.

扭頭問老大,老大一聲令下:不許問別人,這個問題單獨解決,順便提交個解決方式我.

的確,人須要有解決這個問題的能力,這一點非常重要.事實上,最重要的是記性,<<最強大腦>>沒記性再好的分析能力都沒用.

真羨慕你們的好記性...

羨慕雖好,然而,並沒有什麼卵用.還得靠自己多鍛煉.


好了,開始分析問題:問題:我程式裡,用w,s,a,d按鍵控制攝像機的前進,後退,左移,右移.但是,比方,我一直按著w,前進,前進的公式為:        w = 10像素/秒 * 時間長度.現象:一段時間不動,然後突然跳到前面,就像我按著前進按鍵,它不動,然後過會兒突然閃現到前面...一直這樣,畫面一愣一愣的...猜想:是不是我近期改了什麼代碼所致?

對,我近期是加入了著色器程式,那我執行沒有著色器的程式試試看

         結果:一樣,一愣一愣的,並且別的項目也一樣.         結論:跟新改動的代碼有關係可能性不大.繼續猜想:可能 win32程式中訊息迴圈那兒 timedelta有問題    代碼例如以下所看到的:
void Application::Run(){MSG msg;static float lastTime = (float)timeGetTime();//上一次的時間ZeroMemory(&msg, sizeof(MSG));while (msg.message != WM_QUIT){if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}else{float currTime = (float)timeGetTime();//當前的時間float timedelta = (currTime - lastTime)*0.001f;//時間間隔//世界更新m_GameWorld->Update((float)timedelta);//更新fpsUpdateFPS();//畫一幀DrawOneFrame();lastTime = currTime;}}}
下斷點觀察 timedelta 變數是不切實際的,由於訊息迴圈速度很很快,僅僅有幾毫秒甚至僅僅有幾微秒!!!那怎麼觀察timedelta變數的變化呢?老大說用控制台來輸出這個變數.沒搞錯吧...win32  MFC表單怎麼用控制台,特麼逗我麼.沒文化真可怕.一搜,果然有win32上附加產生一個控制台的方法,步驟:1.加標頭檔:#include <conio.h>     2.程式的開頭加函數:AllocConsole();     3.在要輸出變數的地方加:_cprintf("timedelta = %f\n", timedelta);     4.程式的最後釋放分配的控制台:FreeConsole();

ok,配置完成,趕緊看下輸出資料吧:

    結果:

    

     一大堆的0.000000,然後突然0.128000

    結論:罪魁禍首原來在這裡,這就是導致不孕不...不是,呸,導致畫面不平滑,一愣一愣的根本原因.

其它時候都是0,突然0.128大動一下,問題的根本原因已經找到.這就是導致顯示不連續的原因.疑惑:訊息迴圈run函數為什麼資料會不連續?

更新,渲染,一圈下來時間竟然為0?

怎麼可能...

猜想:我用的資料類型是float,精度難道不夠用嗎?粗略預計下,畫面fps在2000左右.也就是0.5毫秒一幀,          也就是0.0005秒應該沒超過float的精度範圍啊...          出於好奇,還是換了雙精確度的double試了一下,         然而,並沒有什麼卵用.          說明不是精度的緣故.繼續猜想:或許跟timeGetTime這個擷取時間的函數有關係,吾查詢了網上大量的文獻資料,發現它擷取的時間精度也不高誤差幾十,甚至幾百毫秒,我就說嘛,遠遠達不到這台電腦的fps需求嘛(公司電腦配置太好,fps能上萬,也就是誤差要在0.1毫秒之內)我明確了...這也是為什麼在我自己垃圾電腦上發覺不出來一愣一愣的原因了,由於我電腦配置太低,效果不明顯...附公司電腦配置圖:(裝B,莫打我...)

所以尋找高精度的計時函數QueryPerformanceFrequency()和QueryPerformanceCounter()

這兩函數牛逼啊,根硬體時鐘的晶振是一個層級的,資料上說,精確到了千分之中的一個毫秒,也就是微秒層級的...

好啊,要的就是你啊....


下面便是改動的訊息迴圈run的代碼:

void Application::Run(){MSG msg;LARGE_INTEGER nFreq;LARGE_INTEGER nBeginTime, nEndTime;QueryPerformanceFrequency(&nFreq);//獲得時鐘頻率QueryPerformanceCounter(&nBeginTime);//開始的時間ZeroMemory(&msg, sizeof(MSG));while (msg.message != WM_QUIT){if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}else{QueryPerformanceCounter(&nEndTime);//結束的時間 float timedelta = (float)(nEndTime.QuadPart - nBeginTime.QuadPart) / (float)nFreq.QuadPart;_cprintf("timedelta = %f\n", timedelta);//控制台輸出結果//世界更新m_GameWorld->Update((float)timedelta);//d3d裝置指標一個項目裡僅僅能有唯一一個UpdateFPS();//畫一幀DrawOneFrame();nBeginTime = nEndTime;}}}
結果:

     

唉,整個人心情都好了,攝像機移動,畫面流暢得一筆啊...

另外,說到時間,我就想到了晶振,說到晶振,我就想到了15萬元一僅僅的萬國牌手錶,心想,貴有什麼用,准麼?說到准,我想起了世界上最準的鐘---原子鐘:有銫原子鐘,氫原子鐘,銣原子鐘,CPT原子鐘,呀的,這玩意50億年誤差只是1秒...唉,人類真聰明,真可怕,說到聰明可怕...然而,並沒有什麼卵用,不能再說了,扯太遠了,到此為止~!
??

C++遊戲介面不流暢的問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.