mirror of
https://github.com/minetest/irrlicht.git
synced 2025-06-28 06:20:21 +02:00
Merging r6288 through r6336 from trunk to ogl-es branch
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6337 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -201,7 +201,7 @@ int main()
|
||||
*/
|
||||
int lastFPS = -1;
|
||||
|
||||
// In order to do framerate independent movement, we have to know
|
||||
// In order to do frame rate independent movement, we have to know
|
||||
// how long it was since the last frame
|
||||
u32 then = device->getTimer()->getTime();
|
||||
|
||||
@ -215,21 +215,24 @@ int main()
|
||||
const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
|
||||
then = now;
|
||||
|
||||
/* Check if keys W, S, A or D are being held down, and move the
|
||||
sphere node around respectively. */
|
||||
core::vector3df nodePosition = sphereNode->getPosition();
|
||||
if ( sphereNode )
|
||||
{
|
||||
/* Check if keys W, S, A or D are being held down, and move the
|
||||
sphere node around respectively. */
|
||||
core::vector3df nodePosition = sphereNode->getPosition();
|
||||
|
||||
if(receiver.IsKeyDown(irr::KEY_KEY_W))
|
||||
nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
|
||||
else if(receiver.IsKeyDown(irr::KEY_KEY_S))
|
||||
nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime;
|
||||
if(receiver.IsKeyDown(irr::KEY_KEY_W))
|
||||
nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
|
||||
else if(receiver.IsKeyDown(irr::KEY_KEY_S))
|
||||
nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime;
|
||||
|
||||
if(receiver.IsKeyDown(irr::KEY_KEY_A))
|
||||
nodePosition.X -= MOVEMENT_SPEED * frameDeltaTime;
|
||||
else if(receiver.IsKeyDown(irr::KEY_KEY_D))
|
||||
nodePosition.X += MOVEMENT_SPEED * frameDeltaTime;
|
||||
if(receiver.IsKeyDown(irr::KEY_KEY_A))
|
||||
nodePosition.X -= MOVEMENT_SPEED * frameDeltaTime;
|
||||
else if(receiver.IsKeyDown(irr::KEY_KEY_D))
|
||||
nodePosition.X += MOVEMENT_SPEED * frameDeltaTime;
|
||||
|
||||
sphereNode->setPosition(nodePosition);
|
||||
sphereNode->setPosition(nodePosition);
|
||||
}
|
||||
|
||||
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,113,113,133));
|
||||
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -1,19 +1,15 @@
|
||||
/** 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,
|
||||
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>
|
||||
#ifndef _IRR_WINDOWS_
|
||||
#error Windows only example
|
||||
#else
|
||||
#include <windows.h> // this example only runs with windows
|
||||
#include <windows.h> // this example only runs with Windows
|
||||
#include <iostream>
|
||||
#include "driverChoice.h"
|
||||
#include "exampleHelper.h"
|
||||
@ -24,9 +20,11 @@ using namespace irr;
|
||||
#pragma comment(lib, "irrlicht.lib")
|
||||
#endif
|
||||
|
||||
HWND hOKButton;
|
||||
HWND hWnd;
|
||||
HWND hOKButton = 0;
|
||||
|
||||
/*
|
||||
Windows message handler
|
||||
*/
|
||||
static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@ -54,13 +52,11 @@ static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Now ask for the driver and create the Windows specific window.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
// ask user for driver
|
||||
/*
|
||||
Ask user for driver
|
||||
*/
|
||||
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
|
||||
if (driverType==video::EDT_COUNT)
|
||||
return 1;
|
||||
@ -76,9 +72,13 @@ int main()
|
||||
if (key != 'a' && key != 'b' && key != 'c')
|
||||
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");
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
@ -103,7 +103,7 @@ int main()
|
||||
int windowWidth = 440;
|
||||
int windowHeight = 380;
|
||||
|
||||
hWnd = CreateWindow( Win32ClassName, __TEXT("Irrlicht Win32 window example"),
|
||||
HWND hWnd = CreateWindow( Win32ClassName, __TEXT("Irrlicht Win32 window example"),
|
||||
style, 100, 100, windowWidth, windowHeight,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
|
||||
@ -112,45 +112,54 @@ int main()
|
||||
windowWidth = clientRect.right;
|
||||
windowHeight = clientRect.bottom;
|
||||
|
||||
// create ok button
|
||||
|
||||
// Create OK button
|
||||
hOKButton = CreateWindow(__TEXT("BUTTON"), __TEXT("OK - Close"), WS_CHILD | WS_VISIBLE | BS_TEXT,
|
||||
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")\
|
||||
__TEXT("Also mixing with MFC and .NET Windows.Forms is possible."),
|
||||
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(""),
|
||||
WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
|
||||
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
|
||||
inside of it. We use Irrlicht createEx() function for this. We only
|
||||
need the handle (HWND) to that window, set it as windowsID parameter
|
||||
and start up the engine as usual. That's it.
|
||||
So now that we have some Windows window, we can use it with Irrlicht.
|
||||
There's several options.
|
||||
*/
|
||||
// create irrlicht device in the button window
|
||||
|
||||
|
||||
irr::SIrrlichtCreationParameters param;
|
||||
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')
|
||||
param.WindowId = reinterpret_cast<void*>(hIrrlichtWindow);
|
||||
|
||||
irr::IrrlichtDevice* device = irr::createDeviceEx(param);
|
||||
|
||||
// setup a simple 3d scene
|
||||
|
||||
irr::scene::ISceneManager* smgr = device->getSceneManager();
|
||||
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);
|
||||
PIXELFORMATDESCRIPTOR pfd={0};
|
||||
@ -165,6 +174,10 @@ int main()
|
||||
videodata.OpenGLWin32.HRc=wglCreateContext(HDc);
|
||||
wglShareLists((HGLRC)driver->getExposedVideoData().OpenGLWin32.HRc, (HGLRC)videodata.OpenGLWin32.HRc);
|
||||
}
|
||||
|
||||
/*
|
||||
Setup a simple 3d scene
|
||||
*/
|
||||
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
|
||||
cam->setTarget(core::vector3df(0,0,0));
|
||||
|
||||
@ -191,32 +204,36 @@ int main()
|
||||
driver->getTexture(mediaPath + "irrlicht2_bk.jpg"));
|
||||
|
||||
// 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));
|
||||
|
||||
// show and execute dialog
|
||||
|
||||
// show and execute the Windows dialog
|
||||
ShowWindow(hWnd , SW_SHOW);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
// do message queue
|
||||
|
||||
#if 1 // Irrlicht does the message handling with device->run()
|
||||
|
||||
/*
|
||||
Now the only thing missing is the drawing loop using
|
||||
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
|
||||
Device->run() will cause Irrlicht to dispatch messages internally too.
|
||||
You need not call Device->run() if you want to do your own message
|
||||
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.
|
||||
*/
|
||||
|
||||
while (device->run())
|
||||
{
|
||||
// draw 3d scene
|
||||
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0), 1.f, 0, videodata);
|
||||
smgr->drawAll();
|
||||
driver->endScene();
|
||||
|
||||
// draw gui into second window
|
||||
if (key=='b')
|
||||
{
|
||||
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0xbbbbbbbb));
|
||||
@ -225,12 +242,13 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
#else // Windows API does the message handling
|
||||
/*
|
||||
The alternative, own message dispatching loop without Device->run()
|
||||
would look like this:
|
||||
*/
|
||||
|
||||
/*MSG msg;
|
||||
MSG msg;
|
||||
while (true)
|
||||
{
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
@ -245,11 +263,20 @@ int main()
|
||||
// advance virtual time
|
||||
device->getTimer()->tick();
|
||||
|
||||
// draw engine picture
|
||||
driver->beginScene(true, true, 0, (key=='c')?hIrrlichtWindow:0);
|
||||
// draw 3d scene
|
||||
driver->beginScene(true, true, 0, videodata);
|
||||
smgr->drawAll();
|
||||
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->drop();
|
||||
@ -259,5 +286,5 @@ int main()
|
||||
#endif // if windows
|
||||
|
||||
/*
|
||||
That's it, Irrlicht now runs in your own windows window.
|
||||
That's it, Irrlicht now uses a Windows window.
|
||||
**/
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -41,7 +41,7 @@ using namespace irr;
|
||||
using namespace scene;
|
||||
|
||||
/*
|
||||
Again, to be able to use the Irrlicht.DLL file, we need to link with the
|
||||
Again, to be able to use the Irrlicht.dll on Windows, we link with the
|
||||
Irrlicht.lib. We could set this option in the project settings, but
|
||||
to make it easy, we use a pragma comment lib:
|
||||
*/
|
||||
@ -66,25 +66,25 @@ public:
|
||||
|
||||
bool OnEvent(const SEvent& event)
|
||||
{
|
||||
// check if user presses the key F9
|
||||
if ((event.EventType == EET_KEY_INPUT_EVENT) &&
|
||||
event.KeyInput.PressedDown)
|
||||
{
|
||||
// check if user presses the key F9 for making a screenshot
|
||||
if (event.KeyInput.Key == KEY_F9)
|
||||
{
|
||||
video::IImage* image = Device->getVideoDriver()->createScreenShot();
|
||||
if (image)
|
||||
{
|
||||
c8 buf[256];
|
||||
snprintf_irr(buf, 256, "%s_shot%04d.jpg",
|
||||
snprintf_irr(buf, 256, "%s_shot%04u.jpg",
|
||||
FilenameTemplate.c_str(),
|
||||
++Number);
|
||||
Device->getVideoDriver()->writeImageToFile(image, buf, 85 );
|
||||
image->drop();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (event.KeyInput.Key == KEY_F8)
|
||||
// Check for F8 - enabling/disabling display of bounding box for the map
|
||||
else if (event.KeyInput.Key == KEY_F8)
|
||||
{
|
||||
if (Node->isDebugDataVisible())
|
||||
Node->setDebugDataVisible(scene::EDS_OFF);
|
||||
@ -112,7 +112,7 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
/*
|
||||
Like in the HelloWorld example, we create an IrrlichtDevice with
|
||||
createDevice(). The difference now is that we ask the user to select
|
||||
which hardware accelerated driver to use. The Software device would be
|
||||
which hardware accelerated driver to use. The Software device might be
|
||||
too slow to draw a huge Quake 3 map, but just for the fun of it, we make
|
||||
this decision possible too.
|
||||
*/
|
||||
@ -130,6 +130,7 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
if (device == 0)
|
||||
return 1; // could not create selected driver.
|
||||
|
||||
// We allow passing a map name as command line parameter
|
||||
const char* mapname=0;
|
||||
if (argc>2)
|
||||
mapname = argv[2];
|
||||
@ -170,7 +171,7 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
|
||||
/*
|
||||
Now we can load the mesh by calling getMesh(). We get a pointer returned
|
||||
to a IAnimatedMesh. As you know, Quake 3 maps are not really animated,
|
||||
to an IAnimatedMesh. As you know, Quake 3 maps are not really animated,
|
||||
they are only a huge chunk of static geometry with some materials
|
||||
attached. Hence the IAnimated mesh consists of only one frame,
|
||||
so we get the "first frame" of the "animation", which is our quake level
|
||||
@ -203,9 +204,9 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
device->setEventReceiver(&screenshotFactory);
|
||||
|
||||
/*
|
||||
now construct SceneNodes for each Shader
|
||||
The Objects are stored in the quake mesh scene::E_Q3_MESH_ITEMS
|
||||
and the Shader ID is stored in the MaterialParameters
|
||||
now construct SceneNodes for each shader
|
||||
The objects are stored in the quake mesh scene::E_Q3_MESH_ITEMS
|
||||
and the shader ID is stored in the MaterialParameters
|
||||
mostly dark looking skulls and moving lava.. or green flashing tubes?
|
||||
*/
|
||||
if ( mesh )
|
||||
@ -253,9 +254,9 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
/*
|
||||
Now we only need a Camera to look at the Quake 3 map. And we want to
|
||||
Now we only need a camera to look at the Quake 3 map. And we want to
|
||||
create a user controlled camera. There are some different cameras
|
||||
available in the Irrlicht engine. For example the Maya Camera which can
|
||||
available in the Irrlicht engine. For example the Maya camera which can
|
||||
be controlled comparable to the camera in Maya: Rotate with left mouse
|
||||
button pressed, Zoom with both buttons pressed, translate with right
|
||||
mouse button pressed. This could be created with
|
||||
@ -266,8 +267,8 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
|
||||
|
||||
/*
|
||||
so we need a good starting Position in the level.
|
||||
we can ask the Quake3 Loader for all entities with class_name
|
||||
so we need a good starting position in the level.
|
||||
we can ask the Quake3 loader for all entities with class_name
|
||||
"info_player_deathmatch"
|
||||
we choose a random launch
|
||||
*/
|
||||
@ -356,6 +357,8 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
gui->drawAll();
|
||||
driver->endScene();
|
||||
|
||||
// Display some info
|
||||
// Setting window caption can be rather slow, so usually shouldn't be done each frame.
|
||||
int fps = driver->getFPS();
|
||||
if (1 || lastFPS != fps)
|
||||
{
|
||||
@ -376,7 +379,7 @@ int IRRCALLCONV main(int argc, char* argv[])
|
||||
str += "/";
|
||||
str += attr->getAttributeAsInt("drawn_transparent_effect");
|
||||
#endif
|
||||
device->setWindowCaption(str.c_str());
|
||||
device->setWindowCaption(str.c_str());
|
||||
lastFPS = fps;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ Target = 17.HelloWorld_Mobile
|
||||
Sources = main.cpp
|
||||
|
||||
# general compiler settings
|
||||
CPPFLAGS = -I../../include -I/usr/X11R6/include
|
||||
CPPFLAGS = -I../../include
|
||||
CXXFLAGS = -O3 -ffast-math
|
||||
#CXXFLAGS = -g -Wall
|
||||
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
A tutorial by Max Winkel.
|
||||
|
||||
In this tutorial we'll learn how to use splitscreen (e.g. for racing-games)
|
||||
with Irrlicht. We'll create a viewport divided
|
||||
into 4 parts, with 3 fixed cameras and one user-controlled.
|
||||
In this tutorial we'll learn how to use split screen (e.g. for racing-games)
|
||||
with Irrlicht. We'll create a viewport divided into 4 parts, with 3 fixed
|
||||
cameras and one user-controlled.
|
||||
|
||||
Ok, let's start with the headers (I think there's
|
||||
OK, let's start with the headers (I think there's
|
||||
nothing to say about it)
|
||||
*/
|
||||
|
||||
@ -23,55 +23,62 @@ using namespace irr;
|
||||
using namespace core;
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
using namespace gui;
|
||||
|
||||
/*
|
||||
Now we'll define the resolution in a constant for use in
|
||||
initializing the device and setting up the viewport. In addition
|
||||
we set up a global variable saying splitscreen is active or not.
|
||||
initializing the device and setting up the viewport.
|
||||
*/
|
||||
|
||||
//Resolution
|
||||
const int ResX=800;
|
||||
const int ResY=600;
|
||||
const bool fullScreen=false;
|
||||
|
||||
//Use SplitScreen?
|
||||
bool SplitScreen=true;
|
||||
|
||||
// We allow quitting the with the ESC key
|
||||
bool Quit = false;
|
||||
|
||||
/*
|
||||
Now we need four pointers to our cameras which are created later:
|
||||
We need four pointers to our cameras which are created later:
|
||||
*/
|
||||
//cameras
|
||||
ICameraSceneNode *camera[4]={0,0,0,0};
|
||||
ICameraSceneNode *Camera[4]={0,0,0,0};
|
||||
|
||||
/*
|
||||
In our event-receiver we switch the SplitScreen-variable,
|
||||
whenever the user press the S-key. All other events are sent
|
||||
to the FPS camera.
|
||||
whenever the user press the S-key.
|
||||
We also allow quitting the application with ESC.
|
||||
*/
|
||||
|
||||
class MyEventReceiver : public IEventReceiver
|
||||
{
|
||||
public:
|
||||
virtual bool OnEvent(const SEvent& event)
|
||||
{
|
||||
//Key S enables/disables SplitScreen
|
||||
if (event.EventType == irr::EET_KEY_INPUT_EVENT &&
|
||||
event.KeyInput.Key == KEY_KEY_S && event.KeyInput.PressedDown)
|
||||
if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown )
|
||||
{
|
||||
SplitScreen = !SplitScreen;
|
||||
return true;
|
||||
if ( event.KeyInput.Key == KEY_KEY_S )
|
||||
{
|
||||
SplitScreen = !SplitScreen;
|
||||
return true;
|
||||
}
|
||||
if (event.KeyInput.Key == KEY_ESCAPE )
|
||||
{
|
||||
Quit = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//Send all other events to camera4
|
||||
if (camera[3])
|
||||
return camera[3]->OnEvent(event);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Ok, now the main-function:
|
||||
First, we initialize the device, get the SourceManager and
|
||||
VideoDriver, load an animated mesh from .md2 and a map from
|
||||
.pk3. Because that's old stuff, I won't explain every step.
|
||||
The main-function:
|
||||
First, we initialize the device, get some useful variables,
|
||||
load an animated mesh from .md2 and a map from .pk3.
|
||||
Because that's old stuff, I won't explain every step.
|
||||
Just take care of the maps position.
|
||||
*/
|
||||
int main()
|
||||
@ -84,7 +91,8 @@ int main()
|
||||
//Instance of the EventReceiver
|
||||
MyEventReceiver receiver;
|
||||
|
||||
//Initialise the engine
|
||||
//Initialize the engine
|
||||
const bool fullScreen=false;
|
||||
IrrlichtDevice *device = createDevice(driverType,
|
||||
dimension2du(ResX,ResY), 32, fullScreen,
|
||||
false, false, &receiver);
|
||||
@ -93,6 +101,7 @@ int main()
|
||||
|
||||
ISceneManager *smgr = device->getSceneManager();
|
||||
IVideoDriver *driver = device->getVideoDriver();
|
||||
IGUIEnvironment* guienv = device->getGUIEnvironment();
|
||||
|
||||
const io::path mediaPath = getExampleMediaPath();
|
||||
|
||||
@ -121,6 +130,9 @@ int main()
|
||||
map_node->setPosition(vector3df(-850,-220,-850));
|
||||
}
|
||||
|
||||
// Add some static text gui element, to give users information and how to show how using the UI works.
|
||||
guienv->addStaticText(L"<S> to switch split screen.\n<ESC> to quit", recti(5,5, 100, 30), false, true, 0, -1, true);
|
||||
|
||||
/*
|
||||
Now we create our four cameras. One is looking at the model
|
||||
from the front, one from the top and one from the side. In
|
||||
@ -129,19 +141,19 @@ user.
|
||||
*/
|
||||
// Create 3 fixed and one user-controlled cameras
|
||||
//Front
|
||||
camera[0] = smgr->addCameraSceneNode(0, vector3df(50,0,0), vector3df(0,0,0));
|
||||
Camera[0] = smgr->addCameraSceneNode(0, vector3df(50,0,0), vector3df(0,0,0));
|
||||
//Top
|
||||
camera[1] = smgr->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0));
|
||||
Camera[1] = smgr->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0));
|
||||
//Left
|
||||
camera[2] = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0));
|
||||
Camera[2] = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0));
|
||||
//User-controlled
|
||||
camera[3] = smgr->addCameraSceneNodeFPS();
|
||||
// don't start at sydney's position
|
||||
if (camera[3])
|
||||
camera[3]->setPosition(core::vector3df(-50,0,-50));
|
||||
Camera[3] = smgr->addCameraSceneNodeFPS();
|
||||
// don't start at Sydney's position
|
||||
if (Camera[3])
|
||||
Camera[3]->setPosition(core::vector3df(-50,0,-50));
|
||||
|
||||
/*
|
||||
Create a variable for counting the fps and hide the mouse:
|
||||
Hide the mouse and create a variable for counting the fps:
|
||||
*/
|
||||
//Hide mouse
|
||||
device->getCursorControl()->setVisible(false);
|
||||
@ -150,12 +162,12 @@ Create a variable for counting the fps and hide the mouse:
|
||||
|
||||
/*
|
||||
There wasn't much new stuff - till now!
|
||||
Only by defining four cameras, the game won't be splitscreen.
|
||||
To do this you need several steps:
|
||||
The game won't be split the screen just by defining four cameras.
|
||||
To do this several steps are needed:
|
||||
- Set the viewport to the whole screen
|
||||
- Begin a new scene (Clear screen)
|
||||
|
||||
- The following 3 steps are repeated for every viewport in the splitscreen
|
||||
- The following 3 steps are repeated for every viewport in the split screen
|
||||
- Set the viewport to the area you wish
|
||||
- Activate the camera which should be "linked" with the viewport
|
||||
- Render all objects
|
||||
@ -168,31 +180,31 @@ To do this you need several steps:
|
||||
Sounds a little complicated, but you'll see it isn't:
|
||||
*/
|
||||
|
||||
while(device->run())
|
||||
while(!Quit && device->run())
|
||||
{
|
||||
// Don't reset mouse cursor when window is not active
|
||||
camera[3]->setInputReceiverEnabled(device->isWindowActive());
|
||||
Camera[3]->setInputReceiverEnabled(device->isWindowActive());
|
||||
|
||||
//Set the viewpoint to the whole screen and begin scene
|
||||
driver->setViewPort(rect<s32>(0,0,ResX,ResY));
|
||||
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, SColor(255,100,100,100));
|
||||
//If SplitScreen is used
|
||||
//If split screen is used
|
||||
if (SplitScreen)
|
||||
{
|
||||
//Activate camera1
|
||||
smgr->setActiveCamera(camera[0]);
|
||||
smgr->setActiveCamera(Camera[0]);
|
||||
//Set viewpoint to the first quarter (left top)
|
||||
driver->setViewPort(rect<s32>(0,0,ResX/2,ResY/2));
|
||||
//Draw scene
|
||||
smgr->drawAll();
|
||||
//Activate camera2
|
||||
smgr->setActiveCamera(camera[1]);
|
||||
smgr->setActiveCamera(Camera[1]);
|
||||
//Set viewpoint to the second quarter (right top)
|
||||
driver->setViewPort(rect<s32>(ResX/2,0,ResX,ResY/2));
|
||||
//Draw scene
|
||||
smgr->drawAll();
|
||||
//Activate camera3
|
||||
smgr->setActiveCamera(camera[2]);
|
||||
smgr->setActiveCamera(Camera[2]);
|
||||
//Set viewpoint to the third quarter (left bottom)
|
||||
driver->setViewPort(rect<s32>(0,ResY/2,ResX/2,ResY));
|
||||
//Draw scene
|
||||
@ -201,15 +213,21 @@ Sounds a little complicated, but you'll see it isn't:
|
||||
driver->setViewPort(rect<s32>(ResX/2,ResY/2,ResX,ResY));
|
||||
}
|
||||
//Activate camera4
|
||||
smgr->setActiveCamera(camera[3]);
|
||||
smgr->setActiveCamera(Camera[3]);
|
||||
//Draw scene
|
||||
smgr->drawAll();
|
||||
|
||||
// Back to whole screen for the UI
|
||||
if (SplitScreen)
|
||||
driver->setViewPort(rect<s32>(0,0,ResX,ResY));
|
||||
guienv->drawAll();
|
||||
|
||||
driver->endScene();
|
||||
|
||||
/*
|
||||
As you can probably see, the image is rendered for every
|
||||
viewport separately. That means, that you'll loose much performance.
|
||||
Ok, if you're asking "How do I have to set the viewport
|
||||
OK, if you're asking "How do I have to set the viewport
|
||||
to get this or that screen?", don't panic. It's really
|
||||
easy: In the rect-function you define 4 coordinates:
|
||||
- X-coordinate of the corner left top
|
||||
@ -225,10 +243,8 @@ Sounds a little complicated, but you'll see it isn't:
|
||||
If you didn't fully understand, just play around with the example
|
||||
to check out what happens.
|
||||
|
||||
Now we just view the current fps and shut down the engine,
|
||||
when the user wants to:
|
||||
Last we show the current fps.
|
||||
*/
|
||||
//Get and show fps
|
||||
if (driver->getFPS() != lastFPS)
|
||||
{
|
||||
lastFPS = driver->getFPS();
|
||||
@ -244,7 +260,4 @@ Sounds a little complicated, but you'll see it isn't:
|
||||
}
|
||||
/*
|
||||
That's it! Just compile and play around with the program.
|
||||
Note: With the S-Key you can switch between using splitscreen
|
||||
and not.
|
||||
**/
|
||||
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -3,13 +3,11 @@
|
||||
This tutorial builds on example 04.Movement which showed how to
|
||||
handle keyboard events in Irrlicht. Here we'll handle mouse events
|
||||
and joystick events, if you have a joystick connected and a device
|
||||
that supports joysticks. These are currently Windows, Linux and SDL
|
||||
that supports joysticks. These are currently Windows, Linux and SDL
|
||||
devices.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// We'll define this to stop MSVC complaining about sprintf().
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma comment(lib, "Irrlicht.lib")
|
||||
#endif
|
||||
|
||||
@ -19,8 +17,21 @@ devices.
|
||||
using namespace irr;
|
||||
|
||||
/*
|
||||
Just as we did in example 04.Movement, we'll store the latest state of the
|
||||
Just as we did in example 04.Movement with keys, we'll store the latest state of the
|
||||
mouse and the first joystick, updating them as we receive events.
|
||||
|
||||
Note that instead of working with events we could work with CursorControl, aka
|
||||
device->getCursorControl(), to get the current mouse state.
|
||||
With events you get every mouse movement since the last device->run(),
|
||||
while CursorControl will always return the current state at the moment you check it.
|
||||
CursorControl will be able to get cursor positions even if the mouse is outside the
|
||||
active Window, while the behavior of mouse-events for this is a bit system dependent
|
||||
and also can be influenced by system calls for mouse-grabbing.
|
||||
Events tend to work on more devices (especially mobile devices) where CursorControl might
|
||||
not be available. Also on some systems (X11) checking the mouse position with CursorControl
|
||||
can be rather slow compared to events.
|
||||
Often it depends a bit on the type of game which solution is preferable, just be aware
|
||||
that you have some choice for this.
|
||||
*/
|
||||
class MyEventReceiver : public IEventReceiver
|
||||
{
|
||||
@ -30,7 +41,8 @@ public:
|
||||
{
|
||||
core::position2di Position;
|
||||
bool LeftButtonDown;
|
||||
SMouseState() : LeftButtonDown(false) { }
|
||||
bool WasMouseMoved;
|
||||
SMouseState() : LeftButtonDown(false), WasMouseMoved(false) { }
|
||||
} MouseState;
|
||||
|
||||
// This is the one method that we have to implement
|
||||
@ -52,6 +64,7 @@ public:
|
||||
case EMIE_MOUSE_MOVED:
|
||||
MouseState.Position.X = event.MouseInput.X;
|
||||
MouseState.Position.Y = event.MouseInput.Y;
|
||||
MouseState.WasMouseMoved = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -63,7 +76,6 @@ public:
|
||||
// The state of each connected joystick is sent to us
|
||||
// once every run() of the Irrlicht device. Store the
|
||||
// state of the first joystick, ignoring other joysticks.
|
||||
// This is currently only supported on Windows and Linux.
|
||||
if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT
|
||||
&& event.JoystickEvent.Joystick == 0)
|
||||
{
|
||||
@ -83,9 +95,9 @@ public:
|
||||
return MouseState;
|
||||
}
|
||||
|
||||
|
||||
MyEventReceiver()
|
||||
void ResetMouseMoved()
|
||||
{
|
||||
MouseState.WasMouseMoved = false;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -94,11 +106,9 @@ private:
|
||||
|
||||
|
||||
/*
|
||||
The event receiver for keeping the pressed keys is ready, the actual responses
|
||||
The event receiver for remembering the events is ready, the actual responses
|
||||
will be made inside the render loop, right before drawing the scene. So lets
|
||||
just create an irr::IrrlichtDevice and the scene node we want to move. We also
|
||||
create some other additional scene nodes, to show that there are also some
|
||||
different possibilities to move and animate scene nodes.
|
||||
just create an irr::IrrlichtDevice and the scene node we want to move.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
@ -117,6 +127,11 @@ int main()
|
||||
return 1; // could not create selected driver.
|
||||
|
||||
|
||||
/*
|
||||
Joysticks have to be activated to generate events.
|
||||
So lets's do that and also print out some info to the console
|
||||
about all the joysticks we found and can use.
|
||||
*/
|
||||
core::array<SJoystickInfo> joystickInfo;
|
||||
if(device->activateJoysticks(joystickInfo))
|
||||
{
|
||||
@ -153,6 +168,7 @@ int main()
|
||||
std::cout << "Joystick support is not enabled." << std::endl;
|
||||
}
|
||||
|
||||
// Set some window caption text
|
||||
core::stringw tmp = L"Irrlicht Joystick Example (";
|
||||
tmp += joystickInfo.size();
|
||||
tmp += " joysticks)";
|
||||
@ -179,20 +195,24 @@ int main()
|
||||
camera->setPosition(core::vector3df(0, 0, -10));
|
||||
|
||||
// As in example 04, we'll use framerate independent movement.
|
||||
u32 then = device->getTimer()->getTime();
|
||||
u32 then = device->getTimer()->getRealTime();
|
||||
const f32 MOVEMENT_SPEED = 5.f;
|
||||
|
||||
// Ignore all events which happened until now.
|
||||
// Like mouse events triggered while we chose our driver.
|
||||
device->clearSystemMessages();
|
||||
|
||||
while(device->run())
|
||||
{
|
||||
// Work out a frame delta time.
|
||||
const u32 now = device->getTimer()->getTime();
|
||||
const u32 now = device->getTimer()->getRealTime();
|
||||
const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
|
||||
then = now;
|
||||
|
||||
bool movedWithJoystick = false;
|
||||
core::vector3df nodePosition = node->getPosition();
|
||||
|
||||
if(joystickInfo.size() > 0)
|
||||
if(joystickInfo.size() > 0) // if we have at least one joystick
|
||||
{
|
||||
f32 moveHorizontal = 0.f; // Range is -1.f for full left to +1.f for full right
|
||||
f32 moveVertical = 0.f; // -1.f for full down to +1.f for full up.
|
||||
@ -237,11 +257,14 @@ int main()
|
||||
nodePosition.X += MOVEMENT_SPEED * frameDeltaTime * moveHorizontal;
|
||||
nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime * moveVertical;
|
||||
movedWithJoystick = true;
|
||||
|
||||
// We only go back to following mouse when it moves again
|
||||
receiver.ResetMouseMoved();
|
||||
}
|
||||
}
|
||||
|
||||
// If the arrow node isn't being moved with the joystick, then have it follow the mouse cursor.
|
||||
if(!movedWithJoystick)
|
||||
if (!movedWithJoystick && receiver.GetMouseState().WasMouseMoved)
|
||||
{
|
||||
// Create a ray through the mouse cursor.
|
||||
core::line3df ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(
|
||||
@ -257,9 +280,13 @@ int main()
|
||||
const f32 availableMovement = MOVEMENT_SPEED * frameDeltaTime;
|
||||
|
||||
if(toMousePosition.getLength() <= availableMovement)
|
||||
{
|
||||
nodePosition = mousePosition; // Jump to the final position
|
||||
}
|
||||
else
|
||||
{
|
||||
nodePosition += toMousePosition.normalize() * availableMovement; // Move towards it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -3,13 +3,13 @@
|
||||
This tutorial shows how to load different Quake 3 maps.
|
||||
|
||||
Features:
|
||||
- Load BSP Archives at Runtime from the menu
|
||||
- Load a Map from the menu. Showing with Screenshot
|
||||
- Load BSP archives at runtime from the menu
|
||||
- Load a map from the menu. Showing with screenshot
|
||||
- Set the VideoDriver at runtime from menu
|
||||
- Adjust GammaLevel at runtime
|
||||
- Create SceneNodes for the Shaders
|
||||
- Load EntityList and create Entity SceneNodes
|
||||
- Create Players with Weapons and with Collision Response
|
||||
- Create SceneNodes for the shaders
|
||||
- Load EntityList and create entity SceneNodes
|
||||
- Create players with weapons and with collision response
|
||||
- Play music
|
||||
|
||||
You can download the Quake III Arena demo ( copyright id software )
|
||||
@ -26,7 +26,7 @@ Copyright 2006-2011 Burningwater, Thomas Alten
|
||||
#include "sound.h"
|
||||
|
||||
/*
|
||||
Game Data is used to hold Data which is needed to drive the game
|
||||
GameData is used to hold data which is needed to drive the game
|
||||
*/
|
||||
struct GameData
|
||||
{
|
||||
@ -100,7 +100,7 @@ void GameData::setDefault ()
|
||||
loadParam.mergeShaderBuffer = 1; // merge meshbuffers with same material
|
||||
loadParam.cleanUnResolvedMeshes = 1; // should unresolved meshes be cleaned. otherwise blue texture
|
||||
loadParam.loadAllShaders = 1; // load all scripts in the script directory
|
||||
loadParam.loadSkyShader = 0; // load sky Shader
|
||||
loadParam.loadSkyShader = 0; // load sky shader
|
||||
loadParam.alpharef = 1;
|
||||
|
||||
sound = 0;
|
||||
@ -168,18 +168,18 @@ s32 GameData::load ( const path &filename )
|
||||
}
|
||||
|
||||
/*
|
||||
Store the current game State in a quake3 configuration file
|
||||
Store the current game state in a quake3 configuration file
|
||||
*/
|
||||
s32 GameData::save ( const path &filename )
|
||||
{
|
||||
return 0;
|
||||
return 0; // TODO: Anyone knows why it just returns?
|
||||
if (!Device)
|
||||
return 0;
|
||||
|
||||
c8 buf[128];
|
||||
u32 i;
|
||||
|
||||
// Store current Archive for restart
|
||||
// Store current archive for restart
|
||||
CurrentArchiveList.clear();
|
||||
IFileSystem *fs = Device->getFileSystem();
|
||||
for ( i = 0; i != fs->getFileArchiveCount(); ++i )
|
||||
@ -187,7 +187,7 @@ s32 GameData::save ( const path &filename )
|
||||
CurrentArchiveList.push_back ( fs->getFileArchive(i)->getFileList()->getPath() );
|
||||
}
|
||||
|
||||
// Store Player Position and Rotation
|
||||
// Store player position and rotation
|
||||
ICameraSceneNode * camera = Device->getSceneManager()->getActiveCamera ();
|
||||
if ( camera )
|
||||
{
|
||||
@ -279,7 +279,7 @@ void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode *
|
||||
|
||||
if (!device)
|
||||
return;
|
||||
// load FPS weapon to Camera
|
||||
// load FPS weapon to camera
|
||||
Device = device;
|
||||
Mesh = mesh;
|
||||
MapParent = mapNode;
|
||||
@ -377,8 +377,8 @@ void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode *
|
||||
|
||||
|
||||
/*
|
||||
so we need a good starting Position in the level.
|
||||
we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch"
|
||||
So we need a good starting position in the level.
|
||||
We can ask the Quake3 loader for all entities with class_name "info_player_deathmatch"
|
||||
*/
|
||||
void Q3Player::respawn ()
|
||||
{
|
||||
@ -396,7 +396,7 @@ void Q3Player::respawn ()
|
||||
}
|
||||
|
||||
/*
|
||||
set Player position from saved coordinates
|
||||
set player position from saved coordinates
|
||||
*/
|
||||
void Q3Player::setpos ( const vector3df &pos, const vector3df &rotation )
|
||||
{
|
||||
@ -414,7 +414,7 @@ void Q3Player::setpos ( const vector3df &pos, const vector3df &rotation )
|
||||
}
|
||||
}
|
||||
|
||||
/* set the Animation of the player and weapon
|
||||
/* set the animation of the player and weapon
|
||||
*/
|
||||
void Q3Player::setAnim ( const c8 *name )
|
||||
{
|
||||
@ -446,7 +446,7 @@ void Q3Player::OnAnimationEnd(IAnimatedMeshSceneNode* node)
|
||||
|
||||
|
||||
|
||||
/* GUI Elements
|
||||
/* GUI elements
|
||||
*/
|
||||
struct GUI
|
||||
{
|
||||
@ -560,13 +560,13 @@ CQuake3EventHandler::CQuake3EventHandler( GameData *game )
|
||||
BulletParent(0), FogParent(0), SkyNode(0), Meta(0)
|
||||
{
|
||||
buf[0]=0;
|
||||
// Also use 16 Bit Textures for 16 Bit RenderDevice
|
||||
// Also use 16 bit textures for 16 bit RenderDevice
|
||||
if ( Game->deviceParam.Bits == 16 )
|
||||
{
|
||||
game->Device->getVideoDriver()->setTextureCreationFlag(ETCF_ALWAYS_16_BIT, true);
|
||||
}
|
||||
|
||||
// Quake3 Shader controls Z-Writing
|
||||
// Quake3 shader controls Z-writing
|
||||
game->Device->getSceneManager()->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
|
||||
|
||||
// create internal textures
|
||||
@ -599,21 +599,10 @@ void CQuake3EventHandler::createTextures()
|
||||
|
||||
video::IImage* image;
|
||||
u32 i;
|
||||
u32 x;
|
||||
u32 y;
|
||||
u32 * data;
|
||||
for ( i = 0; i != 8; ++i )
|
||||
{
|
||||
image = driver->createImage ( video::ECF_A8R8G8B8, dim);
|
||||
data = (u32*) image->getData ();
|
||||
for ( y = 0; y != dim.Height; ++y )
|
||||
{
|
||||
for ( x = 0; x != dim.Width; ++x )
|
||||
{
|
||||
data [x] = 0xFFFFFFFF;
|
||||
}
|
||||
data = (u32*) ( (u8*) data + image->getPitch() );
|
||||
}
|
||||
image->fill(SColor(0xFFFFFFFF));
|
||||
snprintf_irr ( buf, 64, "smoke_%02d", i );
|
||||
driver->addTexture( buf, image );
|
||||
image->drop ();
|
||||
@ -623,15 +612,7 @@ void CQuake3EventHandler::createTextures()
|
||||
for ( i = 0; i != 1; ++i )
|
||||
{
|
||||
image = driver->createImage ( video::ECF_A8R8G8B8, dim);
|
||||
data = (u32*) image->getData ();
|
||||
for ( y = 0; y != dim.Height; ++y )
|
||||
{
|
||||
for ( x = 0; x != dim.Width; ++x )
|
||||
{
|
||||
data [x] = 0xFFFFFFFF;
|
||||
}
|
||||
data = (u32*) ( (u8*) data + image->getPitch() );
|
||||
}
|
||||
image->fill(SColor(0xFFFFFFFF));
|
||||
snprintf_irr ( buf, 64, "fog_%02d", i );
|
||||
driver->addTexture( buf, image );
|
||||
image->drop ();
|
||||
@ -644,7 +625,6 @@ void CQuake3EventHandler::createTextures()
|
||||
*/
|
||||
void CQuake3EventHandler::CreateGUI()
|
||||
{
|
||||
|
||||
IGUIEnvironment *env = Game->Device->getGUIEnvironment();
|
||||
IVideoDriver * driver = Game->Device->getVideoDriver();
|
||||
|
||||
@ -663,15 +643,6 @@ void CQuake3EventHandler::CreateGUI()
|
||||
|
||||
// minimal gui size 800x600
|
||||
dimension2d<u32> dim ( 800, 600 );
|
||||
dimension2d<u32> vdim ( Game->Device->getVideoDriver()->getScreenSize() );
|
||||
|
||||
if ( vdim.Height >= dim.Height && vdim.Width >= dim.Width )
|
||||
{
|
||||
//dim = vdim;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
gui.Window = env->addWindow ( rect<s32> ( 0, 0, dim.Width, dim.Height ), false, L"Quake3 Explorer" );
|
||||
gui.Window->setToolTipText ( L"Quake3Explorer. Loads and show various BSP File Format and Shaders." );
|
||||
@ -860,7 +831,7 @@ void CQuake3EventHandler::AddArchive ( const path& archiveName )
|
||||
}
|
||||
|
||||
// store the current archives in game data
|
||||
// show the attached Archive in proper order
|
||||
// show the attached archive in proper order
|
||||
if ( gui.ArchiveList )
|
||||
{
|
||||
gui.ArchiveList->clearRows();
|
||||
@ -998,7 +969,7 @@ void CQuake3EventHandler::AddArchive ( const path& archiveName )
|
||||
}
|
||||
|
||||
/*
|
||||
clears the Map in Memory
|
||||
clears the map in memory
|
||||
*/
|
||||
void CQuake3EventHandler::dropMap ()
|
||||
{
|
||||
@ -1113,9 +1084,9 @@ void CQuake3EventHandler::LoadMap ( const stringw &mapName, s32 collision )
|
||||
BulletParent->setName ( "Bullet Container" );
|
||||
|
||||
/*
|
||||
now construct SceneNodes for each Shader
|
||||
The Objects are stored in the quake mesh E_Q3_MESH_ITEMS
|
||||
and the Shader ID is stored in the MaterialParameters
|
||||
now construct SceneNodes for each shader
|
||||
The objects are stored in the quake mesh E_Q3_MESH_ITEMS
|
||||
and the shader ID is stored in the MaterialParameters
|
||||
mostly dark looking skulls and moving lava.. or green flashing tubes?
|
||||
*/
|
||||
Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_ITEMS,ShaderParent, Meta, false );
|
||||
@ -1123,13 +1094,13 @@ void CQuake3EventHandler::LoadMap ( const stringw &mapName, s32 collision )
|
||||
Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_UNRESOLVED,UnresolvedParent, Meta, true );
|
||||
|
||||
/*
|
||||
Now construct Models from Entity List
|
||||
Now construct models from entity list
|
||||
*/
|
||||
Q3ModelFactory ( Game->loadParam, Game->Device, Mesh, ItemParent, false );
|
||||
}
|
||||
|
||||
/*
|
||||
Adds a SceneNode with an icon to the Scene Tree
|
||||
Adds a SceneNode with an icon to the scene tree
|
||||
*/
|
||||
void CQuake3EventHandler::addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent)
|
||||
{
|
||||
@ -1169,7 +1140,7 @@ void CQuake3EventHandler::addSceneTreeItem( ISceneNode * parent, IGUITreeViewNod
|
||||
|
||||
node = nodeParent->addChildBack( msg, 0, imageIndex );
|
||||
|
||||
// Add all Animators
|
||||
// Add all animators
|
||||
list<ISceneNodeAnimator*>::ConstIterator ait = (*it)->getAnimators().begin();
|
||||
for (; ait != (*it)->getAnimators().end(); ++ait)
|
||||
{
|
||||
@ -1753,7 +1724,7 @@ void CQuake3EventHandler::useItem( Q3Player * player)
|
||||
}
|
||||
else
|
||||
{
|
||||
// doesnt collide with wall
|
||||
// doesn't collide with wall
|
||||
vector3df start = camera->getPosition();
|
||||
if ( player->WeaponNode )
|
||||
{
|
||||
@ -2104,7 +2075,7 @@ void runGame ( GameData *game )
|
||||
eventHandler->AddArchive ( game->CurrentArchiveList[i] );
|
||||
}
|
||||
|
||||
// Load a Map or startup to the GUI
|
||||
// Load a map or startup to the GUI
|
||||
if ( game->CurrentMapName.size () )
|
||||
{
|
||||
eventHandler->LoadMap ( game->CurrentMapName, 1 );
|
||||
|
@ -301,7 +301,7 @@ const SItemElement * getItemElement ( const stringc& key )
|
||||
}
|
||||
|
||||
/*!
|
||||
Quake3 Model Factory.
|
||||
Quake3 model factory.
|
||||
Takes the mesh buffers and creates scenenodes for their associated shaders
|
||||
*/
|
||||
void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam,
|
||||
@ -399,7 +399,7 @@ void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam,
|
||||
sceneNodeID += 1;
|
||||
}
|
||||
|
||||
// show Debug Shader Name
|
||||
// show debug shader name
|
||||
if ( showShaderName && node )
|
||||
{
|
||||
swprintf_irr ( (wchar_t*) buf, 64, L"%hs:%d", node->getName(),node->getID() );
|
||||
@ -413,7 +413,7 @@ void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam,
|
||||
sceneNodeID += 1;
|
||||
}
|
||||
|
||||
// create Portal Rendertargets
|
||||
// create portal rendertargets
|
||||
if ( shader )
|
||||
{
|
||||
const SVarGroup *group = shader->getGroup(1);
|
||||
@ -496,7 +496,7 @@ void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam,
|
||||
|
||||
|
||||
/*!
|
||||
create Items from Entity
|
||||
create items from entity
|
||||
*/
|
||||
void Q3ModelFactory ( Q3LevelLoadParameter &loadParam,
|
||||
IrrlichtDevice *device,
|
||||
@ -513,7 +513,7 @@ void Q3ModelFactory ( Q3LevelLoadParameter &loadParam,
|
||||
|
||||
|
||||
char buf[128];
|
||||
const SVarGroup *group;
|
||||
const SVarGroup *group = 0;
|
||||
IEntity search;
|
||||
s32 index;
|
||||
s32 lastIndex;
|
||||
@ -531,12 +531,12 @@ void Q3ModelFactory ( Q3LevelLoadParameter &loadParam,
|
||||
}
|
||||
fclose ( f );
|
||||
*/
|
||||
IAnimatedMeshMD3* model;
|
||||
SMD3Mesh * mesh;
|
||||
const SMD3MeshBuffer *meshBuffer;
|
||||
IMeshSceneNode* node;
|
||||
ISceneNodeAnimator* anim;
|
||||
const IShader *shader;
|
||||
IAnimatedMeshMD3* model = 0;
|
||||
SMD3Mesh * mesh = 0;
|
||||
const SMD3MeshBuffer *meshBuffer = 0;
|
||||
IMeshSceneNode* node = 0;
|
||||
ISceneNodeAnimator* anim = 0;
|
||||
const IShader *shader = 0;
|
||||
u32 pos;
|
||||
vector3df p;
|
||||
u32 nodeCount = 0;
|
||||
@ -546,7 +546,7 @@ void Q3ModelFactory ( Q3LevelLoadParameter &loadParam,
|
||||
if ( showShaderName )
|
||||
font = device->getGUIEnvironment()->getFont("fontlucida.png");
|
||||
|
||||
const SItemElement *itemElement;
|
||||
const SItemElement *itemElement = 0;
|
||||
|
||||
// walk list
|
||||
for ( index = 0; (u32) index < entity.size(); ++index )
|
||||
@ -706,7 +706,7 @@ s32 Q3StartPosition ( IQ3LevelMesh* mesh,
|
||||
|
||||
u32 parsepos;
|
||||
|
||||
const SVarGroup *group;
|
||||
const SVarGroup *group = 0;
|
||||
group = entityList[ index ].getGroup(1);
|
||||
|
||||
parsepos = 0;
|
||||
@ -802,7 +802,7 @@ ISceneNodeAnimatorCollisionResponse* camCollisionResponse( IrrlichtDevice * devi
|
||||
}
|
||||
|
||||
|
||||
//! internal Animation
|
||||
//! internal animation
|
||||
void setTimeFire ( TimeFire *t, u32 delta, u32 flags )
|
||||
{
|
||||
t->flags = flags;
|
||||
|
@ -46,7 +46,7 @@ enum eItemSubGroup
|
||||
CHAINGUN,
|
||||
};
|
||||
|
||||
//! aplly a special effect to the shader
|
||||
//! apply a special effect to the shader
|
||||
enum eItemSpecialEffect
|
||||
{
|
||||
SPECIAL_SFX_NONE = 0,
|
||||
@ -55,7 +55,7 @@ enum eItemSpecialEffect
|
||||
SPECIAL_SFX_ROTATE_1 = 4,
|
||||
};
|
||||
|
||||
// a List for defining a model
|
||||
// a list for defining a model
|
||||
struct SItemElement
|
||||
{
|
||||
const c8 *key;
|
||||
@ -124,11 +124,11 @@ funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename);
|
||||
|
||||
|
||||
/*
|
||||
get the current collision respone camera animator
|
||||
get the current collision response camera animator
|
||||
*/
|
||||
ISceneNodeAnimatorCollisionResponse* camCollisionResponse( IrrlichtDevice * device );
|
||||
|
||||
//! internal Animation
|
||||
//! internal animation
|
||||
enum eTimeFireFlag
|
||||
{
|
||||
FIRED = 1,
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** Example 022 Material Viewer
|
||||
|
||||
This example can be used to play around with material settings and watch the results.
|
||||
This example can be used to experiment with material settings and watch the results.
|
||||
Only the default non-shader materials are used in here.
|
||||
|
||||
You have a node with a mesh, one dynamic light and global ambient light to play around with.
|
||||
@ -9,8 +9,7 @@ You can move the camera while left-mouse button is clicked.
|
||||
*/
|
||||
|
||||
// TODO: Should be possible to set all material values by the GUI.
|
||||
// For now just change the defaultMaterial in CApp::init for the rest.
|
||||
// TODO: Allow users to switch between a sphere and a box mesh.
|
||||
// For now just change the defaultMaterial in CApp::setActiveMeshNodeType for the rest.
|
||||
|
||||
#include <irrlicht.h>
|
||||
#include "driverChoice.h"
|
||||
@ -127,9 +126,8 @@ video::E_VERTEX_TYPE getVertexTypeForMaterialType(video::E_MATERIAL_TYPE materia
|
||||
}
|
||||
|
||||
/*
|
||||
Custom GUI-control to edit colorvalues.
|
||||
Custom GUI-control to edit color values.
|
||||
*/
|
||||
// Constructor
|
||||
CColorControl::CColorControl(gui::IGUIEnvironment* guiEnv, const core::position2d<s32> & pos, const wchar_t *text, IGUIElement* parent, s32 id)
|
||||
: gui::IGUIElement(gui::EGUIET_ELEMENT, guiEnv, parent,id, core::rect< s32 >(pos, pos+core::dimension2d<s32>(80, 75)))
|
||||
, DirtyFlag(true)
|
||||
@ -147,12 +145,13 @@ CColorControl::CColorControl(gui::IGUIEnvironment* guiEnv, const core::position2
|
||||
IGUIStaticText * groupElement = guiEnv->addStaticText (L"", rectControls, true, false, this, -1, false);
|
||||
groupElement->setNotClipped(true);
|
||||
|
||||
guiEnv->addStaticText (text, core::rect<s32>(0,0,80,15), false, false, groupElement, -1, false);
|
||||
s32 border=guiEnv->getSkin()->getSize(EGDS_TEXT_DISTANCE_X);
|
||||
guiEnv->addStaticText(text, core::rect<s32>(border,border,80,15), false, false, groupElement, -1, true);
|
||||
|
||||
EditAlpha = addEditForNumbers(guiEnv, core::position2d<s32>(0,15), L"a", -1, groupElement );
|
||||
EditRed = addEditForNumbers(guiEnv, core::position2d<s32>(0,30), L"r", -1, groupElement );
|
||||
EditGreen = addEditForNumbers(guiEnv, core::position2d<s32>(0,45), L"g", -1, groupElement );
|
||||
EditBlue = addEditForNumbers(guiEnv, core::position2d<s32>(0,60), L"b", -1, groupElement );
|
||||
EditAlpha = addEditForNumbers(guiEnv, core::position2d<s32>(border,15), L"a", -1, groupElement );
|
||||
EditRed = addEditForNumbers(guiEnv, core::position2d<s32>(border,30), L"r", -1, groupElement );
|
||||
EditGreen = addEditForNumbers(guiEnv, core::position2d<s32>(border,45), L"g", -1, groupElement );
|
||||
EditBlue = addEditForNumbers(guiEnv, core::position2d<s32>(border,60), L"b", -1, groupElement );
|
||||
|
||||
ColorStatic = guiEnv->addStaticText (L"", core::rect<s32>(60,15,80,75), true, false, groupElement, -1, true);
|
||||
|
||||
@ -163,10 +162,9 @@ CColorControl::CColorControl(gui::IGUIEnvironment* guiEnv, const core::position2
|
||||
// event receiver
|
||||
bool CColorControl::OnEvent(const SEvent &event)
|
||||
{
|
||||
if ( event.EventType != EET_GUI_EVENT )
|
||||
return false;
|
||||
|
||||
if ( event.GUIEvent.Caller->getID() == ButtonSetId && event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED )
|
||||
if ( event.EventType == EET_GUI_EVENT
|
||||
&& event.GUIEvent.Caller->getID() == ButtonSetId
|
||||
&& event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED )
|
||||
{
|
||||
Color = getColorFromEdits();
|
||||
setEditsFromColor(Color);
|
||||
@ -183,60 +181,52 @@ void CColorControl::setColor(const video::SColor& col)
|
||||
setEditsFromColor(Color);
|
||||
}
|
||||
|
||||
// Add a staticbox for a description + an editbox so users can enter numbers
|
||||
// Add a statictext for a description + an editbox so users can enter numbers
|
||||
gui::IGUIEditBox* CColorControl::addEditForNumbers(gui::IGUIEnvironment* guiEnv, const core::position2d<s32> & pos, const wchar_t *text, s32 id, gui::IGUIElement * parent)
|
||||
{
|
||||
using namespace gui;
|
||||
|
||||
core::rect< s32 > rect(pos, pos+core::dimension2d<s32>(10, 15));
|
||||
guiEnv->addStaticText (text, rect, false, false, parent, -1, false);
|
||||
core::recti rect(pos, pos+core::dimension2d<s32>(10, 15));
|
||||
guiEnv->addStaticText(text, rect, false, false, parent, -1, false);
|
||||
rect += core::position2d<s32>( 20, 0 );
|
||||
rect.LowerRightCorner.X += 20;
|
||||
gui::IGUIEditBox* edit = guiEnv->addEditBox(L"0", rect, true, parent, id);
|
||||
return edit;
|
||||
}
|
||||
|
||||
// Get the color value from the editfields
|
||||
// Get the color value from the editboxes
|
||||
video::SColor CColorControl::getColorFromEdits() const
|
||||
{
|
||||
video::SColor col;
|
||||
|
||||
if (EditAlpha)
|
||||
{
|
||||
u32 alpha = core::strtoul10(core::stringc(EditAlpha->getText()).c_str());
|
||||
if (alpha > 255)
|
||||
alpha = 255;
|
||||
u32 alpha = core::min_(core::strtoul10(core::stringc(EditAlpha->getText()).c_str()), 255u);
|
||||
col.setAlpha(alpha);
|
||||
}
|
||||
|
||||
if (EditRed)
|
||||
{
|
||||
u32 red = core::strtoul10(core::stringc(EditRed->getText()).c_str());
|
||||
if (red > 255)
|
||||
red = 255;
|
||||
u32 red = core::min_(core::strtoul10(core::stringc(EditRed->getText()).c_str()), 255u);
|
||||
col.setRed(red);
|
||||
}
|
||||
|
||||
if (EditGreen)
|
||||
{
|
||||
u32 green = core::strtoul10(core::stringc(EditGreen->getText()).c_str());
|
||||
if (green > 255)
|
||||
green = 255;
|
||||
u32 green = core::min_(core::strtoul10(core::stringc(EditGreen->getText()).c_str()), 255u);
|
||||
col.setGreen(green);
|
||||
}
|
||||
|
||||
if (EditBlue)
|
||||
{
|
||||
u32 blue = core::strtoul10(core::stringc(EditBlue->getText()).c_str());
|
||||
if (blue > 255)
|
||||
blue = 255;
|
||||
u32 blue = core::min_(core::strtoul10(core::stringc(EditBlue->getText()).c_str()), 255u);
|
||||
col.setBlue(blue);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
// Fill the editfields with the value for the given color
|
||||
// Fill the editboxes with a color value
|
||||
void CColorControl::setEditsFromColor(video::SColor col)
|
||||
{
|
||||
DirtyFlag = true;
|
||||
@ -345,10 +335,9 @@ CTextureControl::CTextureControl(gui::IGUIEnvironment* guiEnv, video::IVideoDriv
|
||||
|
||||
bool CTextureControl::OnEvent(const SEvent &event)
|
||||
{
|
||||
if ( event.EventType != EET_GUI_EVENT )
|
||||
return false;
|
||||
|
||||
if ( event.GUIEvent.Caller == ComboTexture && event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED )
|
||||
if ( event.EventType == EET_GUI_EVENT
|
||||
&& event.GUIEvent.Caller == ComboTexture
|
||||
&& event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED )
|
||||
{
|
||||
DirtyFlag = true;
|
||||
}
|
||||
@ -392,13 +381,15 @@ void CTextureControl::selectTextureByName(const irr::core::stringw& name)
|
||||
void CTextureControl::updateTextures(video::IVideoDriver * driver)
|
||||
{
|
||||
s32 oldSelected = ComboTexture->getSelected();
|
||||
s32 selectNew = -1;
|
||||
core::stringw oldTextureName;
|
||||
if ( oldSelected >= 0 )
|
||||
{
|
||||
oldTextureName = ComboTexture->getItem(oldSelected);
|
||||
}
|
||||
|
||||
ComboTexture->clear();
|
||||
|
||||
s32 selectNew = -1;
|
||||
for ( u32 i=0; i < driver->getTextureCount(); ++i )
|
||||
{
|
||||
video::ITexture * texture = driver->getTextureByIndex(i);
|
||||
@ -422,60 +413,70 @@ void CTextureControl::updateTextures(video::IVideoDriver * driver)
|
||||
/*
|
||||
Control which allows setting some of the material values for a meshscenenode
|
||||
*/
|
||||
void CMaterialControl::init(scene::IMeshSceneNode* node, IrrlichtDevice * device, const core::position2d<s32> & pos, const wchar_t * description)
|
||||
void CMaterialControl::init(IrrlichtDevice * device, const core::position2d<s32> & pos, const wchar_t * description)
|
||||
{
|
||||
if ( Initialized || !node || !device) // initializing twice or with invalid data not allowed
|
||||
if ( Initialized || !device) // initializing twice or with invalid data not allowed
|
||||
return;
|
||||
|
||||
Driver = device->getVideoDriver ();
|
||||
gui::IGUIEnvironment* guiEnv = device->getGUIEnvironment();
|
||||
//scene::ISceneManager* smgr = device->getSceneManager();
|
||||
const video::SMaterial & material = node->getMaterial(0);
|
||||
|
||||
s32 top = pos.Y;
|
||||
|
||||
// Description
|
||||
guiEnv->addStaticText(description, core::rect<s32>(pos.X, top, pos.X+60, top+15), false, false, 0, -1, false);
|
||||
guiEnv->addStaticText(description, core::rect<s32>(pos.X, top, pos.X+150, top+15), true, false, 0, -1, true);
|
||||
top += 15;
|
||||
|
||||
// Control for material type
|
||||
core::rect<s32> rectCombo(pos.X, top, 150, top+15);
|
||||
core::rect<s32> rectCombo(pos.X, top, pos.X+150, top+15);
|
||||
top += 15;
|
||||
ComboMaterial = guiEnv->addComboBox (rectCombo);
|
||||
for ( int i=0; i <= (int)video::EMT_ONETEXTURE_BLEND; ++i )
|
||||
{
|
||||
ComboMaterial->addItem( core::stringw(video::sBuiltInMaterialTypeNames[i]).c_str() );
|
||||
}
|
||||
ComboMaterial->setSelected( (s32)material.MaterialType );
|
||||
ComboMaterial->setSelected(0);
|
||||
|
||||
// Control to enable/disabling material lighting
|
||||
core::rect<s32> rectBtn(core::position2d<s32>(pos.X, top), core::dimension2d<s32>(100, 15));
|
||||
top += 15;
|
||||
ButtonLighting = guiEnv->addButton (rectBtn, 0, -1, L"Lighting");
|
||||
ButtonLighting->setIsPushButton(true);
|
||||
ButtonLighting->setPressed(material.Lighting);
|
||||
core::rect<s32> rectInfo( rectBtn.LowerRightCorner.X, rectBtn.UpperLeftCorner.Y, rectBtn.LowerRightCorner.X+40, rectBtn.UpperLeftCorner.Y+15 );
|
||||
core::rect<s32> rectInfo( rectBtn.LowerRightCorner.X, rectBtn.UpperLeftCorner.Y, rectBtn.LowerRightCorner.X+50, rectBtn.UpperLeftCorner.Y+15 );
|
||||
InfoLighting = guiEnv->addStaticText(L"", rectInfo, true, false );
|
||||
InfoLighting->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER );
|
||||
|
||||
// Controls for colors
|
||||
TypicalColorsControl = new CTypicalColorsControl(guiEnv, core::position2d<s32>(pos.X, top), true, guiEnv->getRootGUIElement());
|
||||
top += 300;
|
||||
TypicalColorsControl->setColorsToMaterialColors(material);
|
||||
|
||||
// Controls for selecting the material textures
|
||||
guiEnv->addStaticText(L"Textures", core::rect<s32>(pos.X, top, pos.X+60, top+15), false, false, 0, -1, false);
|
||||
guiEnv->addStaticText(L"Textures", core::rect<s32>(pos.X, top, pos.X+150, top+15), true, false, 0, -1, true);
|
||||
top += 15;
|
||||
|
||||
for (irr::u32 i=0; i<irr::video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
// The default material types only use first 2 textures
|
||||
irr::u32 maxTextures = core::min_(2u, irr::video::MATERIAL_MAX_TEXTURES);
|
||||
for (irr::u32 i=0; i<maxTextures; ++i)
|
||||
{
|
||||
TextureControls[i] = new CTextureControl(guiEnv, Driver, core::position2di(pos.X, top), guiEnv->getRootGUIElement());
|
||||
TextureControls.push_back(new CTextureControl(guiEnv, Driver, core::position2di(pos.X, top), guiEnv->getRootGUIElement()));
|
||||
top += 15;
|
||||
}
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
void CMaterialControl::setMaterial(const irr::video::SMaterial & material)
|
||||
{
|
||||
if (ComboMaterial)
|
||||
ComboMaterial->setSelected( (s32)material.MaterialType );
|
||||
if (ButtonLighting)
|
||||
ButtonLighting->setPressed(material.Lighting);
|
||||
if (TypicalColorsControl)
|
||||
TypicalColorsControl->setColorsToMaterialColors(material);
|
||||
for (irr::u32 i=0; i<TextureControls.size(); ++i)
|
||||
TextureControls[i]->setDirty();
|
||||
}
|
||||
|
||||
void CMaterialControl::update(scene::IMeshSceneNode* sceneNode, scene::IMeshSceneNode* sceneNode2T, scene::IMeshSceneNode* sceneNodeTangents)
|
||||
{
|
||||
if ( !Initialized )
|
||||
@ -525,19 +526,19 @@ void CMaterialControl::update(scene::IMeshSceneNode* sceneNode, scene::IMeshScen
|
||||
|
||||
TypicalColorsControl->resetDirty();
|
||||
|
||||
for (irr::u32 i=0; i<irr::video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
for (irr::u32 i=0; i<TextureControls.size(); ++i)
|
||||
TextureControls[i]->resetDirty();
|
||||
}
|
||||
|
||||
void CMaterialControl::updateTextures()
|
||||
{
|
||||
for (irr::u32 i=0; i<irr::video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
for (irr::u32 i=0; i<TextureControls.size(); ++i)
|
||||
TextureControls[i]->updateTextures(Driver);
|
||||
}
|
||||
|
||||
void CMaterialControl::selectTextures(const irr::core::stringw& name)
|
||||
{
|
||||
for (irr::u32 i=0; i<irr::video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
for (irr::u32 i=0; i<TextureControls.size(); ++i)
|
||||
TextureControls[i]->selectTextureByName(name);
|
||||
}
|
||||
|
||||
@ -550,11 +551,11 @@ void CMaterialControl::updateMaterial(video::SMaterial & material)
|
||||
{
|
||||
TypicalColorsControl->updateMaterialColors(material);
|
||||
material.Lighting = ButtonLighting->isPressed();
|
||||
for (irr::u32 i=0; i<irr::video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
for (irr::u32 i=0; i<TextureControls.size(); ++i)
|
||||
{
|
||||
if ( TextureControls[i]->isDirty() )
|
||||
{
|
||||
material.TextureLayer[i].Texture = Driver->getTexture( io::path(TextureControls[i]->getSelectedTextureName()) );
|
||||
material.TextureLayer[i].Texture = Driver->findTexture( io::path(TextureControls[i]->getSelectedTextureName()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -568,8 +569,10 @@ void CLightNodeControl::init(scene::ILightSceneNode* node, gui::IGUIEnvironment*
|
||||
if ( Initialized || !node || !guiEnv) // initializing twice or with invalid data not allowed
|
||||
return;
|
||||
|
||||
guiEnv->addStaticText(description, core::rect<s32>(pos.X, pos.Y, pos.X+70, pos.Y+15), false, false, 0, -1, false);
|
||||
gui::IGUIStaticText* st = guiEnv->addStaticText(description, core::rect<s32>(pos.X, pos.Y, pos.X+80, pos.Y+15), true, false, 0, -1, true);
|
||||
st->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT);
|
||||
TypicalColorsControl = new CTypicalColorsControl(guiEnv, core::position2d<s32>(pos.X, pos.Y+15), false, guiEnv->getRootGUIElement());
|
||||
TypicalColorsControl->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT);
|
||||
const video::SLight & lightData = node->getLightData();
|
||||
TypicalColorsControl->setColorsToLightDataColors(lightData);
|
||||
Initialized = true;
|
||||
@ -588,9 +591,7 @@ void CLightNodeControl::update(scene::ILightSceneNode* node)
|
||||
Main application class
|
||||
*/
|
||||
|
||||
/*
|
||||
Event handler
|
||||
*/
|
||||
// Event handler
|
||||
bool CApp::OnEvent(const SEvent &event)
|
||||
{
|
||||
if (event.EventType == EET_GUI_EVENT)
|
||||
@ -618,13 +619,33 @@ bool CApp::OnEvent(const SEvent &event)
|
||||
|
||||
case gui::EGET_FILE_SELECTED:
|
||||
{
|
||||
// load the model file, selected in the file open dialog
|
||||
// load the texture file, selected in the file open dialog
|
||||
gui::IGUIFileOpenDialog* dialog =
|
||||
(gui::IGUIFileOpenDialog*)event.GUIEvent.Caller;
|
||||
loadTexture(io::path(dialog->getFileName()).c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case gui::EGET_COMBO_BOX_CHANGED:
|
||||
if (event.GUIEvent.Caller == ComboMeshType )
|
||||
{
|
||||
irr::scene::IMeshSceneNode* currentNode = getVisibleMeshNode();
|
||||
if (currentNode)
|
||||
{
|
||||
// ensure next mesh will get same color and material settings
|
||||
if ( ControlVertexColors )
|
||||
{
|
||||
video::S3DVertex * vertices = (video::S3DVertex *)currentNode->getMesh()->getMeshBuffer(0)->getVertices();
|
||||
ControlVertexColors->setColor(vertices[0].Color);
|
||||
}
|
||||
if ( MeshMaterialControl )
|
||||
MeshMaterialControl->setMaterial(currentNode->getMaterial(0));
|
||||
}
|
||||
setActiveMeshNodeType((ENodeType)ComboMeshType->getSelected());
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -702,44 +723,33 @@ bool CApp::init(int argc, char *argv[])
|
||||
subMenuFile->addItem(L"Quit", GUI_ID_QUIT);
|
||||
|
||||
// a static camera
|
||||
Camera = smgr->addCameraSceneNode (0, core::vector3df(0, 40, -40),
|
||||
core::vector3df(0, 10, 0),
|
||||
Camera = smgr->addCameraSceneNode (0, core::vector3df(0, 30, -50),
|
||||
core::vector3df(0, 0, 0),
|
||||
-1);
|
||||
|
||||
// default material
|
||||
video::SMaterial defaultMaterial;
|
||||
defaultMaterial.Shininess = 20.f;
|
||||
|
||||
// add the nodes which are used to show the materials
|
||||
SceneNode = smgr->addCubeSceneNode (30.0f, 0, -1,
|
||||
core::vector3df(0, 0, 0),
|
||||
core::vector3df(0.f, 45.f, 0.f),
|
||||
core::vector3df(1.0f, 1.0f, 1.0f));
|
||||
SceneNode->getMaterial(0) = defaultMaterial;
|
||||
setActiveMeshNodeType(ENT_CUBE);
|
||||
|
||||
const s32 controlsTop = 20;
|
||||
MeshMaterialControl = new CMaterialControl();
|
||||
MeshMaterialControl->init( SceneNode, Device, core::position2d<s32>(10,controlsTop), L"Material" );
|
||||
MeshMaterialControl->init( Device, core::position2d<s32>(10,controlsTop), L"Material");
|
||||
MeshMaterialControl->setMaterial(SceneNode->getMaterial(0));
|
||||
MeshMaterialControl->selectTextures(core::stringw("CARO_A8R8G8B8")); // set a useful default texture
|
||||
|
||||
// create nodes with other vertex types
|
||||
scene::IMesh * mesh2T = MeshManipulator->createMeshWith2TCoords(SceneNode->getMesh());
|
||||
SceneNode2T = smgr->addMeshSceneNode(mesh2T, 0, -1, SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() );
|
||||
mesh2T->drop();
|
||||
|
||||
scene::IMesh * meshTangents = MeshManipulator->createMeshWithTangents(SceneNode->getMesh(), false, false, false);
|
||||
SceneNodeTangents = smgr->addMeshSceneNode(meshTangents, 0, -1
|
||||
, SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() );
|
||||
meshTangents->drop();
|
||||
|
||||
|
||||
// add one light
|
||||
NodeLight = smgr->addLightSceneNode(0, core::vector3df(0, 0, -40),
|
||||
const f32 lightRadius = 80.f;
|
||||
NodeLight = smgr->addLightSceneNode(0, core::vector3df(0, 30, -70),
|
||||
video::SColorf(1.0f, 1.0f, 1.0f),
|
||||
35.0f);
|
||||
lightRadius);
|
||||
LightControl = new CLightNodeControl();
|
||||
LightControl->init(NodeLight, guiEnv, core::position2d<s32>(550,controlsTop), L"Dynamic light" );
|
||||
|
||||
#if 0 // enable to have some visual feedback for the light size
|
||||
scene::IMeshSceneNode* lightRadiusNode = smgr->addSphereSceneNode(lightRadius, 64, NodeLight);
|
||||
lightRadiusNode->getMaterial(0).Lighting = false;
|
||||
lightRadiusNode->getMaterial(0).Wireframe = true;
|
||||
#endif
|
||||
|
||||
// one large cube around everything. That's mainly to make the light more obvious.
|
||||
scene::IMeshSceneNode* backgroundCube = smgr->addCubeSceneNode (200.0f, 0, -1, core::vector3df(0, 0, 0),
|
||||
core::vector3df(45, 0, 0),
|
||||
@ -748,18 +758,21 @@ bool CApp::init(int argc, char *argv[])
|
||||
backgroundCube->getMaterial(0).EmissiveColor.set(255,50,50,50); // we keep some self lighting to keep texts visible
|
||||
|
||||
|
||||
// Add a the mesh vertex color control
|
||||
guiEnv->addStaticText(L"Mesh", core::rect<s32>(200, controlsTop, 270, controlsTop+15), false, false, 0, -1, false);
|
||||
ControlVertexColors = new CColorControl( guiEnv, core::position2d<s32>(200, controlsTop+15), L"Vertex colors", guiEnv->getRootGUIElement());
|
||||
video::S3DVertex * vertices = (video::S3DVertex *)SceneNode->getMesh()->getMeshBuffer(0)->getVertices();
|
||||
if ( vertices )
|
||||
{
|
||||
ControlVertexColors->setColor(vertices[0].Color);
|
||||
}
|
||||
// Add a the mesh UI controls
|
||||
gui::IGUIStaticText* stMesh = guiEnv->addStaticText(L"Mesh", core::rect<s32>(440, controlsTop, 520, controlsTop+15), true, false, 0, -1, true);
|
||||
stMesh->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT);
|
||||
ComboMeshType = guiEnv->addComboBox(core::rect<s32>(440, controlsTop+16, 520, controlsTop+30), 0, -1);
|
||||
ComboMeshType->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT);
|
||||
ComboMeshType->addItem(L"cube");
|
||||
ComboMeshType->addItem(L"sphere");
|
||||
ControlVertexColors = new CColorControl( guiEnv, core::position2d<s32>(440, controlsTop+30), L"Vertex colors", guiEnv->getRootGUIElement());
|
||||
ControlVertexColors->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT);
|
||||
ControlVertexColors->setColor(irr::video::SColor(255,255,255,255));
|
||||
|
||||
// Add a control for ambient light
|
||||
GlobalAmbient = new CColorControl( guiEnv, core::position2d<s32>(550, 300), L"Global ambient", guiEnv->getRootGUIElement());
|
||||
GlobalAmbient->setColor( smgr->getAmbientLight().toSColor() );
|
||||
GlobalAmbient->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -769,15 +782,12 @@ bool CApp::init(int argc, char *argv[])
|
||||
*/
|
||||
bool CApp::update()
|
||||
{
|
||||
using namespace irr;
|
||||
|
||||
video::IVideoDriver* videoDriver = Device->getVideoDriver();
|
||||
if ( !Device->run() )
|
||||
return false;
|
||||
|
||||
// Figure out delta time since last frame
|
||||
ITimer * timer = Device->getTimer();
|
||||
u32 newTick = timer->getRealTime();
|
||||
u32 newTick = Device->getTimer()->getRealTime();
|
||||
f32 deltaTime = RealTimeTick > 0 ? f32(newTick-RealTimeTick)/1000.f : 0.f; // in seconds
|
||||
RealTimeTick = newTick;
|
||||
|
||||
@ -807,22 +817,30 @@ bool CApp::update()
|
||||
GlobalAmbient->resetDirty();
|
||||
}
|
||||
|
||||
// Let the user move the light around
|
||||
const float zoomSpeed = 10.f * deltaTime;
|
||||
const float rotationSpeed = 100.f * deltaTime;
|
||||
if ( KeysPressed[KEY_PLUS] || KeysPressed[KEY_ADD])
|
||||
ZoomOut(NodeLight, zoomSpeed);
|
||||
if ( KeysPressed[KEY_MINUS] || KeysPressed[KEY_SUBTRACT])
|
||||
ZoomOut(NodeLight, -zoomSpeed);
|
||||
if ( KeysPressed[KEY_RIGHT])
|
||||
RotateHorizontal(NodeLight, rotationSpeed);
|
||||
if ( KeysPressed[KEY_LEFT])
|
||||
RotateHorizontal(NodeLight, -rotationSpeed);
|
||||
UpdateRotationAxis(NodeLight, LightRotationAxis);
|
||||
if ( KeysPressed[KEY_UP])
|
||||
RotateAroundAxis(NodeLight, rotationSpeed, LightRotationAxis);
|
||||
if ( KeysPressed[KEY_DOWN])
|
||||
RotateAroundAxis(NodeLight, -rotationSpeed, LightRotationAxis);
|
||||
|
||||
// Let the user move the light around
|
||||
irr::gui::IGUIElement* focus=guiEnv->getFocus(); // some checks to prevent interfering with UI input
|
||||
if ( !focus || focus == guiEnv->getRootGUIElement()
|
||||
|| focus->getType() == irr::gui::EGUIET_STATIC_TEXT
|
||||
|| focus->getType() == irr::gui::EGUIET_BUTTON
|
||||
)
|
||||
{
|
||||
if ( KeysPressed[KEY_PLUS] || KeysPressed[KEY_ADD])
|
||||
ZoomOut(NodeLight, zoomSpeed);
|
||||
if ( KeysPressed[KEY_MINUS] || KeysPressed[KEY_SUBTRACT])
|
||||
ZoomOut(NodeLight, -zoomSpeed);
|
||||
if ( KeysPressed[KEY_RIGHT])
|
||||
RotateHorizontal(NodeLight, rotationSpeed);
|
||||
if ( KeysPressed[KEY_LEFT])
|
||||
RotateHorizontal(NodeLight, -rotationSpeed);
|
||||
UpdateRotationAxis(NodeLight, LightRotationAxis);
|
||||
if ( KeysPressed[KEY_UP])
|
||||
RotateAroundAxis(NodeLight, rotationSpeed, LightRotationAxis);
|
||||
if ( KeysPressed[KEY_DOWN])
|
||||
RotateAroundAxis(NodeLight, -rotationSpeed, LightRotationAxis);
|
||||
}
|
||||
|
||||
// Let the user move the camera around
|
||||
if (MousePressed)
|
||||
@ -957,7 +975,7 @@ void CApp::createDefaultTextures(video::IVideoDriver * driver)
|
||||
imageA8R8G8B8->drop();
|
||||
}
|
||||
|
||||
// Load a texture and make sure nodes know it when more textures are available.
|
||||
// Load a texture and make sure UI knows it when more textures are available.
|
||||
void CApp::loadTexture(const io::path &name)
|
||||
{
|
||||
Device->getVideoDriver()->getTexture(name);
|
||||
@ -1004,7 +1022,7 @@ void CApp::ZoomOut(irr::scene::ISceneNode* node, irr::f32 units)
|
||||
void CApp::UpdateRotationAxis(irr::scene::ISceneNode* node, irr::core::vector3df& axis)
|
||||
{
|
||||
// Find a perpendicular axis to the x,z vector. If none found (vector straight up/down) continue to use the existing one.
|
||||
core::vector3df pos(node->getPosition());
|
||||
core::vector3df pos(node->getPosition());
|
||||
if ( !core::equals(pos.X, 0.f) || !core::equals(pos.Z, 0.f) )
|
||||
{
|
||||
axis.X = -pos.Z;
|
||||
@ -1013,6 +1031,69 @@ void CApp::UpdateRotationAxis(irr::scene::ISceneNode* node, irr::core::vector3df
|
||||
}
|
||||
}
|
||||
|
||||
void CApp::setActiveMeshNodeType(ENodeType nodeType)
|
||||
{
|
||||
scene::ISceneManager* smgr = Device->getSceneManager();
|
||||
|
||||
if ( SceneNode )
|
||||
smgr->addToDeletionQueue(SceneNode);
|
||||
SceneNode = nullptr;
|
||||
if ( SceneNode2T )
|
||||
smgr->addToDeletionQueue(SceneNode2T);
|
||||
SceneNode2T = nullptr;
|
||||
if ( SceneNodeTangents )
|
||||
smgr->addToDeletionQueue(SceneNodeTangents);
|
||||
SceneNodeTangents = nullptr;
|
||||
|
||||
// default material
|
||||
video::SMaterial defaultMaterial;
|
||||
defaultMaterial.Shininess = 20.f;
|
||||
|
||||
// add the nodes which are used to show the materials
|
||||
const irr::f32 size = 35.f;
|
||||
if ( nodeType == ENT_CUBE)
|
||||
{
|
||||
SceneNode = smgr->addCubeSceneNode (size, 0, -1,
|
||||
core::vector3df(0, 0, 0),
|
||||
core::vector3df(0.f, 45.f, 0.f),
|
||||
core::vector3df(1.0f, 1.0f, 1.0f),
|
||||
scene::ECMT_1BUF_24VTX_NP);
|
||||
// avoid wrong colored lines at cube-borders (uv's go from 0-1 currently, which does not work well with interpolation)
|
||||
for ( u32 i=0; i < irr::video::MATERIAL_MAX_TEXTURES_USED; ++i)
|
||||
{
|
||||
defaultMaterial.TextureLayer[i].TextureWrapU = irr::video::ETC_CLAMP_TO_EDGE;
|
||||
defaultMaterial.TextureLayer[i].TextureWrapV = irr::video::ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneNode = smgr->addSphereSceneNode(size*0.5f);
|
||||
}
|
||||
SceneNode->getMaterial(0) = defaultMaterial;
|
||||
// SceneNode->setDebugDataVisible(scene::EDS_NORMALS); // showing normals can sometimes be useful to understand what's going on
|
||||
|
||||
// create nodes with other vertex types
|
||||
scene::IMesh * mesh2T = MeshManipulator->createMeshWith2TCoords(SceneNode->getMesh());
|
||||
SceneNode2T = smgr->addMeshSceneNode(mesh2T, 0, -1, SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() );
|
||||
mesh2T->drop();
|
||||
|
||||
scene::IMesh * meshTangents = MeshManipulator->createMeshWithTangents(SceneNode->getMesh(), false, false, false);
|
||||
SceneNodeTangents = smgr->addMeshSceneNode(meshTangents, 0, -1
|
||||
, SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() );
|
||||
meshTangents->drop();
|
||||
}
|
||||
|
||||
irr::scene::IMeshSceneNode* CApp::getVisibleMeshNode() const
|
||||
{
|
||||
if ( SceneNode && SceneNode->isVisible() )
|
||||
return SceneNode;
|
||||
if ( SceneNode2T && SceneNode2T->isVisible() )
|
||||
return SceneNode2T;
|
||||
if ( SceneNodeTangents && SceneNodeTangents->isVisible() )
|
||||
return SceneNodeTangents;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
Short main as most is done in classes.
|
||||
*/
|
||||
|
@ -110,6 +110,12 @@ public:
|
||||
// Change active selectionbased on the texture name
|
||||
void selectTextureByName(const irr::core::stringw& name);
|
||||
|
||||
// Set dirty flag (node will update texture)
|
||||
void setDirty()
|
||||
{
|
||||
DirtyFlag = true;
|
||||
}
|
||||
|
||||
// Reset the dirty flag
|
||||
void resetDirty()
|
||||
{
|
||||
@ -140,15 +146,12 @@ public:
|
||||
CMaterialControl()
|
||||
: Initialized(false), Driver(0)
|
||||
, TypicalColorsControl(0), ButtonLighting(0), InfoLighting(0), ComboMaterial(0)
|
||||
{
|
||||
for (irr::u32 i=0; i<irr::video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
TextureControls[i] = 0;
|
||||
}
|
||||
{}
|
||||
|
||||
// Destructor
|
||||
~CMaterialControl()
|
||||
{
|
||||
for (irr::u32 i=0; i<irr::video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
for (irr::u32 i=0; i<TextureControls.size(); ++i)
|
||||
{
|
||||
if (TextureControls[i] )
|
||||
TextureControls[i]->drop();
|
||||
@ -157,7 +160,9 @@ public:
|
||||
TypicalColorsControl->drop();
|
||||
}
|
||||
|
||||
void init(irr::scene::IMeshSceneNode* node, irr::IrrlichtDevice * device, const irr::core::position2d<irr::s32> & pos, const wchar_t * description);
|
||||
void init(irr::IrrlichtDevice * device, const irr::core::position2d<irr::s32> & pos, const wchar_t * description);
|
||||
|
||||
void setMaterial(const irr::video::SMaterial & material);
|
||||
|
||||
void update(irr::scene::IMeshSceneNode* sceneNode, irr::scene::IMeshSceneNode* sceneNode2T, irr::scene::IMeshSceneNode* sceneNodeTangents);
|
||||
|
||||
@ -177,7 +182,7 @@ protected:
|
||||
irr::gui::IGUIButton * ButtonLighting;
|
||||
irr::gui::IGUIStaticText* InfoLighting;
|
||||
irr::gui::IGUIComboBox * ComboMaterial;
|
||||
CTextureControl* TextureControls[irr::video::MATERIAL_MAX_TEXTURES];
|
||||
irr::core::array<CTextureControl*> TextureControls;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -242,6 +247,7 @@ public:
|
||||
, LightRotationAxis(irr::core::vector3df(1,0,0))
|
||||
, MeshMaterialControl(0)
|
||||
, LightControl(0)
|
||||
, ComboMeshType(0)
|
||||
, ControlVertexColors(0)
|
||||
, GlobalAmbient(0)
|
||||
, MousePressed(false)
|
||||
@ -293,6 +299,14 @@ protected:
|
||||
void ZoomOut(irr::scene::ISceneNode* node, irr::f32 units);
|
||||
void UpdateRotationAxis(irr::scene::ISceneNode* node, irr::core::vector3df& axis);
|
||||
|
||||
enum ENodeType
|
||||
{
|
||||
ENT_CUBE,
|
||||
ENT_SPHERE
|
||||
};
|
||||
void setActiveMeshNodeType(ENodeType nodeType);
|
||||
|
||||
irr::scene::IMeshSceneNode* getVisibleMeshNode() const;
|
||||
|
||||
private:
|
||||
SConfig Config;
|
||||
@ -309,6 +323,7 @@ private:
|
||||
irr::core::vector3df LightRotationAxis;
|
||||
CMaterialControl* MeshMaterialControl;
|
||||
CLightNodeControl* LightControl;
|
||||
irr::gui::IGUIComboBox* ComboMeshType;
|
||||
CColorControl* ControlVertexColors;
|
||||
CColorControl* GlobalAmbient;
|
||||
bool KeysPressed[irr::KEY_KEY_CODES_COUNT];
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** Example 024 CursorControl
|
||||
|
||||
Show how to modify cursors and offer some useful tool-functions for creating cursors.
|
||||
Show how to modify cursors and offer some useful tool functions for creating cursors.
|
||||
It can also be used for experiments with the mouse in general.
|
||||
*/
|
||||
|
||||
@ -142,7 +142,7 @@ void PrintMouseEventName(const SEvent& event, stringw &result)
|
||||
}
|
||||
|
||||
/*
|
||||
Helper function to print all the state information which get from a mouse-event into a stringw
|
||||
Helper function to print all the state information from a mouse event into a stringw
|
||||
*/
|
||||
void PrintMouseState(const SEvent& event, stringw &result)
|
||||
{
|
||||
@ -295,6 +295,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if ( event.EventType == EET_KEY_INPUT_EVENT)
|
||||
{
|
||||
// Allow invisible cursor to show up again when users presses ESC
|
||||
if ( !event.KeyInput.PressedDown && event.KeyInput.Key == irr::KEY_ESCAPE )
|
||||
{
|
||||
TimerAction action;
|
||||
action.Action = ETA_MOUSE_VISIBLE;
|
||||
Context.runTimerAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -303,7 +314,7 @@ private:
|
||||
};
|
||||
|
||||
/*
|
||||
Use several imagefiles as animation frames for a sprite which can be used as cursor icon.
|
||||
Use several image files as animation frames for a sprite which can then be used as a cursor icon.
|
||||
The images in those files all need to have the same size.
|
||||
Return sprite index on success or -1 on failure
|
||||
*/
|
||||
@ -345,7 +356,7 @@ s32 AddAnimatedIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideo
|
||||
}
|
||||
|
||||
/*
|
||||
Use several images within one imagefile as animation frames for a sprite which can be used as cursor icon
|
||||
Use several images within one image file as animation frames for a sprite which can then be used as a cursor icon
|
||||
The sizes of the icons within that file all need to have the same size
|
||||
Return sprite index on success or -1 on failure
|
||||
*/
|
||||
@ -433,8 +444,6 @@ int main()
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
IGUIEnvironment* env = device->getGUIEnvironment();
|
||||
|
||||
gui::IGUISpriteBank * SpriteBankIcons;
|
||||
|
||||
SAppContext context;
|
||||
context.Device = device;
|
||||
|
||||
@ -443,23 +452,24 @@ int main()
|
||||
rectInfoStatic.UpperLeftCorner += dimension2di(0, 15);
|
||||
context.InfoStatic = env->addStaticText (L"", rectInfoStatic, true, true);
|
||||
rect< s32 > rectEventBox(10,210, 200, 400);
|
||||
env->addStaticText (L"click events (new on top)", rectEventBox, true, true);
|
||||
env->addStaticText (L"Click events (new on top)", rectEventBox, true, true);
|
||||
rectEventBox.UpperLeftCorner += dimension2di(0, 15);
|
||||
context.EventBox = env->addListBox(rectEventBox);
|
||||
rect< s32 > rectCursorBox(210,10, 400, 250);
|
||||
env->addStaticText (L"cursors, click to set the active one", rectCursorBox, true, true);
|
||||
env->addStaticText (L"Cursors, click to set the active one", rectCursorBox, true, true);
|
||||
rectCursorBox.UpperLeftCorner += dimension2di(0, 15);
|
||||
context.CursorBox = env->addListBox(rectCursorBox);
|
||||
rect< s32 > rectSpriteBox(210,260, 400, 400);
|
||||
env->addStaticText (L"sprites", rectSpriteBox, true, true);
|
||||
env->addStaticText (L"Sprites", rectSpriteBox, true, true);
|
||||
rectSpriteBox.UpperLeftCorner += dimension2di(0, 15);
|
||||
context.SpriteBox = env->addListBox(rectSpriteBox);
|
||||
|
||||
context.ButtonSetVisible = env->addButton( rect<s32>( 410, 20, 560, 40 ), 0, -1, L"set visible (delayed)" );
|
||||
context.ButtonSetInvisible = env->addButton( rect<s32>( 410, 50, 560, 70 ), 0, -1, L"set invisible (delayed)" );
|
||||
context.ButtonSimulateBadFps = env->addButton( rect<s32>( 410, 80, 560, 100 ), 0, -1, L"simulate bad FPS" );
|
||||
context.ButtonSetVisible = env->addButton( rect<s32>( 410, 20, 560, 40 ), 0, -1, L"Set visible (delayed)" );
|
||||
context.ButtonSetInvisible = env->addButton( rect<s32>( 410, 50, 560, 70 ), 0, -1, L"Set invisible (delayed)" );
|
||||
context.ButtonSimulateBadFps = env->addButton( rect<s32>( 410, 80, 560, 100 ), 0, -1, L"Simulate bad FPS" );
|
||||
context.ButtonSimulateBadFps->setIsPushButton(true);
|
||||
context.ButtonChangeIcon = env->addButton( rect<s32>( 410, 140, 560, 160 ), 0, -1, L"replace cursor icon\n(cursor+sprite must be selected)" );
|
||||
s32 t = context.SpriteBox->getAbsolutePosition().UpperLeftCorner.Y;
|
||||
context.ButtonChangeIcon = env->addButton( rect<s32>( 410, t, 560, t+20), 0, -1, L"Replace cursor icon\n(cursor+sprite must be selected)" );
|
||||
|
||||
// set the names for all the system cursors
|
||||
for ( int i=0; i < (int)gui::ECI_COUNT; ++i )
|
||||
@ -470,7 +480,7 @@ int main()
|
||||
/*
|
||||
Create sprites which then can be used as cursor icons.
|
||||
*/
|
||||
SpriteBankIcons = env->addEmptySpriteBank(io::path("cursor_icons"));
|
||||
gui::IGUISpriteBank * SpriteBankIcons = env->addEmptySpriteBank(io::path("cursor_icons"));
|
||||
context.SpriteBox->setSpriteBank(SpriteBankIcons);
|
||||
|
||||
const io::path mediaPath = getExampleMediaPath();
|
||||
@ -546,7 +556,8 @@ int main()
|
||||
driver->endScene();
|
||||
}
|
||||
|
||||
// By simulating bad fps we can find out if hardware-support for cursors works or not. If it works the cursor will move as usual,while it otherwise will just update with 2 fps now.
|
||||
// By simulating a bad frame rate we can find out if hardware support for cursors works or not.
|
||||
// If it works the cursor will move as usual, otherwise it will update with only 2 fps when SimulateBadFps is true.
|
||||
if ( context.SimulateBadFps )
|
||||
{
|
||||
device->sleep(500); // 2 fps
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -224,7 +224,7 @@ public:
|
||||
// Get setting as string
|
||||
stringw getSetting(const stringw& key) const
|
||||
{
|
||||
//the find function or irrmap returns a pointer to a map Node
|
||||
//the find function of irr::map returns a pointer to a map::Node
|
||||
//if the key can be found, otherwise it returns null
|
||||
//the map node has the function getValue and getKey, as we already know the key, we return node->getValue()
|
||||
map<stringw, stringw>::Node* n = SettingMap.find(key);
|
||||
@ -263,7 +263,7 @@ private:
|
||||
|
||||
map<stringw, stringw> SettingMap; //current config
|
||||
|
||||
stringw SettingsFile; // location of the xml, usually the
|
||||
stringw SettingsFile; // filename of the xml
|
||||
irr::IrrlichtDevice* NullDevice;
|
||||
};
|
||||
|
||||
@ -338,7 +338,7 @@ public:
|
||||
|
||||
if (App.Settings->save())
|
||||
{
|
||||
App.Gui->addMessageBox(L"settings save",L"settings saved, please restart for settings to change effect","",true);
|
||||
App.Gui->addMessageBox(L"Settings saved",L"Settings saved, please restart for settings to change effect","",true);
|
||||
}
|
||||
}
|
||||
// cancel/exit button clicked, tell the application to exit
|
||||
@ -375,7 +375,7 @@ void createSettingsDialog(SAppContext& app)
|
||||
app.Gui->getSkin()->setColor((irr::gui::EGUI_DEFAULT_COLOR)i, col);
|
||||
}
|
||||
|
||||
//create video settings windows
|
||||
//create video settings window
|
||||
gui::IGUIWindow* windowSettings = app.Gui->addWindow(rect<s32>(10,10,400,400),true,L"Videosettings");
|
||||
app.Gui->addStaticText (L"Select your desired video settings", rect< s32 >(10,20, 200, 40), false, true, windowSettings);
|
||||
|
||||
@ -434,7 +434,7 @@ int main()
|
||||
param.WindowSize.set(640,480);
|
||||
|
||||
// Try to load config.
|
||||
// I leave it as an exercise of the reader to store the configuration in the local application data folder,
|
||||
// I leave it as an exercise for the reader to store the configuration in the local application data folder,
|
||||
// the only logical place to store config data for games. For all other operating systems I redirect to your manuals
|
||||
app.Settings = new SettingManager(getExampleMediaPath() + "settings.xml");
|
||||
if ( !app.Settings->load() )
|
||||
@ -448,7 +448,7 @@ int main()
|
||||
//settings xml loaded from disk,
|
||||
|
||||
//map driversetting to driver type and test if the setting is valid
|
||||
//the DriverOptions map contains string representations mapped to to irrlicht E_DRIVER_TYPE enum
|
||||
//the DriverOptions map contains string representations mapped to to Irrlicht E_DRIVER_TYPE enum
|
||||
//e.g "direct3d9" will become 4
|
||||
//see DriverOptions in the settingmanager class for details
|
||||
map<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting("driver") );
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -5,7 +5,7 @@ Target = 27.PostProcessing
|
||||
Sources = main.cpp
|
||||
|
||||
# general compiler settings
|
||||
CPPFLAGS = -I../../include -I/usr/X11R6/include
|
||||
CPPFLAGS = -I../../include
|
||||
CXXFLAGS = -O3 -ffast-math
|
||||
#CXXFLAGS = -g -Wall
|
||||
|
||||
|
@ -5,7 +5,7 @@ Target = 28.CubeMapping
|
||||
Sources = main.cpp
|
||||
|
||||
# general compiler settings
|
||||
CPPFLAGS = -I../../include -I/usr/X11R6/include
|
||||
CPPFLAGS = -I../../include
|
||||
CXXFLAGS = -O3 -ffast-math
|
||||
#CXXFLAGS = -g -Wall
|
||||
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
@ -12,7 +12,7 @@ IrrlichtHome := ../..
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
|
Reference in New Issue
Block a user