Post date: Jul 4, 2011 5:14:56 PM
Ở bước 8, ta đã có một View dùng cho win32-vs. Ở bước này, ta tìm cách tích hợp openGL vào View
Đầu tiên, ta implement 2 hàm sau vào CVSView
CVSView
... void CVSView::InitGL() { HDC hdc = m_hGameWndDC; GLuint PixelFormat; // pfd Tells Windows How We Want Things To Be static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),// Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 16, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, // Alpha Buffer 0, // Shift Bit Ignored 0, // Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 16, // 16Bit Z-Buffer (Depth Buffer) 8, // Stencil Buffer 0, // Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; PixelFormat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, PixelFormat, &pfd); m_hGLRC = wglCreateContext(hdc); wglMakeCurrent(hdc, m_hGLRC); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable( GL_TEXTURE_2D ); glViewport(0, 0, m_iWidth,m_iHeight); } void CVSView::RefreshGL() { SwapBuffers(m_hGameWndDC); glEnable(GL_DEPTH_TEST); glDepthMask(TRUE); glDepthFunc(GL_LEQUAL); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
Thực hiện lời gọi hàm InitGL trong InitClientWindow, và RefreshGL trong Update
CVSView.cpp
... //----------------------------------- // Init win32 client window //----------------------------------- void CVSView::InitClientWindow() { //get current instant HINSTANCE hInstance = GetModuleHandle(0); //---------------------------------- // init WNDCLASSEX WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = 0;//LoadIcon(hInstance, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = 0; wcex.lpszClassName = "main"; wcex.hIconSm = 0;//LoadIcon(wcex.hInstance, IDI_APPLICATION); if (! RegisterClassEx( &wcex ) ) { return; // ERR, SO QUIT } //---------------------------------- // init HWND DWORD style = WS_POPUP; if(!m_isFullScreen) { style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; } RECT clientSize; clientSize.top = 0; clientSize.left = 0; clientSize.right = m_iWidth; clientSize.bottom = m_iHeight; AdjustWindowRect(&clientSize, style, FALSE); const int realWidth = clientSize.right - clientSize.left; const int realHeight = clientSize.bottom - clientSize.top; int windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; int windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; if(!m_isFullScreen) { m_hwndWindow = CreateWindow( "main", m_strTitle, style, windowLeft, windowTop, realWidth, realHeight, NULL, NULL, hInstance, NULL); } else { m_hwndWindow = CreateWindow( "main", m_strTitle, style, 0, 0, m_iWidth, m_iHeight, NULL, NULL, hInstance, NULL); } m_hGameWndDC = GetDC(m_hwndWindow); InitGL(); ShowWindow( m_hwndWindow, SW_SHOW ); UpdateWindow( m_hwndWindow ); if(!m_isFullScreen) { MoveWindow(m_hwndWindow, windowLeft, windowTop, realWidth, realHeight, TRUE); } SetActiveWindow(m_hwndWindow); SetForegroundWindow(m_hwndWindow); if(m_isFullScreen) { DEVMODE dm; memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(DEVMODE); dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; dm.dmPelsWidth = m_iWidth; dm.dmPelsHeight = m_iHeight; dm.dmBitsPerPel = 32; ChangeDisplaySettings(&dm, CDS_FULLSCREEN); } } //------------------------------------ // update win32 message //------------------------------------ void CVSView::Update() { // handle win32 message MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); if (msg.hwnd == m_hwndWindow) { WndProc(m_hwndWindow, msg.message, msg.wParam, msg.lParam); } } RefreshGL(); DispatchMessage(&msg); } ...
Hai hàm trên cần một số hàm từ thư viện OpenGL. Để có thể build được, ta cần khai báo thư viện OpenGL torng Header.h
Header.h
... #include #if CONFIG_PLATFORM==PLATFORM_WIN32_VS # include <windows.h> # include <time.h> # include "libs/ogl/gl.h" # include "libs/ogl/glext.h" # pragma comment(lib, "libs/ogl/opengl32.lib") #endif #include "Macros.h" ...
Lưu ý: các file gl.h, glext.h được đặt trong thư mục Libs\ogl\
Download