[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Игровые движки » IrrLicht Engine » Туториал №14: Окно Win32
Туториал №14: Окно Win32
MerGC_TeamДата: Четверг, 03.04.2014, 17:43 | Сообщение # 1
Веселый админ
Группа: Администраторы
Сообщений: 32
Статус: Оффлайн
Код этого туториала запускается только на платформе Windows и демонстрирует как Irrlicht может рендерить сцену в окно win32 приложения. Возможно и в окна MFC и .NET Windows.Forms тоже.

По началу надо создать окно с помощью API. Я не буду коментировать эту процедуру, читайте MSDN.

Код
#include < irrlicht.h >
#ifndef _IRR_WINDOWS_
#error Windows only example
#else
#include < windows.h > // будет компилироваться только на windows
#include < iostream >
#include "driverChoice.h"

using namespace irr;  

HWND hOKButton;
HWND hWnd;

static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
                 WPARAM wParam, LPARAM lParam)
{
         switch (message)
         {
         case WM_COMMAND:
                 {
                         HWND hwndCtl = (HWND)lParam;
                         int code = HIWORD(wParam);

                         if (hwndCtl == hOKButton)
                         {
                    DestroyWindow(hWnd);
                    PostQuitMessage(0);
                    return 0;
                         }
                 }
                 break;
         case WM_DESTROY:
                 PostQuitMessage(0);
                 return 0;

         }

         return DefWindowProc(hWnd, message, wParam, lParam);
}


Теперь запрашиваем видеодрайвер и создаем окно win32

Код
int main()
{
         // запрос драйвера
         video::E_DRIVER_TYPE driverType=driverChoiceConsole();
         if (driverType==video::EDT_COUNT)
                 return 1;

         printf("Select the render window (some dead window may exist too):n"
                 " (a) Window with button (via CreationParam)n"
                 " (b) Window with button (via beginScene)n"
                 " (c) Own Irrlicht window (default behavior)n"
                 " (otherKey) exitnn");

         char key;
         std::cin >> key;
         if (key != 'a' && key != 'b' && key != 'c')
                 return 1;

         HINSTANCE hInstance = 0;
         // создаем диалог

         const char* Win32ClassName = "CIrrlichtWindowsTestDialog";

         WNDCLASSEX wcex;
         wcex.cbSize                     = sizeof(WNDCLASSEX);
         wcex.style                      = CS_HREDRAW | CS_VREDRAW;
         wcex.lpfnWndProc        = (WNDPROC)CustomWndProc;
         wcex.cbClsExtra         = 0;
         wcex.cbWndExtra         = DLGWINDOWEXTRA;
         wcex.hInstance          = hInstance;
         wcex.hIcon                      = NULL;
         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW);
         wcex.lpszMenuName       = 0;
         wcex.lpszClassName      = Win32ClassName;
         wcex.hIconSm            = 0;

         RegisterClassEx(&wcex);

         DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION |
                 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX;

         int windowWidth = 440;
         int windowHeight = 380;

         hWnd = CreateWindow( Win32ClassName, "Irrlicht Win32 window example",
                 style, 100, 100, windowWidth, windowHeight,
                 NULL, NULL, hInstance, NULL);

         RECT clientRect;
         GetClientRect(hWnd, &clientRect);
         windowWidth = clientRect.right;
         windowHeight = clientRect.bottom;

         // создаем кнопку ОК

         hOKButton = CreateWindow("BUTTON", "OK - Close", WS_CHILD | WS_VISIBLE | BS_TEXT,
                 windowWidth - 160, windowHeight - 40, 150, 30, hWnd, NULL, hInstance, NULL);

         // создаем произвольный текст

         CreateWindow("STATIC", "This is Irrlicht running inside a standard Win32 window.n"
                 "Also mixing with MFC and .NET Windows.Forms is possible.",
                 WS_CHILD | WS_VISIBLE, 20, 20, 400, 40, hWnd, NULL, hInstance, NULL);

         // создаем окно в которое будем рендерить

         HWND hIrrlichtWindow = CreateWindow("BUTTON", "",
                         WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
                         50, 80, 320, 220, hWnd, NULL, hInstance, NULL);
         video::SExposedVideoData videodata((key=='b')?hIrrlichtWindow:0);


Так теперь у нас есть win32 окошко для рендерига, поместим в него IrrLicht, для этого создадим корневой объект(движок) используя функцию createEx(). Нам нужен дескриптор окна (HWND) который мы установим как windowsID параметром для движка.

Код
// создаем корневой объект(движок) irrlicht в окне win32

         irr::SIrrlichtCreationParameters param;
         param.DriverType = driverType;
         if (key=='a')
                 param.WindowId = reinterpret_cast<void*>(hIrrlichtWindow);

         irr::IrrlichtDevice* device = irr::createDeviceEx(param);

         // настроим простую 3d сцену

         irr::scene::ISceneManager* smgr = device->getSceneManager();
         video::IVideoDriver* driver = device->getVideoDriver();

         if (driverType==video::EDT_OPENGL)
         {
                 HDC HDc=GetDC(hIrrlichtWindow);
                 PIXELFORMATDESCRIPTOR pfd={0};
                 pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
                 int pf = GetPixelFormat(HDc);
                 DescribePixelFormat(HDc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
                 pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
                 pfd.cDepthBits=16;
                 pf = ChoosePixelFormat(HDc, &pfd);
                 SetPixelFormat(HDc, pf, &pfd);
                 videodata.OpenGLWin32.HDc = HDc;
                 videodata.OpenGLWin32.HRc=wglCreateContext(HDc);
                 wglShareLists((HGLRC)driver->getExposedVideoData().OpenGLWin32.HRc, (HGLRC)videodata.OpenGLWin32.HRc);
         }
         scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
         cam->setTarget(core::vector3df(0,0,0));

         scene::ISceneNodeAnimator* anim =
                 smgr->createFlyCircleAnimator(core::vector3df(0,15,0), 30.0f);
         cam->addAnimator(anim);
         anim->drop();

         scene::ISceneNode* cube = smgr->addCubeSceneNode(20);

         cube->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
         cube->setMaterialTexture(1, driver->getTexture("../../media/water.jpg"));
         cube->setMaterialFlag( video::EMF_LIGHTING, false );
         cube->setMaterialType( video::EMT_REFLECTION_2_LAYER );

         smgr->addSkyBoxSceneNode(
         driver->getTexture("../../media/irrlicht2_up.jpg"),
         driver->getTexture("../../media/irrlicht2_dn.jpg"),
         driver->getTexture("../../media/irrlicht2_lf.jpg"),
         driver->getTexture("../../media/irrlicht2_rt.jpg"),
         driver->getTexture("../../media/irrlicht2_ft.jpg"),
         driver->getTexture("../../media/irrlicht2_bk.jpg"));

         // показываем окно

         ShowWindow(hWnd , SW_SHOW);
         UpdateWindow(hWnd);

         // обрабатываем последовательность событий


Теперь обычный цикл отрисовки, правда вместо стандартного цикла IrrLicht, вы можете использовать цикл на базе GetMessage или DispatchMessage, но учтите, что Irrlicht возможно не сможет перехватить события от пользователя и вам придется это учесть в обработчике событий вашего окна.

Код
while (device->run())
         {
                 driver->beginScene(true, true, 0, videodata);
                 smgr->drawAll();
                 driver->endScene();
         }


Альтернативный цикл без Device->run() выглядит примерно так:

MSG msg; while (true) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg);

if (msg.message == WM_QUIT) break; }

advance virtual time device->getTimer()->tick();

отрисовка сцены driver->beginScene(true, true, 0, (key=='c')?hIrrlichtWindow:0); smgr->drawAll(); driver->endScene(); }

Код
device->closeDevice();
         device->drop();

         return 0;
}
#endif // если windows


Это все, Irrlicht теперь запускается внутри окна windows.

* Данный пример компилируется только компилятором Microsoft Visual Studio.
 
Форум » Игровые движки » IrrLicht Engine » Туториал №14: Окно Win32
  • Страница 1 из 1
  • 1
Поиск: