I have modified the "14.
" Irrlicht example to show the bug. Here it is the modified version of "
Code: Select all
// this example only runs in windows and demonstrates that Irrlicht
// can run inside a win32 window.
#include <irrlicht.h>
#include <afxwin.h>
#include <windows.h> // this example only runs with windows
using namespace irr;
#pragma comment(lib, "irrlicht.lib")
const int IDFILTER = 8;
irr::scene::ISceneManager* smgr;
video::IVideoDriver* driver;
/////////////////////////////////////////
/////////////////////////////////////////
class C3DWnd : public CWnd
{
public:
C3DWnd();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
scene::ISceneNode* m_selectedSceneNode;
protected:
DECLARE_MESSAGE_MAP()
};
C3DWnd::C3DWnd()
{
smgr = NULL;
driver = NULL;
m_selectedSceneNode = 0;
}
void C3DWnd::OnMouseMove(UINT nFlags, CPoint point)
{
scene::ISceneNode* selectedSceneNode = 0;
selectedSceneNode = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(core::position2d<s32>(point.x, point.y), IDFILTER);
if (m_selectedSceneNode)
if (selectedSceneNode != m_selectedSceneNode)
m_selectedSceneNode->getMaterial(0).EmissiveColor.set(0,0,0,0);
if (selectedSceneNode)
{
selectedSceneNode->getMaterial(0).EmissiveColor.set(128, 255, 0, 0);
m_selectedSceneNode = selectedSceneNode;
driver->beginScene(true, true, 0);
smgr->drawAll();
driver->endScene();
}
CWnd::OnMouseMove(nFlags, point);
}
BEGIN_MESSAGE_MAP(C3DWnd, CWnd)
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
/////////////////////////////////////////
/////////////////////////////////////////
C3DWnd g_3DWnd;
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;
//case WM_MOUSEMOVE:
// break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
int main()
//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hpre, LPSTR cmd, int cc)
{
HINSTANCE hInstance = 0;
// create dialog
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 = 800;
int windowHeight = 600;
hWnd = CreateWindow( Win32ClassName, "Irrlicht Win32 window example: ---Shifted Mouse Coordinates Bug---",
style, 100, 100, windowWidth, windowHeight,
NULL, NULL, hInstance, NULL);
RECT clientRect;
GetClientRect(hWnd, &clientRect);
windowWidth = clientRect.right;
windowHeight = clientRect.bottom;
// create ok button
hOKButton = CreateWindow("BUTTON", "OK - Close", WS_CHILD | WS_VISIBLE | BS_TEXT,
windowWidth - 160, windowHeight - 40, 150, 30, hWnd, NULL, hInstance, NULL);
// create some text
CreateWindow("STATIC", "Move the mouse over the objects to see the Shifted Mouse Coordinates Bug\n"\
"In the left-down corner works fine, but try in the other corners...",
WS_CHILD | WS_VISIBLE, 20, 20, 600, 40, hWnd, NULL, hInstance, NULL);
// create window to put irrlicht in
//HWND hIrrlichtWindow = CreateWindow("BUTTON", "", WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
// 50, 80, 700, 430, hWnd, NULL, hInstance, NULL);
g_3DWnd.CreateEx(NULL, "BUTTON", "", WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
50, 80, 700, 430, hWnd, NULL, NULL);
g_3DWnd.SetFocus();
// create irrlicht device in the button window
irr::SIrrlichtCreationParameters param;
// param.WindowId = reinterpret_cast<s32>(hIrrlichtWindow); // hColorButton
param.WindowId = reinterpret_cast<s32>(g_3DWnd.m_hWnd); // hColorButton
param.DriverType = video::EDT_OPENGL;
irr::IrrlichtDevice* device = irr::createDeviceEx(param);
// setup a simple 3d scene
smgr = device->getSceneManager();
driver = device->getVideoDriver();
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode(NULL, core::vector3df(5,5,10),
core::vector3df(0,0,0));
cam->setTarget(core::vector3df(10,10,0));
//scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(core::vector3df(0,15,0), 30.0f);
//cam->addAnimator(anim);
//anim->drop();
for (int y = 0; y < 10; y++)
{
for (int x = 0; x < 10; x++)
{
//scene::ISceneNode* DotSceneNode = smgr->addCubeSceneNode(1, NULL, IDFILTER,
// core::vector3df(4*x,4*y,0));
scene::ISceneNode* DotSceneNode = smgr->addSphereSceneNode(.5, 8, NULL, IDFILTER,
core::vector3df(6*x,6*y,0));
DotSceneNode->getMaterial(0).AmbientColor.set(128, 0, 0, 255);
DotSceneNode->setMaterialFlag( video::EMF_LIGHTING, true );
DotSceneNode->setMaterialFlag( video::EMF_NORMALIZE_NORMALS, true);
}
}
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"));
// Lights:
scene::ILightSceneNode* pIrrLight1 = smgr->addLightSceneNode(0, core::vector3df(0.7,0.4,0.6),
video::SColorf(0.6f, 0.6f, 0.6f));
pIrrLight1->getLightData().Type = video::ELT_DIRECTIONAL;
pIrrLight1->getLightData().AmbientColor = video::SColorf(0.6f, 0.6f, 0.6f);
scene::ILightSceneNode* pIrrLight2 = smgr->addLightSceneNode(0, core::vector3df(-0.4,-0.7,-0.3),
video::SColorf(0.2f, 0.2f, 0.2f));
pIrrLight2->getLightData().Type = video::ELT_DIRECTIONAL;
// show and execute dialog
ShowWindow(hWnd , SW_SHOW);
UpdateWindow(hWnd);
// do message queue
// Instead of this, you can also simply use your own message loop
// using GetMessage, DispatchMessage and whatever. Calling
// Device->run() will cause Irrlicht to dispatch messages internally too.
// 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 then and you have to do it on your own using the window
// messages, DirectInput, or whatever.
for (int i = 0; i < 100; i++)
{
driver->beginScene(true, true, 0);
smgr->drawAll();
driver->endScene();
cam->setTarget(core::vector3df(i/10.0,i/10.0,2));
cam->setPosition(core::vector3df(15.0-i/10.0,15.0-i/10.0,8));
cam->setFarValue(10000000.0f);
cam->setScale(core::vector3df(1.0,1.0,1.0));
Sleep(1);
}
MSG msg;
while (device->run())
{
driver->beginScene(true, true, 0);
smgr->drawAll();
driver->endScene();
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(1);
}
// the alternative, own message dispatching loop without Device->run() would
// look like this:
/*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();
// draw engine picture
driver->beginScene(true, true, 0);
smgr->drawAll();
driver->endScene();
}*/
device->closeDevice();
device->drop();
return 0;
}
.