windows遊戲編程大師技巧2學習感悟(1)

          我一向是伸手黨,只愛看別人的,從來不回覆,更不用說自己寫了。但是最近的學習經歷讓我覺得很有必要寫出來,一是用來提醒自己以後再碰到類似的問題又忘了解決辦法的時候,二是確實的體會到了當遇到困難用盡各種辦法都解決不了的時候那種無力和懊惱感。

 

          最近剛看完windows遊戲編程大師技巧技巧的第二版,覺得有必要自己也寫一遍實現出來,不然到底掌握了沒有心裏根本沒底。這本書由於距離現在有些年代了,所以可能是因爲歷史原因,一些API函數調用在IDE裏各種出問題。

 

         昨晚到現在一直都在解決繪製位圖的問題,剛剛終於憑藉自己的聰明才智給解決了(哈哈哈),心裏那股爽勁甭提了。書裏第7章的7.75載入24位位圖的DEMO7——12.cpp裏出現了兩個重大問題,有一個網上搜了半天勉強解決了,但是沒人給出原因。就是_lseek(file_handle,-(long)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END)這個函數,意思很明顯,把文件指針定位到圖像數據之前,怎麼看怎麼對,編譯也通過了,一運行就是出錯,網上找不到答案,希望有高手看到這篇文章的時候能給小弟一個答案,在這裏先謝過您了:)

 

       第二個問題,我覺得是作者犯錯了,爲什用我覺得,首先沒看到網上有人提出質疑,第二這本書都出這麼久了也再版了難道作者和出版社沒發現?我不確定。。。但是這個問題確實是存在的,還是這個cpp裏,Game_Main函數中用於把bitmap.buffer中的圖像數據填充到primary_buffer中時所用的循環,原來的cpp中是這麼寫的

for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
    {
    for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
        {
        // get BGR values
        UCHAR blue  = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]),
              green = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]),
              red   = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]);

        // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
        DWORD pixel = _RGB32BIT(0,red,green,blue);

        // write the pixel
        primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;

        } // end for index_x

    } // end for index_y

第一遍的時候沒細看,覺得意思差不多就過了,調試的時候斷點到這裏就出錯了,總是非法訪問內存,就認真的看了了一下發現問題了。循環的用意是把圖片數據拷到顯示錶面的內存裏,但是循環設置的x和y的條件是 分別小於屏幕的長寬值,把圖片中對應於屏幕的座標數據複製到顯示錶面上,問題來了。圖片的大小怎麼可能和和屏幕一樣大呢,舉個例子說,假如圖片是100*100的,而屏幕是1024*768,那麼在圖片100*100之外而在屏幕之內的地方這些像素點通通都是不存在圖片上的!那麼通過下標運算讀取圖片中的內存數據當然就非法了,不是典型的越界嗎!應該只是把圖片的數據拷到屏幕上,那麼應該改兩個地方。一是index_x和index_y的循環條件改成圖片的長寬,即cpp裏的bitmap.bitmapinfoheader.biHeight和bitmap.bitmapinfoheader.biWidth; 二是下標運算裏的SCREEN_WIDTH應該改成圖片的寬度bitmap.bitmapinfoheader.biWidth。下面是我改正之後的

for (int index_y = 0; index_y < bitmap.bitmapinfoheader.biHeight; index_y++)
 {
  for (int index_x = 0; index_x < bitmap.bitmapinfoheader.biWidth; index_x++)
  {
   // get BGR values
   UCHAR blue  = (bitmap.buffer[index_y*(bitmap.bitmapinfoheader.biWidth)*3 + index_x*3 + 0]),
    green = (bitmap.buffer[index_y*(bitmap.bitmapinfoheader.biWidth)*3 + index_x*3 + 1]),
    red   = (bitmap.buffer[index_y*(bitmap.bitmapinfoheader.biWidth)*3 + index_x*3 + 2]);

   // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
   DWORD pixel = _RGB32BIT(0,red,green,blue);

   // write the pixel
   primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;

  } // end for index_x

 } // end for index_y

             改過之後編譯運行都OK。美膩的圖像出乃了:)希望這篇文章能給同樣有困惑的同學提供一點幫助哈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章