1. 程式人生 > >談一談Cocos2d-x中的某些“大小”

談一談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>
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>
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>
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>
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>
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. };
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>
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);
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. }
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);
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);
//設定裁剪顯示區域
tpCCEGLView->setScissorInPoints(100,100,100,100);
	//開啟裁剪檢測
glEnable(GL_SCISSOR_TEST);

執行測試:


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

相關推薦

Cocos2d-x某些大小

這裡說的“大小”,包括了以下一些內容: (1).視窗的大小 (2).解析度的大小 (3).影幕的大小 (4).視口的大小 (5).裁剪區域的大小 我們先來看(1),視窗的大小 視窗的大小,即是Windows窗體大小。我們以HelloCpp為例,開啟main.cpp,。找到

原生JS的【面向對象思想】

時間 lin 因此 pre defined 成員方法 .... 面向對象的思想 其實在 【重點提前說:面向對象的思想很重要!】 最近開始接觸學習後臺的PHP語言,在接觸到PHP中的面向對象相關思想之後,突然想到之前曾接觸的JS中的面向對象思想

java的Canves機制

getx 包括 true 事情 操作 應用 感覺 todo canvas 0--寫在前面:   很多初學java的童鞋,常常很苦惱,一天天的都跟命令行較勁,好像很無聊的樣子,如果能跳出命令行做出界面甚至一個畫圖界面,那將是一件很興奮的事情;也可以讓編程變的有趣;有腦洞的同學

python的魔法變數*args和**kwargs

導讀 最近看了看github大佬寫的程式碼後,發現自己之前寫的程式碼就是個,沒有註釋,沒有封裝,沒有可讀性。哎,幸虧發現及時,現在正在寫一個新的任務,剛好可以好好弄弄架構和程式碼了 在弄程式碼期間發現了*args和**kwargs這兩個引數大佬們有時候經常用,當然最多的其實是在閱讀pytho

django類檢視

1.類檢視的定義 以函式的方式定義的檢視稱為函式檢視,函式檢視便於理解。但是遇到一個檢視對應的路徑提供了多種不同HTTP請求方式的支援時,便需要在一個函式中編寫不同的業務邏輯,程式碼可讀性與複用性都不佳。 def register(request): """處理

Java開發的坑() -- log4j2在SaaS專案的應用

背景介紹: 做server端開發有些年頭了,特別是開始做SaaS型別的專案時,深知log的重要性,特別是半夜三更使用者(大都是美國那邊的)遇到問題的電話打過來,這個時候沒有一個強大log,那只有抓瞎的份了。以前都是走的微軟系的開發工具,log的框架也是別人早就寫好的,所以

C#File類和FileInfo類的區別

File類是一個靜態類,優點:呼叫簡單;缺點:始終消耗CPU資源。FileInfo類是一個例項類,優點:呼叫完就釋放CPU資源;缺點:操作複雜這裡用一個讀取一篇文章幷包含空格,處理空格後,再寫回去的操作來演示兩者是如何對檔案進行操作的。File類: //

JavascriptsetTimeout

前段時間公司在開會的時候提到了Javascript裡的setTimeout,同事們的討論很有意思,決定和大家分享一下。 話不多說,上程式碼 //程式碼塊A document.querySelector('button').onclick = function(){    

關於Combox當SelectedIndex="0" 無效的問題

最近在做一個專案,combox繫結資料來源之後,有些SelectedIndex="0" 是有值的,有些沒值,百思不得其解,今天專門花時間研究下這個問題,終於搞定!!!! 重點在SelectedValuePath這個屬性,SelectedValuePath繫結的值==int?

"大公司定標準、公司搞專利、小公司賣苦力"

“一流企業定標準、二流企業做品牌、三流企業賣技術、四流企業做產品”是經濟發展的普遍規律,  標準之爭其實是市場之爭。誰掌握了標準,就意味著先行拿到市場的入場券,甚至成為行業的定義者 上個世紀以

這篇文章,我們來Spring的屬性注入

> **本系列文章:** > > [讀原始碼,我們可以從第一行讀起](https://blog.csdn.net/qq_41907991/article/details/105667900) > > [你知道Spring是怎麼解析配置類的嗎?](https://blog.csdn.net/qq_4190799

Cocos2d-xVector&lt;T&gt;容器以及實例介紹

top 宋體 hello 操作符 模板類 log ins bsp main Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容納的是Ref及子類所創建的對象指針,其中的T是模板,表示能夠放入到容器中的類型,在Cocos2d-x 3.x

cocos2d-x XML解析與數據存儲

lba false 網上 unsigned failed popu new ccm cfile 一不小心就玩了一周的遊戲了。哎。玩的時候時間過得總是這麽快。。。 於是今天決定看一下之前不怎麽非常熟悉的XML;(之前做遊戲時數據的儲存用到過XML,但這塊是還有一個同事在做

linux下開發,解決cocos2d-x編譯出現的一個小問題, undefined reference to symbol &#39;pthread_create@@GLIBC_2.2.5&#39;

water span x86 code bject data- ace 技術分享 inux 解決cocos2d-x中編譯出現的一個小問題 對於cocos2d-x 2.×中編譯中,若頭文件裏引入了#include "cocos-ext.h",在進行C++編譯的時候會遇到例

跑PHP計劃任務

amp reg dmi content set cnblogs input span put 公司所用計劃任務均是大概這樣子的: */2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php ta

商品編碼的問題

什麽是 開發測試 upd 無奈 是不是 默認 修改 都沒有 做了 如題:今天談一談商品編碼的問題,我們不是完全從物流和商品本身的角度去談商品該怎麽編碼才符合國際標準,EAN,UPC啥啥啥怎麽樣的。我們從計算機程序設計,電商,數據庫存儲的角度看一看商品編碼,首先商品有哪些編碼

實例介紹Cocos2d-xBox2D物理引擎:碰撞檢測

函數實現 pda creates pty blank oid rtu and 重構 在Box2D中碰撞事件通過實現b2ContactListener類函數實現,b2ContactListener是Box2D提供的抽象類,它的抽象函數:virtual void BeginC

APP版本號問題

nbsp param pos 得到 大於 reat 兼容 pat 用戶 如題:談一談APP版本號問題 為什麽要談這個問題,周五晚上11~12點,被微信點名,說APP有錯,無效的版本號,商城無法下單。我正在準備收拾東西,周末回老家,結果看到這樣問題,菊花一緊。我擦,我剛加的

購物車

關系 大數據 tor 存儲 緩存 不同的 影響 什麽 activity 如題:今天談一談購物車這個話題。最近在重構購物車,所以借著興頭談一談購物車的設計。很久很久以前,那個時候還有沒有智能手機,還沒有京東,淘寶也剛剛起步,大概是在上學時讀書看到的,記得書中說購物車是放在se

Cocos2d-XMenu的綜合運用

cond edi ros log 程序 cal coo 項目 綜合 今天將曾經寫的代碼和項目集成到了一個菜單中,能夠通過菜單切換到曾經做的項目 程序的project文件夾 主要代碼分析: LessonMenu.h中實現創建菜單,遍歷菜單通過菜單切換