談一談Cocos2d-x中的某些“大小”

這裏說的“大小”,包括了以下一些內容:

(1).窗口的大小

(2).分辨率的大小

(3).影幕的大小

(4).視口的大小

(5).裁剪區域的大小

我們先來看(1),窗口的大小

窗口的大小,即是Windows窗體大小。我們以HelloCpp爲例,打開main.cpp,。找到這兩句代碼:

  1. <SPAN style="FONT-FAMILY: SimSun; FONT-SIZE: 14px">CCEGLView* eglView = CCEGLView::sharedOpenGLView();
  2. eglView->setFrameSize(960, 640 );</SPAN>
  1. <SPAN style="FONT-SIZE: 14px; FONT-FAMILY: SimSun">CCEGLView* eglView = CCEGLView::sharedOpenGLView();  
  2. eglView->setFrameSize(960, 640 );</SPAN>  
CCEGLView* eglView = CCEGLView::sharedOpenGLView();
eglView->setFrameSize(960, 640 );

這裏取得了Opengl視窗類CCEGLView單件實例指針返回給指針變量eglView,並調用其setFrameSize函數設置一個所謂的Frame大小。這個大小是神馬東西?進去看看!

進入到CCEGLView.cpp的相應函數:


  1. <SPAN style="FONT-SIZE: 14px">void CCEGLView::setFrameSize(float width, float height)
  2. {
  3. //我們在這裏看到調用了Create函數,這裏傳入的width,height就是要創建的窗口的大小。
  4. Create((LPCTSTR)m_szViewName, (int)width, (int)height);
  5. //後面調用基類的setFrameSize,一會兒再分析,暫略過。
  6. CCEGLViewProtocol::setFrameSize(width, height);
  7. }</SPAN>
  1. <SPAN style="FONT-SIZE: 14px">void CCEGLView::setFrameSize(float width, float height)  
  2. {  
  3.     //我們在這裏看到調用了Create函數,這裏傳入的width,height就是要創建的窗口的大小。   
  4. Create((LPCTSTR)m_szViewName, (int)width, (int)height);  
  5. //後面調用基類的setFrameSize,一會兒再分析,暫略過。   
  6.     CCEGLViewProtocol::setFrameSize(width, height);  
  7. }</SPAN>  
void CCEGLView::setFrameSize(float width, float height)
{
    //我們在這裏看到調用了Create函數,這裏傳入的width,height就是要創建的窗口的大小。
Create((LPCTSTR)m_szViewName, (int)width, (int)height);
//後面調用基類的setFrameSize,一會兒再分析,暫略過。
    CCEGLViewProtocol::setFrameSize(width, height);
}

看一下Create函數:

  1. <SPAN style="FONT-SIZE: 14px">bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
  2. {
  3. bool bRet = false;
  4. do
  5. {
  6. //這裏通過判斷m_hWnd是否有效來確保只Create一次,不允許創建多個窗體。
  7. CC_BREAK_IF(m_hWnd);
  8. //
  9. HINSTANCE hInstance = GetModuleHandle( NULL );
  10. WNDCLASS wc; //窗口類信息結構
  11. //填充信息結構
  12. wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  13. wc.lpfnWndProc = _WindowProc;
  14. wc.cbClsExtra = 0;
  15. wc.cbWndExtra = 0;
  16. wc.hInstance = hInstance;
  17. wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
  18. wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  19. wc.hbrBackground = NULL;
  20. wc.lpszMenuName = NULL;
  21. wc.lpszClassName = kWindowClassName;
  22. //註冊窗口類
  23. CC_BREAK_IF(! RegisterClass(&wc) && 1410 != GetLastError());
  24. //取得電腦屏幕大小矩形
  25. RECT rcDesktop;
  26. GetWindowRect(GetDesktopWindow(), &rcDesktop);
  27. //將窗口標題多字節轉寬字符。
  28. WCHAR wszBuf[50] = {0};
  29. MultiByteToWideChar(CP_UTF8, 0, m_szViewName, -1, wszBuf, sizeof(wszBuf));
  30. // 使用註冊過的窗口類創建窗口
  31. m_hWnd = CreateWindowEx(
  32. WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, // Extended Style For The Window
  33. kWindowClassName, // Class Name
  34. wszBuf, // Window Title
  35. WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX, // Defined Window Style
  36. 0, 0, // Window Position
  37. 0, // Window Width
  38. 0, // Window Height
  39. NULL, // No Parent Window
  40. NULL, // No Menu
  41. hInstance, // Instance
  42. NULL );
  43. //通過窗口句柄有效性判斷確保創建成功才能繼續
  44. CC_BREAK_IF(! m_hWnd);
  45. //重點函數,調整窗口大小
  46. resize(w, h);
  47. //初始化OpenGL
  48. bRet = initGL();
  49. //返回成功判斷
  50. CC_BREAK_IF(!bRet);
  51. //保存單件實例指針
  52. s_pMainWindow = this;
  53. bRet = true;
  54. } while (0);
  55. //返回成敗
  56. return bRet;
  57. }</SPAN>
  1. <SPAN style="FONT-SIZE: 14px">bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)  
  2. {  
  3.     bool bRet = false;  
  4.     do   
  5. {  
  6.             //這裏通過判斷m_hWnd是否有效來確保只Create一次,不允許創建多個窗體。   
  7.                 CC_BREAK_IF(m_hWnd);  
  8.             //   
  9.             HINSTANCE hInstance = GetModuleHandle( NULL );  
  10.             WNDCLASS  wc;       //窗口類信息結構   
  11.   
  12.             //填充信息結構   
  13.             wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;    
  14.             wc.lpfnWndProc    = _WindowProc;                      
  15.             wc.cbClsExtra     = 0;                                
  16.             wc.cbWndExtra     = 0;                                
  17.             wc.hInstance      = hInstance;                        
  18.             wc.hIcon          = LoadIcon( NULL, IDI_WINLOGO );    
  19.             wc.hCursor        = LoadCursor( NULL, IDC_ARROW );    
  20.             wc.hbrBackground  = NULL;                            
  21.             wc.lpszMenuName   = NULL;                            
  22.             wc.lpszClassName  = kWindowClassName;                
  23.             //註冊窗口類   
  24.             CC_BREAK_IF(! RegisterClass(&wc) && 1410 != GetLastError());          
  25.   
  26.             //取得電腦屏幕大小矩形   
  27.             RECT rcDesktop;  
  28.             GetWindowRect(GetDesktopWindow(), &rcDesktop);  
  29.             //將窗口標題多字節轉寬字符。   
  30.             WCHAR wszBuf[50] = {0};  
  31.             MultiByteToWideChar(CP_UTF8, 0, m_szViewName, -1, wszBuf, sizeof(wszBuf));  
  32.   
  33.             // 使用註冊過的窗口類創建窗口   
  34.             m_hWnd = CreateWindowEx(  
  35.                 WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,    // Extended Style For The Window   
  36.                 kWindowClassName,                                    // Class Name   
  37.                 wszBuf,                                                // Window Title   
  38.                 WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX,        // Defined Window Style   
  39.                 0, 0,                                                // Window Position   
  40.                 0,                                                  // Window Width   
  41.                 0,                                                  // Window Height   
  42.                 NULL,                                                // No Parent Window   
  43.                 NULL,                                                // No Menu   
  44.                 hInstance,                                            // Instance   
  45.                 NULL );  
  46.         //通過窗口句柄有效性判斷確保創建成功才能繼續   
  47.         CC_BREAK_IF(! m_hWnd);  
  48.        //重點函數,調整窗口大小   
  49.         resize(w, h);  
  50.         //初始化OpenGL   
  51.         bRet = initGL();  
  52.        //返回成功判斷   
  53.         CC_BREAK_IF(!bRet);  
  54.         //保存單件實例指針   
  55.         s_pMainWindow = this;  
  56.         bRet = true;  
  57.     } while (0);  
  58.     //返回成敗   
  59.     return bRet;  
  60. }</SPAN>  
bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
{
    bool bRet = false;
    do 
{
			//這裏通過判斷m_hWnd是否有效來確保只Create一次,不允許創建多個窗體。
        		CC_BREAK_IF(m_hWnd);
			//
			HINSTANCE hInstance = GetModuleHandle( NULL );
			WNDCLASS  wc;       //窗口類信息結構

			//填充信息結構
			wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  
			wc.lpfnWndProc    = _WindowProc;                    
			wc.cbClsExtra     = 0;                              
			wc.cbWndExtra     = 0;                              
			wc.hInstance      = hInstance;                      
			wc.hIcon          = LoadIcon( NULL, IDI_WINLOGO );  
			wc.hCursor        = LoadCursor( NULL, IDC_ARROW );  
			wc.hbrBackground  = NULL;                          
			wc.lpszMenuName   = NULL;                          
			wc.lpszClassName  = kWindowClassName;              
			//註冊窗口類
			CC_BREAK_IF(! RegisterClass(&wc) && 1410 != GetLastError());        

			//取得電腦屏幕大小矩形
			RECT rcDesktop;
			GetWindowRect(GetDesktopWindow(), &rcDesktop);
			//將窗口標題多字節轉寬字符。
			WCHAR wszBuf[50] = {0};
			MultiByteToWideChar(CP_UTF8, 0, m_szViewName, -1, wszBuf, sizeof(wszBuf));

			// 使用註冊過的窗口類創建窗口
			m_hWnd = CreateWindowEx(
				WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,    // Extended Style For The Window
				kWindowClassName,                                    // Class Name
				wszBuf,                                                // Window Title
				WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX,        // Defined Window Style
				0, 0,                                                // Window Position
				0,                                                  // Window Width
				0,                                                  // Window Height
				NULL,                                                // No Parent Window
				NULL,                                                // No Menu
				hInstance,                                            // Instance
				NULL );
        //通過窗口句柄有效性判斷確保創建成功才能繼續
        CC_BREAK_IF(! m_hWnd);
	   //重點函數,調整窗口大小
        resize(w, h);
        //初始化OpenGL
        bRet = initGL();
	   //返回成功判斷
        CC_BREAK_IF(!bRet);
        //保存單件實例指針
        s_pMainWindow = this;
        bRet = true;
    } while (0);
    //返回成敗
    return bRet;
}

創建窗口時並沒有用到w和h,所以只有繼續看重點函數才能知道窗口大小是怎麼設置的。


  1. <SPAN style="FONT-SIZE: 14px">void CCEGLView::resize(int width, int height)
  2. {
  3. //窗口句柄有效性判斷
  4. if (! m_hWnd)
  5. {
  6. return;
  7. }
  8. //獲取窗口的客戶區大小矩形,這個客戶區其實就是咱們OpenGL視窗的實際大小,不包含一般窗口的菜單,邊框,狀態欄等部分。
  9. RECT rcClient;
  10. GetClientRect(m_hWnd, &rcClient);
  11. //如果當前窗口的客戶區部分大小與參數width,height相同,直接返回
  12. if (rcClient.right - rcClient.left == width &&
  13. rcClient.bottom - rcClient.top == height)
  14. {
  15. return;
  16. }
  17. // 否則重新設置客戶區大小矩形變量的值。
  18. rcClient.right = rcClient.left + width;
  19. rcClient.bottom = rcClient.top + height;
  20. //此函數將使窗口的整體大小(即如果有則包含菜單欄,邊框,底部狀態欄和客戶可視區的整個窗口的大小)按照
  21. 指定的客戶區大小rcClient和窗口樣式來自動調整,確保了客戶區就是rcClient指定大小。其中GetWindowLong用來獲取當前窗口的
  22. 樣式,GWL_STYLE爲基本樣式信息,GWL_EXSTYLE爲擴展欄式信息。返回窗口的整體大小再傳給rcClient。
  23. AdjustWindowRectEx(&rcClient, GetWindowLong(m_hWnd, GWL_STYLE), false,
  24. GetWindowLong(m_hWnd, GWL_EXSTYLE));
  25. // 設置窗口的顯示位置並應用rcClient做爲窗口的大小。
  26. SetWindowPos(m_hWnd, 0, 0, 0, rcClient.right - rcClient.left,
  27. rcClient.bottom - rcClient.top, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER
  28. | SWP_NOZORDER);
  29. }
  30. </SPAN>
  1. <SPAN style="FONT-SIZE: 14px">void CCEGLView::resize(int width, int height)  
  2. {     
  3. //窗口句柄有效性判斷   
  4.     if (! m_hWnd)  
  5.     {  
  6.         return;  
  7.     }  
  8.   
  9.     //獲取窗口的客戶區大小矩形,這個客戶區其實就是咱們OpenGL視窗的實際大小,不包含一般窗口的菜單,邊框,狀態欄等部分。   
  10. RECT rcClient;  
  11.     GetClientRect(m_hWnd, &rcClient);  
  12.     //如果當前窗口的客戶區部分大小與參數width,height相同,直接返回   
  13.         if (rcClient.right - rcClient.left == width &&  
  14.             rcClient.bottom - rcClient.top == height)  
  15.         {  
  16.             return;  
  17.         }  
  18.         // 否則重新設置客戶區大小矩形變量的值。   
  19.         rcClient.right = rcClient.left + width;  
  20.         rcClient.bottom = rcClient.top + height;  
  21.         //此函數將使窗口的整體大小(即如果有則包含菜單欄,邊框,底部狀態欄和客戶可視區的整個窗口的大小)按照   
  22. 指定的客戶區大小rcClient和窗口樣式來自動調整,確保了客戶區就是rcClient指定大小。其中GetWindowLong用來獲取當前窗口的  
  23. 樣式,GWL_STYLE爲基本樣式信息,GWL_EXSTYLE爲擴展欄式信息。返回窗口的整體大小再傳給rcClient。  
  24.         AdjustWindowRectEx(&rcClient, GetWindowLong(m_hWnd, GWL_STYLE), false,   
  25.                 GetWindowLong(m_hWnd, GWL_EXSTYLE));  
  26.   
  27.         // 設置窗口的顯示位置並應用rcClient做爲窗口的大小。   
  28.         SetWindowPos(m_hWnd, 0, 0, 0, rcClient.right - rcClient.left,   
  29.             rcClient.bottom - rcClient.top, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER   
  30.                 | SWP_NOZORDER);  
  31. }  
  32. </SPAN>  
void CCEGLView::resize(int width, int height)
{	
//窗口句柄有效性判斷
    if (! m_hWnd)
    {
        return;
    }

    //獲取窗口的客戶區大小矩形,這個客戶區其實就是咱們OpenGL視窗的實際大小,不包含一般窗口的菜單,邊框,狀態欄等部分。
RECT rcClient;
    GetClientRect(m_hWnd, &rcClient);
	//如果當前窗口的客戶區部分大小與參數width,height相同,直接返回
		if (rcClient.right - rcClient.left == width &&
			rcClient.bottom - rcClient.top == height)
		{
			return;
		}
		// 否則重新設置客戶區大小矩形變量的值。
		rcClient.right = rcClient.left + width;
		rcClient.bottom = rcClient.top + height;
		//此函數將使窗口的整體大小(即如果有則包含菜單欄,邊框,底部狀態欄和客戶可視區的整個窗口的大小)按照
指定的客戶區大小rcClient和窗口樣式來自動調整,確保了客戶區就是rcClient指定大小。其中GetWindowLong用來獲取當前窗口的
樣式,GWL_STYLE爲基本樣式信息,GWL_EXSTYLE爲擴展欄式信息。返回窗口的整體大小再傳給rcClient。
		AdjustWindowRectEx(&rcClient, GetWindowLong(m_hWnd, GWL_STYLE), false, 
                GetWindowLong(m_hWnd, GWL_EXSTYLE));

		// 設置窗口的顯示位置並應用rcClient做爲窗口的大小。
		SetWindowPos(m_hWnd, 0, 0, 0, rcClient.right - rcClient.left, 
			rcClient.bottom - rcClient.top, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER 
                | SWP_NOZORDER);
}

好了,我們看,窗口的大小就是這麼設置的。作者考慮到了不同的樣式窗口對於客戶區大小的影響,故做了相應的處理。所以我們創建指定大小的窗口時其實真正的意思是創建一個指定客戶區大小的窗口。


我們再來看 (2),分辨率的大小和 (3),影幕的大小 (4),視口的大小


分辨率:即是屏幕上圖像的精細度,在Cocos2d-x中其大小爲屏幕在橫向和縱向可以容納的邏輯點數量,爲了好理解,我們把它想像成投影機的分辨率。

影幕:想想小時候看電影時用到的那塊白布吧,當然也許公司會議室裏也能看到它。也就是投影機用來投射畫面的畫布。

視口:其實就是上面說的投影機投影出來的影片畫面所佔的矩形。它如果大於影幕的大小,那麼你就不能看到完整的影片畫面。如果小於影幕的大小。你就可以在它顯示的區域裏看到影片畫面。


我們現在看一下剛纔略過的代碼:CCEGLViewProtocol::setFrameSize(width,height);

進入CCEGLViewProtocol.cpp中相應函數定義:


  1. <SPAN style="FONT-SIZE: 14px">void CCEGLViewProtocol::setFrameSize(float width, float height)
  2. {
  3. //這裏使用參數對兩個變量進行了賦值,第一個就是分辨率大小。第二個就是影幕的大小。
  4. m_obDesignResolutionSize = m_obScreenSize = CCSizeMake(width, height);
  5. }
  6. </SPAN>
  1. <SPAN style="FONT-SIZE: 14px">void CCEGLViewProtocol::setFrameSize(float width, float height)  
  2. {  
  3.     //這裏使用參數對兩個變量進行了賦值,第一個就是分辨率大小。第二個就是影幕的大小。   
  4.     m_obDesignResolutionSize = m_obScreenSize = CCSizeMake(width, height);  
  5. }  
  6. </SPAN>  
void CCEGLViewProtocol::setFrameSize(float width, float height)
{
    //這裏使用參數對兩個變量進行了賦值,第一個就是分辨率大小。第二個就是影幕的大小。
    m_obDesignResolutionSize = m_obScreenSize = CCSizeMake(width, height);
}

雙擊“m_obDesignResolutionSize”,按下Ctrl+F,在彈出查找對話框裏對當前文檔CCEGLViewProtocol.cpp中查找全部使用。





點擊第一個查找結果,看一下所在函數setDesignResolutionSize,這個函數是用來設置分辨率大小的。前兩個參數無疑就是設置分辨率橫向縱向的像素數量的。最後一個參數resolutionPolicy我們必須瞭解一下,進入ResolutionPolicy的定義:

  1. enum ResolutionPolicy
  2. {
  3. // 擴展填充模式:這裏等於是直接設置投影機的分辨率。如果這個分辨率與畫布大小的比例失調,就會出現失真。
  4. kResolutionExactFit,
  5. // 低調整模式:這個吧,是按照設置的分辨率在橫縱方向上最低值調整視口大小,使投影機投影出來的影片畫面所佔的矩形在
  6. 畫布上所對應的相應方向上與最低值一致。
  7. kResolutionNoBorder
  8. // 高調整模式:與上面恰恰相反,按照設置的分辨率在橫縱方向上最高值調整視口大小,使投影機投影出來的影片畫面所佔的
  9. 矩形在畫布上所對應的相應方向上與最高值一致。同時這個矩形的另一個方向按最低值進行裁剪,區域外部分填充黑色。
  10. kResolutionShowAll,
  11. //無效值
  12. kResolutionUnKnown,
  13. };
  1. enum ResolutionPolicy  
  2. {  
  3.     // 擴展填充模式:這裏等於是直接設置投影機的分辨率。如果這個分辨率與畫布大小的比例失調,就會出現失真。   
  4.     kResolutionExactFit,  
  5.     // 低調整模式:這個吧,是按照設置的分辨率在橫縱方向上最低值調整視口大小,使投影機投影出來的影片畫面所佔的矩形在   
  6.     畫布上所對應的相應方向上與最低值一致。  
  7.     kResolutionNoBorder  
  8.     // 高調整模式:與上面恰恰相反,按照設置的分辨率在橫縱方向上最高值調整視口大小,使投影機投影出來的影片畫面所佔的   
  9.     矩形在畫布上所對應的相應方向上與最高值一致。同時這個矩形的另一個方向按最低值進行裁剪,區域外部分填充黑色。  
  10.     kResolutionShowAll,  
  11.     //無效值   
  12.     kResolutionUnKnown,  
  13. };  
enum ResolutionPolicy
{
    // 擴展填充模式:這裏等於是直接設置投影機的分辨率。如果這個分辨率與畫布大小的比例失調,就會出現失真。
    kResolutionExactFit,
    // 低調整模式:這個吧,是按照設置的分辨率在橫縱方向上最低值調整視口大小,使投影機投影出來的影片畫面所佔的矩形在
    畫布上所對應的相應方向上與最低值一致。
    kResolutionNoBorder
    // 高調整模式:與上面恰恰相反,按照設置的分辨率在橫縱方向上最高值調整視口大小,使投影機投影出來的影片畫面所佔的
    矩形在畫布上所對應的相應方向上與最高值一致。同時這個矩形的另一個方向按最低值進行裁剪,區域外部分填充黑色。
    kResolutionShowAll,
    //無效值
    kResolutionUnKnown,
};


這個枚舉歸結爲“分辨率模式”。是不是有點迷糊,得,我們在繼續下面的函數之前,先以例子來說明一下:

打開HelloLua工程的AppDelegate.cpp,看一下這個函數:

  1. <SPAN style="FONT-SIZE: 14px">bool AppDelegate::applicationDidFinishLaunching()
  2. {
  3. // 取得顯示設備的單件實例指針
  4. CCDirector *pDirector = CCDirector::sharedDirector();
  5. // 設置其使用的OpenGL視窗爲單件OpenGL視窗
  6. pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
  7. //在這裏設置了分辨率爲480,320,與窗口客戶區一致,顯示模式爲kResolutionShowAll。
  8. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionShowAll);
  9. //開始高清顯示模式
  10. // pDirector->enableRetinaDisplay(true);
  11. // 設置顯示FPS相關
  12. pDirector->setDisplayStats(true);
  13. // 設置幀間隔時間
  14. pDirector->setAnimationInterval(1.0 / 60);
  15. // 註冊LUA管理器並設置爲當前使用的腳本系統
  16. CCScriptEngineProtocol* pEngine = CCLuaEngine::engine();
  17. CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
  18. //執行hello.lua腳本啓動遊戲,不懂的可以參見本博主的博文“HelloLua”深入分析一文
  19. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
  20. CCString* pstrFileContent = CCString::createWithContentsOfFile("hello.lua");
  21. if (pstrFileContent)
  22. {
  23. pEngine->executeString(pstrFileContent->getCString());
  24. }
  25. #else
  26. std::string path = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("hello.lua");
  27. pEngine->addSearchPath(path.substr(0, path.find_last_of("/")).c_str());
  28. pEngine->executeScriptFile(path.c_str());
  29. #endif
  30. return true;
  31. }
  32. </SPAN>
  1. <SPAN style="FONT-SIZE: 14px">bool AppDelegate::applicationDidFinishLaunching()  
  2. {  
  3.     // 取得顯示設備的單件實例指針   
  4. CCDirector *pDirector = CCDirector::sharedDirector();  
  5. // 設置其使用的OpenGL視窗爲單件OpenGL視窗   
  6.     pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());  
  7.     //在這裏設置了分辨率爲480,320,與窗口客戶區一致,顯示模式爲kResolutionShowAll。   
  8.     CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionShowAll);  
  9.       
  10.     //開始高清顯示模式   
  11.     // pDirector->enableRetinaDisplay(true);   
  12.   
  13.     // 設置顯示FPS相關   
  14.     pDirector->setDisplayStats(true);  
  15.   
  16.     // 設置幀間隔時間   
  17.     pDirector->setAnimationInterval(1.0 / 60);  
  18.   
  19.     // 註冊LUA管理器並設置爲當前使用的腳本系統   
  20.     CCScriptEngineProtocol* pEngine = CCLuaEngine::engine();  
  21.     CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);  
  22.     //執行hello.lua腳本啓動遊戲,不懂的可以參見本博主的博文“HelloLua”深入分析一文   
  23. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)   
  24.     CCString* pstrFileContent = CCString::createWithContentsOfFile("hello.lua");  
  25.     if (pstrFileContent)  
  26.     {  
  27.         pEngine->executeString(pstrFileContent->getCString());  
  28.     }  
  29. #else   
  30.     std::string path = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("hello.lua");  
  31.     pEngine->addSearchPath(path.substr(0, path.find_last_of("/")).c_str());  
  32.     pEngine->executeScriptFile(path.c_str());  
  33. #endif    
  34.   
  35.     return true;  
  36. }  
  37. </SPAN>  
bool AppDelegate::applicationDidFinishLaunching()
{
    // 取得顯示設備的單件實例指針
CCDirector *pDirector = CCDirector::sharedDirector();
// 設置其使用的OpenGL視窗爲單件OpenGL視窗
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
	//在這裏設置了分辨率爲480,320,與窗口客戶區一致,顯示模式爲kResolutionShowAll。
    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionShowAll);
    
	//開始高清顯示模式
    // pDirector->enableRetinaDisplay(true);

    // 設置顯示FPS相關
    pDirector->setDisplayStats(true);

    // 設置幀間隔時間
    pDirector->setAnimationInterval(1.0 / 60);

    // 註冊LUA管理器並設置爲當前使用的腳本系統
    CCScriptEngineProtocol* pEngine = CCLuaEngine::engine();
    CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
	//執行hello.lua腳本啓動遊戲,不懂的可以參見本博主的博文“HelloLua”深入分析一文
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    CCString* pstrFileContent = CCString::createWithContentsOfFile("hello.lua");
    if (pstrFileContent)
    {
        pEngine->executeString(pstrFileContent->getCString());
    }
#else
    std::string path = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("hello.lua");
    pEngine->addSearchPath(path.substr(0, path.find_last_of("/")).c_str());
    pEngine->executeScriptFile(path.c_str());
#endif 

    return true;
}

我們要乾點壞事,好吧。我們嘗試着將其分別改爲

  1. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionExactFit);
  2. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionNoBorder);
  3. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionShowAll);
  1. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionExactFit);  
  2. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionNoBorder);  
  3. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionShowAll);  
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionExactFit);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionNoBorder);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionShowAll);

並進行測試。下面是測試圖。




好好理解一下。

再回來看setDesignResolutionSize函數:


  1. void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
  2. {
  3. //是否使用高清模式(視網膜屏幕),高清模式不讓設置分辨率。
  4. CCAssert(m_bIsRetinaEnabled == false, "can not enable retina while set design resolution size!");
  5. //確保分辨率顯示方式有效
  6. CCAssert(resolutionPolicy != kResolutionUnKnown, "should set resolutionPolicy");
  7. //如果參數無效,直接返回。
  8. if (width == 0.0f || height == 0.0f)
  9. {
  10. return;
  11. }
  12. //在這裏對變量m_obDesignResolutionSize進行了設置。
  13. m_obDesignResolutionSize.setSize(width, height);
  14. //這裏計算出影幕大小與分辨率大小的比率。存放在變量m_fScaleX,m_fScaleY中。
  15. m_fScaleX = (float)m_obScreenSize.width / m_obDesignResolutionSize.width;
  16. m_fScaleY = (float)m_obScreenSize.height / m_obDesignResolutionSize.height;
  17. //如果模式是kResolutionNoBorder,按照最大影幕方式,即保證像素不失真的情況下,影幕適應分辨率
  18. //如果是低調整模式
  19. if (resolutionPolicy == kResolutionNoBorder)
  20. {
  21. //縮放值按最大
  22. m_fScaleX = m_fScaleY = MAX(m_fScaleX, m_fScaleY);
  23. }
  24. //如果是高調整模式
  25. if (resolutionPolicy == kResolutionShowAll)
  26. {
  27. //縮放值按最小
  28. m_fScaleX = m_fScaleY = MIN(m_fScaleX, m_fScaleY);
  29. }
  30. // 根據縮放值和分辨率計算視口的寬高
  31. float viewPortW = m_obDesignResolutionSize.width * m_fScaleX;
  32. float viewPortH = m_obDesignResolutionSize.height * m_fScaleY;
  33. // 設置視口位置居屏幕中間
  34. m_obViewPortRect.setRect((m_obScreenSize.width - viewPortW) / 2, (m_obScreenSize.height - viewPortH) / 2, viewPortW, viewPortH);
  35. //保存分辨率模式
  36. m_eResolutionPolicy = resolutionPolicy;
  37. //使用變量設置Opengl視口(此處屏蔽,在SetGLDefaultValues中會有設)
  38. //setViewPortInPoints(0, 0,m_obScreenSize.width, m_obScreenSize.height);
  39. // 創建FPS的文字標籤
  40. CCDirector::sharedDirector()->createStatsLabel();
  41. //初始化邏輯點和像素值大小
  42. CCDirector::sharedDirector()->m_obWinSizeInPoints = CCDirector::sharedDirector()->m_obWinSizeInPixels = getSize();
  43. //對OpengGL用到的一些設置進行初始化,其中有重設投影函數,會再重置視口。
  44. CCDirector::sharedDirector()->setGLDefaultValues();
  45. }
  1. void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)  
  2. {  
  3.     //是否使用高清模式(視網膜屏幕),高清模式不讓設置分辨率。   
  4. CCAssert(m_bIsRetinaEnabled == false"can not enable retina while set design resolution size!");  
  5. //確保分辨率顯示方式有效   
  6.     CCAssert(resolutionPolicy != kResolutionUnKnown, "should set resolutionPolicy");  
  7.     //如果參數無效,直接返回。   
  8.     if (width == 0.0f || height == 0.0f)  
  9.     {  
  10.         return;  
  11.     }  
  12.     //在這裏對變量m_obDesignResolutionSize進行了設置。   
  13.     m_obDesignResolutionSize.setSize(width, height);  
  14.     //這裏計算出影幕大小與分辨率大小的比率。存放在變量m_fScaleX,m_fScaleY中。   
  15.     m_fScaleX = (float)m_obScreenSize.width / m_obDesignResolutionSize.width;  
  16.     m_fScaleY = (float)m_obScreenSize.height / m_obDesignResolutionSize.height;  
  17. //如果模式是kResolutionNoBorder,按照最大影幕方式,即保證像素不失真的情況下,影幕適應分辨率   
  18. //如果是低調整模式   
  19.     if (resolutionPolicy == kResolutionNoBorder)  
  20. {  
  21.        //縮放值按最大   
  22.         m_fScaleX = m_fScaleY = MAX(m_fScaleX, m_fScaleY);  
  23.     }  
  24.     //如果是高調整模式   
  25.     if (resolutionPolicy == kResolutionShowAll)  
  26. {  
  27.         //縮放值按最小   
  28.         m_fScaleX = m_fScaleY = MIN(m_fScaleX, m_fScaleY);  
  29.     }  
  30.   
  31.     // 根據縮放值和分辨率計算視口的寬高       
  32.     float viewPortW = m_obDesignResolutionSize.width * m_fScaleX;  
  33.     float viewPortH = m_obDesignResolutionSize.height * m_fScaleY;  
  34.     // 設置視口位置居屏幕中間   
  35.     m_obViewPortRect.setRect((m_obScreenSize.width - viewPortW) / 2, (m_obScreenSize.height - viewPortH) / 2, viewPortW, viewPortH);  
  36.     //保存分辨率模式   
  37.     m_eResolutionPolicy = resolutionPolicy;  
  38.     //使用變量設置Opengl視口(此處屏蔽,在SetGLDefaultValues中會有設)   
  39.     //setViewPortInPoints(0, 0,m_obScreenSize.width, m_obScreenSize.height);   
  40. // 創建FPS的文字標籤   
  41. CCDirector::sharedDirector()->createStatsLabel();  
  42. //初始化邏輯點和像素值大小   
  43. CCDirector::sharedDirector()->m_obWinSizeInPoints = CCDirector::sharedDirector()->m_obWinSizeInPixels = getSize();   
  44. //對OpengGL用到的一些設置進行初始化,其中有重設投影函數,會再重置視口。   
  45.     CCDirector::sharedDirector()->setGLDefaultValues();  
  46. }  
void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
{
	//是否使用高清模式(視網膜屏幕),高清模式不讓設置分辨率。
CCAssert(m_bIsRetinaEnabled == false, "can not enable retina while set design resolution size!");
//確保分辨率顯示方式有效
    CCAssert(resolutionPolicy != kResolutionUnKnown, "should set resolutionPolicy");
    //如果參數無效,直接返回。
    if (width == 0.0f || height == 0.0f)
    {
        return;
    }
    //在這裏對變量m_obDesignResolutionSize進行了設置。
    m_obDesignResolutionSize.setSize(width, height);
    //這裏計算出影幕大小與分辨率大小的比率。存放在變量m_fScaleX,m_fScaleY中。
    m_fScaleX = (float)m_obScreenSize.width / m_obDesignResolutionSize.width;
    m_fScaleY = (float)m_obScreenSize.height / m_obDesignResolutionSize.height;
//如果模式是kResolutionNoBorder,按照最大影幕方式,即保證像素不失真的情況下,影幕適應分辨率
//如果是低調整模式
    if (resolutionPolicy == kResolutionNoBorder)
{
	   //縮放值按最大
        m_fScaleX = m_fScaleY = MAX(m_fScaleX, m_fScaleY);
    }
    //如果是高調整模式
    if (resolutionPolicy == kResolutionShowAll)
{
	    //縮放值按最小
        m_fScaleX = m_fScaleY = MIN(m_fScaleX, m_fScaleY);
    }

    // 根據縮放值和分辨率計算視口的寬高    
    float viewPortW = m_obDesignResolutionSize.width * m_fScaleX;
    float viewPortH = m_obDesignResolutionSize.height * m_fScaleY;
	// 設置視口位置居屏幕中間
    m_obViewPortRect.setRect((m_obScreenSize.width - viewPortW) / 2, (m_obScreenSize.height - viewPortH) / 2, viewPortW, viewPortH);
    //保存分辨率模式
    m_eResolutionPolicy = resolutionPolicy;
    //使用變量設置Opengl視口(此處屏蔽,在SetGLDefaultValues中會有設)
    //setViewPortInPoints(0, 0,m_obScreenSize.width, m_obScreenSize.height);
// 創建FPS的文字標籤
CCDirector::sharedDirector()->createStatsLabel();
//初始化邏輯點和像素值大小
CCDirector::sharedDirector()->m_obWinSizeInPoints = CCDirector::sharedDirector()->m_obWinSizeInPixels = getSize(); 
//對OpengGL用到的一些設置進行初始化,其中有重設投影函數,會再重置視口。
    CCDirector::sharedDirector()->setGLDefaultValues();
}

現在大家明白我爲什麼將(2),(3),(4)並在一起說了。它們其實是有機結合的。相輔相成,缺一不可。


我們最後來看一下:(5),裁剪區域的大小:

裁剪區域:如果對Opengl顯示窗口設定裁剪區域,則裁剪區域外的像素將不會顯示。


我們仍然在HelloLua工程中進行說明:

在函數AppDelegate::applicationDidFinishLaunching()中我們在

  1. CCEGLViewProtocol* tpCCEGLView = (CCEGLViewProtocol*) CCEGLView::sharedOpenGLView();
  2. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionShowAll);
  1. CCEGLViewProtocol*  tpCCEGLView = (CCEGLViewProtocol*) CCEGLView::sharedOpenGLView();  
  2.   
  3. CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionShowAll);  
CCEGLViewProtocol*	tpCCEGLView = (CCEGLViewProtocol*) CCEGLView::sharedOpenGLView();

CCEGLView::sharedOpenGLView()->setDesignResolutionSize(80, 320, kResolutionShowAll);

後面增加代碼:


  1. //設定裁剪顯示區域
  2. tpCCEGLView->setScissorInPoints(100,100,100,100);
  3. //開啓裁剪檢測
  4. glEnable(GL_SCISSOR_TEST);
  1. //設定裁剪顯示區域   
  2. tpCCEGLView->setScissorInPoints(100,100,100,100);  
  3.     //開啓裁剪檢測   
  4. glEnable(GL_SCISSOR_TEST);  
//設定裁剪顯示區域
tpCCEGLView->setScissorInPoints(100,100,100,100);
	//開啓裁剪檢測
glEnable(GL_SCISSOR_TEST);

運行測試:



可以看到,我們對畫面進行了裁剪。從屏幕100,100位置起的大小爲寬100,高100的區域被設爲了裁剪顯示區域,其它部分均被裁切掉了。

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