Cleanup code & documentation of Example 14 a bit.

Note: Turns out we never got rendering into 2 OpenGL Windows same time working.
Not going to look into this for now as it's not a new bug (never seems to have worked).
If anyone has more information (like maybe it's not possible?) be nice and tell us in the forum.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6302 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2022-03-09 18:26:23 +00:00
parent 3ad07543be
commit c20d3d08b6

@ -1,19 +1,15 @@
/** Example 014 Win32 Window /** Example 014 Win32 Window
This example only runs under MS Windows and demonstrates that Irrlicht can This example runs only under MS Windows and demonstrates how Irrlicht can
render inside a win32 window. MFC and .NET Windows.Forms windows are possible, render inside a win32 window. MFC and .NET Windows.Forms windows are possible,
too. too.*/
In the beginning, we create a windows window using the windows API. I'm not
going to explain this code, because it is windows specific. See the MSDN or a
windows book for details.
*/
#include <irrlicht.h> #include <irrlicht.h>
#ifndef _IRR_WINDOWS_ #ifndef _IRR_WINDOWS_
#error Windows only example #error Windows only example
#else #else
#include <windows.h> // this example only runs with windows #include <windows.h> // this example only runs with Windows
#include <iostream> #include <iostream>
#include "driverChoice.h" #include "driverChoice.h"
#include "exampleHelper.h" #include "exampleHelper.h"
@ -24,8 +20,11 @@ using namespace irr;
#pragma comment(lib, "irrlicht.lib") #pragma comment(lib, "irrlicht.lib")
#endif #endif
HWND hOKButton; HWND hOKButton = 0;
/*
Windows message handler
*/
static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message, static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam) WPARAM wParam, LPARAM lParam)
{ {
@ -53,13 +52,11 @@ static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
return DefWindowProc(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam);
} }
/*
Now ask for the driver and create the Windows specific window.
*/
int main() int main()
{ {
// ask user for driver /*
Ask user for driver
*/
video::E_DRIVER_TYPE driverType=driverChoiceConsole(); video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT) if (driverType==video::EDT_COUNT)
return 1; return 1;
@ -75,9 +72,13 @@ int main()
if (key != 'a' && key != 'b' && key != 'c') if (key != 'a' && key != 'b' && key != 'c')
return 1; return 1;
HINSTANCE hInstance = 0; /*
// create dialog Create the Windows specific window using the Windows API.
Not further explained here, please see the MSDN or a Windows book
for details about doing that.
*/
HINSTANCE hInstance = 0;
const fschar_t* Win32ClassName = __TEXT("CIrrlichtWindowsTestDialog"); const fschar_t* Win32ClassName = __TEXT("CIrrlichtWindowsTestDialog");
WNDCLASSEX wcex; WNDCLASSEX wcex;
@ -111,45 +112,54 @@ int main()
windowWidth = clientRect.right; windowWidth = clientRect.right;
windowHeight = clientRect.bottom; windowHeight = clientRect.bottom;
// create ok button // Create OK button
hOKButton = CreateWindow(__TEXT("BUTTON"), __TEXT("OK - Close"), WS_CHILD | WS_VISIBLE | BS_TEXT, hOKButton = CreateWindow(__TEXT("BUTTON"), __TEXT("OK - Close"), WS_CHILD | WS_VISIBLE | BS_TEXT,
windowWidth - 160, windowHeight - 40, 150, 30, hWnd, NULL, hInstance, NULL); windowWidth - 160, windowHeight - 40, 150, 30, hWnd, NULL, hInstance, NULL);
// create some text // Create some text
CreateWindow(__TEXT("STATIC"), __TEXT("This is Irrlicht running inside a standard Win32 window.\n")\ CreateWindow(__TEXT("STATIC"), __TEXT("This is Irrlicht running inside a standard Win32 window.\n")\
__TEXT("Also mixing with MFC and .NET Windows.Forms is possible."), __TEXT("Also mixing with MFC and .NET Windows.Forms is possible."),
WS_CHILD | WS_VISIBLE, 20, 20, 400, 40, hWnd, NULL, hInstance, NULL); WS_CHILD | WS_VISIBLE, 20, 20, 400, 40, hWnd, NULL, hInstance, NULL);
// create window to put irrlicht in // Create a window to put Irrlicht in
HWND hIrrlichtWindow = CreateWindow(__TEXT("BUTTON"), __TEXT(""), HWND hIrrlichtWindow = CreateWindow(__TEXT("BUTTON"), __TEXT(""),
WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
50, 80, 320, 220, hWnd, NULL, hInstance, NULL); 50, 80, 320, 220, hWnd, NULL, hInstance, NULL);
video::SExposedVideoData videodata((key=='b')?hIrrlichtWindow:0);
/* /*
So now that we have some window, we can create an Irrlicht device So now that we have some Windows window, we can use it with Irrlicht.
inside of it. We use Irrlicht createEx() function for this. We only There's several options.
need the handle (HWND) to that window, set it as windowsID parameter
and start up the engine as usual. That's it.
*/ */
// create irrlicht device in the button window
irr::SIrrlichtCreationParameters param; irr::SIrrlichtCreationParameters param;
param.DriverType = driverType; param.DriverType = driverType;
/* First option: We create an Irrlicht device inside of the Windows window.
We use Irrlicht createEx() function for this. We do need the
handle (HWND) for that window, set it as windowsID parameter
and start up the engine as usual. That's it.
*/
if (key=='a') if (key=='a')
param.WindowId = reinterpret_cast<void*>(hIrrlichtWindow); param.WindowId = reinterpret_cast<void*>(hIrrlichtWindow);
irr::IrrlichtDevice* device = irr::createDeviceEx(param); irr::IrrlichtDevice* device = irr::createDeviceEx(param);
// setup a simple 3d scene
irr::scene::ISceneManager* smgr = device->getSceneManager(); irr::scene::ISceneManager* smgr = device->getSceneManager();
video::IVideoDriver* driver = device->getVideoDriver(); video::IVideoDriver* driver = device->getVideoDriver();
if (driverType==video::EDT_OPENGL) /*
Second option: We create a typical Irrlicht device, but render to the Window window.
For rendering into another Window than the one used for creating the Irrlicht device
we have to pass some changed SExposedVideoData to beginScene which contains the
HWND of the Windows window.
*/
video::SExposedVideoData videodata((key=='b')?hIrrlichtWindow:0);
/*
OpenGL needs a bit more setup.
Also not yet working as well (haven't figured out yet how to render into the Irrlicht window as well)
*/
if (key == 'b' && driverType==video::EDT_OPENGL)
{ {
HDC HDc=GetDC(hIrrlichtWindow); HDC HDc=GetDC(hIrrlichtWindow);
PIXELFORMATDESCRIPTOR pfd={0}; PIXELFORMATDESCRIPTOR pfd={0};
@ -164,6 +174,10 @@ int main()
videodata.OpenGLWin32.HRc=wglCreateContext(HDc); videodata.OpenGLWin32.HRc=wglCreateContext(HDc);
wglShareLists((HGLRC)driver->getExposedVideoData().OpenGLWin32.HRc, (HGLRC)videodata.OpenGLWin32.HRc); wglShareLists((HGLRC)driver->getExposedVideoData().OpenGLWin32.HRc, (HGLRC)videodata.OpenGLWin32.HRc);
} }
/*
Setup a simple 3d scene
*/
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode(); scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
cam->setTarget(core::vector3df(0,0,0)); cam->setTarget(core::vector3df(0,0,0));
@ -190,32 +204,36 @@ int main()
driver->getTexture(mediaPath + "irrlicht2_bk.jpg")); driver->getTexture(mediaPath + "irrlicht2_bk.jpg"));
// This shows that we can render to multiple windows within one application // This shows that we can render to multiple windows within one application
// TODO: Currently not working with OpenGL
device->getGUIEnvironment()->addStaticText(core::stringw("Second screen render").c_str(),core::recti(0,0,200,200)); device->getGUIEnvironment()->addStaticText(core::stringw("Second screen render").c_str(),core::recti(0,0,200,200));
// show and execute dialog // show and execute the Windows dialog
ShowWindow(hWnd , SW_SHOW); ShowWindow(hWnd , SW_SHOW);
UpdateWindow(hWnd); UpdateWindow(hWnd);
// do message queue // do message queue
#if 1 // Irrlicht does the message handling with device->run()
/* /*
Now the only thing missing is the drawing loop using Now the only thing missing is the drawing loop using
IrrlichtDevice::run(). We do this as usual. But instead of this, there IrrlichtDevice::run(). We do this as usual. But instead of this, there
is another possibility: You can also simply use your own message loop is another possibility: You can also use your own message loop
using GetMessage, DispatchMessage and whatever. Calling using GetMessage, DispatchMessage and whatever. Calling
Device->run() will cause Irrlicht to dispatch messages internally too. device->run() will cause Irrlicht to dispatch messages internally too.
You need not call Device->run() if you want to do your own message You need not call device->run() if you want to do your own message
dispatching loop, but Irrlicht will not be able to fetch user input dispatching loop, but Irrlicht will not be able to fetch user input
then and you have to do it on your own using the window messages, then and you have to do it on your own using the window messages,
DirectInput, or whatever. DirectInput, or whatever.
*/ */
while (device->run()) while (device->run())
{ {
// draw 3d scene
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0), 1.f, 0, videodata); driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0), 1.f, 0, videodata);
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
// draw gui into second window
if (key=='b') if (key=='b')
{ {
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0xbbbbbbbb)); driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0xbbbbbbbb));
@ -224,12 +242,13 @@ int main()
} }
} }
#else // Windows API does the message handling
/* /*
The alternative, own message dispatching loop without Device->run() The alternative, own message dispatching loop without Device->run()
would look like this: would look like this:
*/ */
/*MSG msg; MSG msg;
while (true) while (true)
{ {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
@ -244,11 +263,20 @@ int main()
// advance virtual time // advance virtual time
device->getTimer()->tick(); device->getTimer()->tick();
// draw engine picture // draw 3d scene
driver->beginScene(true, true, 0, (key=='c')?hIrrlichtWindow:0); driver->beginScene(true, true, 0, videodata);
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
}*/
// draw gui into second window
if (key=='b')
{
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0xbbbbbbbb));
device->getGUIEnvironment()->drawAll();
driver->endScene();
}
}
#endif
device->closeDevice(); device->closeDevice();
device->drop(); device->drop();
@ -258,5 +286,5 @@ int main()
#endif // if windows #endif // if windows
/* /*
That's it, Irrlicht now runs in your own windows window. That's it, Irrlicht now uses a Windows window.
**/ **/