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:
cutealien
2022-04-15 18:51:09 +00:00
parent 67469c8899
commit 2d63fdba3d
115 changed files with 1828 additions and 1154 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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));

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.
**/

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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.
**/

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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.
*/

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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") );

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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