Merged revisions 3175-3300 from trunk. Another huge update, bringing the ogl-es branch to the latest version of Irrlicht.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@3301 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2010-06-01 22:52:38 +00:00
parent 253a79d605
commit 7bae34bc61
178 changed files with 7317 additions and 3892 deletions

View File

@ -1,11 +1,82 @@
Changes in 1.7
-----------------------------
Changes in 1.7.1 (17.02.2010)
- Fix octree with frustum+parent checks enabled (didn't clip at all before). Now using plane-checks instead of edge-checks for frustum-box intersection.
- Prevent that X11 selects larger resolutions in fullscreen even when perfect fits are available.
- Ignore setResizable also on X11 when we're fullscreen to avoid messing up the window mode.
- Work around a crash when pressing ESC after closing a Messagebox (found by Acki)
- Prevent borland compile warnings in SColorHSL::FromRGB and in SVertexColorThresholdManipulator (found by mdeininger)
- Improve Windows version detection rules (Patch from brferreira)
- Make it compile on Borland compilers (thx to mdeininger)
- Make sure that CAnimatedMeshSceneNode::clone calls the virtual updateAbsolutePosition for the new object
- Fix that clones got dropped too often when SceneNodes without parent got cloned (found by Ulf)
- Make sure TAB is still recognized on X11 when shift+tab is pressed. This does also fix going to the previous tabstop on X11.
- Send EGET_ELEMENT_LEFT also when there won't be a new hovered element
- Update docs for EGET_ELEMENT_LEFT and EGET_ELEMENT_HOVERED
- Fix tooltips: Remove them when the element is hidden or removed (thx to seven for finding)
- Fix tooltips: Make (more) sure they don't get confused by gui-subelements
- Fix tooltips: Get faster relaunch times working
- Fix tooltips: Make sure hovered element is never the tooltip itself
- Fix string::remove which got in an endless loop when remove was called with an empty string (found and fixed by Ulf)
- Correctly release the GLSL shaders
- Make sure we only release an X11 atom when it was actually created
- Fix aabbox collision test, which not only broke the collision test routines, but also frustum culling, octree tests, etc.
- Fix compilation problem under OSX due to wrong glProgramParameteri usage
- mem leak in OBJ loader fixed
- Removed some default parameters to reduce ambigious situations
---------------------------
Changes in 1.7 (03.02.2010)
- Implement minimize and deminimize under OSX.
- Define sorting order for vector2d and vector3d in operators <, <=, > and >= to fix bugs 2783509 and 2783510. Operators order now by X,Y,Z and use float tolerances.
- Ogre mesh 32bit indices fixed.
- Fix tooltips for gui-elements with sub-element like IGUISpinBox (id: 2927079, found by ArakisTheKitsune)
- ITimer no longer stops when started twice
- wchar_t filesystem updates under Windows.
- Joystick POV fixed under Windows, ids fixed under OSX.
- Some updates to skinned mesh for better bones support and scaling animations.
- OSX supports external window id in creation parameters now.
- Fix bbox collision tests.
- Updates for win32 key handling
- new convenience method for flat plane creation.
- Sky dome and other meshes use VBOs by default now.
- Speed up b3d loading for files with many frames, material color flags and vertex color support enhanced.
- Add hasType to IGUIElement as a dynamic_cast substitute.
- Add another parameter to IGUISkin::draw3DWindowBackground to allow getting the client area without actually drawing
@ -26,6 +97,10 @@ Changes in 1.7
- Add clearSystemMessages to devices (implemented only for Linux and Win32 so far).
- Support changing the render window from beginScene also with OpenGL driver.
- Add getMaterial2D which allows to alter the 2d render state settings, such as filtering, anti-aliasing, thickness, etc.
- Fix incorrect cursorpos for resizable windows on Windows Vista (found and patched by buffer)
- Change the beginScene window parameter from void* to SExposedVideoData&. This will allow to manage contexts for OpenGL at some point.
@ -38,6 +113,8 @@ Changes in 1.7
- Bugfix: Mousewheel no longer sends EMIE_MOUSE_WHEEL messages twice on Linux.
- Use latest jpeglib
- refactoring: E_ATTRIBUTE_TYPE and IAttribute have now own headers
- CStringWArrayAttribute speedup
@ -48,12 +125,16 @@ Changes in 1.7
- Support AES-encrypted zip files. Should work with 128, 196, and 256 bit AES. This addition also adds a new PRNG, SHA, and other algorithms to the engine, though no interface is yet added for them. The implementation of the encryption algorithms is provided by Dr Brian Gladman.
- flattenFilename and getAbsolutePath fixed and properly added at several places.
- Added geometry shaders for OpenGL. A first version of the code was submitted by Matthew Kielan (devsh).
- Bugfix: irrArray should no longer crash when using other allocators.
- Add MaterialViewer example.
- Texture activation now back in setMaterial, which simplifies writing external material renderers (OpenGL only).
- Checkbox uses now disabled text color when disabled.
- Changed colors for window-title caption to keep them readable when not active.
@ -92,6 +173,18 @@ Changes in 1.7
New function findItemWithCommandId
New function insertItem
- new vector3d::getSphericalCoordinateAngles method.
- new triangle3d::isTotalOutsideBox method.
- Newly introduced VertexManipulator interface. This allows for very easy creation of vertex manipulation algorithms. Several manipulators, e.g. vertex color changer and transformation algorithms are already available.
- createMeshWith1TCoords avoids vertex duplication
- getRotation now handles matrices with scaling as well
- Ogre format animations now supported.
- irrArray: Fixed issues with push_front and reallocation
Changed behavior for set_pointer and clear, when free_when_destroyed is false
@ -150,8 +243,8 @@ Changes in 1.7
- draw3DTriangle now renders filled polygons, old behavior can be achieved by setting EMT_WIREFRAME
----------------
Changes in 1.6.1
-----------------------------
Changes in 1.6.1 (13.01.2010)
- Fix pingpong for CSceneNodeAnimatorFlyStraight (found by gbox)

View File

@ -2499,3 +2499,393 @@ IGUISkin.h
new enum value
EGST_COUNT
Changes for Version 1.7
-------------------------
This version has less API-breaking changes than the previous major changes. It has many new features, which simply add methods. All those changes, which affect old methods or structures are mostly put in parallel to the old (and now deprecated) methods. Only a few things are changed without backward compatibility: The texture wrap mode is split into separate U and V modes. The beginScene void* parameter has been replaced by an SExposedVideoData. Simply wrap the pointer with this struct and it should work again.
EMIE_LMOUSE_DOUBLE_CLICK replaces EMIE_MOUSE_DOUBLE_CLICK and EMIE_LMOUSE_TRIPLE_CLICK replaces EMIE_MOUSE_TRIPLE_CLICK
Elements used in the array container need now to have an operator=
Here comes the full list:
path.h
New type
struct SNamedPath
triangle3d.h
New method
bool isTotalOutsideBox(const aabbox3d<T>& box) const
ESceneNodeTypes.h
Changed enum value (from octt)
ESNT_OCTREE = MAKE_IRR_ID('o','c','t','r'),
SColor.h
New method
f32 getLightness() const
driverChoice.h
New method
static irr::video::E_DRIVER_TYPE driverChoiceConsole(bool allDrivers=true)
ITexture.h
New parameter
virtual void regenerateMipMapLevels(void* mipmapData=0) = 0;
Changed return value (from io:path)
const io::SNamedPath& getName() const { return NamedPath; }
SceneParameters.h
New scene parameters
const c8* const OBJ_TEXTURE_PATH = "OBJ_TexturePath";
const c8* const B3D_TEXTURE_PATH = "B3D_TexturePath";
IMeshManipulator.h
Not virtual anymore
void setVertexColorAlpha(IMesh* mesh, s32 alpha) const
void setVertexColors(IMesh* mesh, video::SColor color) const
void scale(IMeshBuffer* buffer, const core::vector3df& factor) const
void scaleMesh(IMesh* mesh, const core::vector3df& factor) const
void scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 level=1) const
void scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level=1) const
void transform(IMesh* mesh, const core::matrix4& m) const
void transform(IMeshBuffer* buffer, const core::matrix4& m) const
New method
template <typename Functor>
bool apply(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate=false) const
template <typename Functor>
bool apply(const Functor& func, IMesh* mesh, bool boundingBoxUpdate=false) const
virtual void recalculateTangents(IMesh* mesh, bool recalculateNormals=false,
bool smooth=false, bool angleWeighted=false) const=0;
void scale(IMesh* mesh, const core::vector3df& factor) const
New parameter
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false, bool recalculateTangents=true) const = 0;
coreutil.h
Changed return type and parameters (from stringc/w)
inline io::path& cutFilenameExtension ( io::path &dest, const io::path &source )
inline io::path& getFileNameExtension ( io::path &dest, const io::path &source )
inline io::path& deletePathFromFilename(io::path& filename)
Fixed behavior
inline io::path& deletePathFromPath(io::path& filename, s32 pathCount)
ICursorControl.h
Return const-ref
virtual const core::position2d<s32>& getPosition() = 0;
irrArray.h
Fixed allocator template usage
array(const array<T, TAlloc>& other) : data(0)
const array<T, TAlloc>& operator=(const array<T, TAlloc>& other)
bool operator == (const array<T, TAlloc>& other) const
bool operator != (const array<T, TAlloc>& other) const
Changed behavior for free_when_destroyed
void set_pointer(T* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
void set_free_when_destroyed(bool f)
irrMap.h
Renamed method (from isEmpty)
bool empty() const
New method
void swap(map<KeyType, ValueType>& other)
IAnimatedMesh.h
virtual f32 getAnimationSpeed() const =0;
IAttributes.h
Made parameters const-ref
virtual void addArray(const c8* attributeName, const core::array<core::stringw>& value) = 0;
virtual void setAttribute(const c8* attributeName, const core::array<core::stringw>& value) = 0;
virtual void setAttribute(s32 index, const core::array<core::stringw>& value) = 0;
ISceneManager.h
Renamed method (from OctTree)
virtual IMeshSceneNode* addOctreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0,
s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false) = 0;
virtual IMeshSceneNode* addOctreeSceneNode(IMesh* mesh, ISceneNode* parent=0,
s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0;
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
New parameter (makeActive)
virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent = 0,
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& lookat = core::vector3df(0,0,100),
s32 id=-1, bool makeActive=true) = 0;
virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent = 0,
f32 rotateSpeed = -1500.0f, f32 zoomSpeed = 200.0f,
f32 translationSpeed = 1500.0f, s32 id=-1,
bool makeActive=true) = 0;
virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0,
f32 rotateSpeed = 100.0f, f32 moveSpeed = 0.5f, s32 id=-1,
SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false,
f32 jumpSpeed = 0.f, bool invertMouse=false,
bool makeActive=true) = 0;
Make parameter const
virtual IMeshSceneNode* addQuake3SceneNode(const IMeshBuffer* meshBuffer, const quake3::IShader * shader,
ISceneNode* parent=0, s32 id=-1) = 0;
New parameter (loop, pingpong)
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points,
f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false) = 0;
SMaterialLayer.h
New clamp modes
ETC_MIRROR_CLAMP, ETC_MIRROR_CLAMP_TO_EDGE, ETC_MIRROR_CLAMP_TO_BORDER
New material layer modes (replaces TextureWrap)
TextureWrapU(ETC_REPEAT), TextureWrapV(ETC_REPEAT)
vector3d.h
Use tolerance to compare, changed order function to total order
bool operator<=(const vector3d<T>&other) const
bool operator>=(const vector3d<T>&other) const
bool operator<(const vector3d<T>&other) const
bool operator>(const vector3d<T>&other) const
New method
vector3d<T> getSphericalCoordinateAngles()
New method specializations
template <>
inline vector3d<s32> vector3d<s32>::operator /(s32 val) const {return core::vector3d<s32>(X/val,Y/val,Z/val);}
template <>
inline vector3d<s32>& vector3d<s32>::operator /=(s32 val) {X/=val;Y/=val;Z/=val; return *this;}
SExposedVideoData.h
New constructors
SExposedVideoData() {OpenGLWin32.HDc=0; OpenGLWin32.HRc=0; OpenGLWin32.HWnd=0;}
explicit SExposedVideoData(void* Window) {OpenGLWin32.HDc=0; OpenGLWin32.HRc=0; OpenGLWin32.HWnd=Window;}
IGUIEnvironment.h
New method
virtual IGUIFont* addFont(const io::path& name, IGUIFont* font) = 0;
New parameter (image)
virtual IGUIWindow* addMessageBox(const wchar_t* caption, const wchar_t* text=0,
bool modal = true, s32 flags = EMBF_OK, IGUIElement* parent=0, s32 id=-1, video::ITexture* image=0) = 0;
IGeometryCreator.h
New method
IMesh* createPlaneMesh(const core::dimension2d<f32>& tileSize,
const core::dimension2d<u32>& tileCount,
video::SMaterial* material,
const core::dimension2d<f32>& textureRepeatCount) const
IFileArchive.h
New archive type
EFAT_NPK = MAKE_IRR_ID('N','P','K', 0),
New member for storing the password of AES-encrypted archives
core::stringc Password;
IFileSystem.h
New parameter (password)
virtual bool addFileArchive(const path& filename, bool ignoreCase=true,
bool ignorePaths=true,
E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN,
const core::stringc& password="") =0;
IrrlichtDevice.h
New method
virtual void clearSystemMessages() = 0;
irrMath.h
Changed constant (from 1)
const s32 ROUNDING_ERROR_S32 = 0;
New method
template <class T>
inline void swap(T& a, T& b)
IGPUProgrammingServices.h
New parameters (for geometry shaders)
virtual s32 addHighLevelShaderMaterial
virtual s32 addHighLevelShaderMaterialFromFiles
virtual s32 addHighLevelShaderMaterialFromFiles
New overload (for calling with geometry shaders)
s32 addHighLevelShaderMaterial
s32 addHighLevelShaderMaterialFromFiles
s32 addHighLevelShaderMaterialFromFiles
ISceneNode.h
New types
typedef core::list<ISceneNode*> ISceneNodeList;
typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList;
IEventReceiver.h
Renamed events (split from EMIE_MOUSE_*)
EMIE_LMOUSE_DOUBLE_CLICK,
EMIE_RMOUSE_DOUBLE_CLICK,
EMIE_MMOUSE_DOUBLE_CLICK,
EMIE_LMOUSE_TRIPLE_CLICK,
EMIE_RMOUSE_TRIPLE_CLICK,
EMIE_MMOUSE_TRIPLE_CLICK,
IGUISpriteBank.h
New method
virtual s32 addTextureAsSprite(video::ITexture* texture) = 0;
virtual void clear() = 0;
SMaterial.h
Changed binary packing (non-visible from user calls)
inline f32 pack_texureBlendFunc ( const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact, const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE )
IGUISkin.h
New values
EGDS_MESSAGE_BOX_GAP_SPACE,
EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH,
EGDS_MESSAGE_BOX_MAX_TEST_WIDTH,
EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT,
EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT,
New parameter (checkClientArea)
virtual core::rect<s32> draw3DWindowBackground(IGUIElement* element,
bool drawTitleBar, video::SColor titleBarColor,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0,
core::rect<s32>* checkClientArea=0) = 0;
quaternion.h
New operator
bool operator!=(const quaternion& other) const;
New method
inline quaternion& set(const core::quaternion& quat);
inline bool equals(const quaternion& other,
const f32 tolerance = ROUNDING_ERROR_f32 ) const;
irrList.h
New method
u32 size() const
void swap(list<T>& other)
IVideoDriver.h
New render targets
ERT_MULTI_RENDER_TEXTURES
New class
struct IRenderTarget
Changed parameter (from void*)
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true,
SColor color=SColor(255,0,0,0),
const SExposedVideoData& videoData=SExposedVideoData(),
core::rect<s32>* sourceRect=0) =0;
New parameter (mipmapData)
virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0) = 0;
New method
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0)) =0;
void drawIndexedTriangleFan(const S3DVertexTangents* vertices,
u32 vertexCount, const u16* indexList, u32 triangleCount)
virtual void getFog(SColor& color, E_FOG_TYPE& fogType,
f32& start, f32& end, f32& density,
bool& pixelFog, bool& rangeFog) = 0;
virtual SMaterial& getMaterial2D() =0;
virtual void enableMaterial2D(bool enable=true) =0;
virtual core::dimension2du getMaxTextureSize() const =0;
Made non-virtual
void drawIndexedTriangleList(const S3DVertex* vertices,
u32 vertexCount, const u16* indexList, u32 triangleCount)
void drawIndexedTriangleList(const S3DVertex2TCoords* vertices,
u32 vertexCount, const u16* indexList, u32 triangleCount)
void drawIndexedTriangleList(const S3DVertexTangents* vertices,
u32 vertexCount, const u16* indexList, u32 triangleCount)
void drawIndexedTriangleFan(const S3DVertex* vertices,
u32 vertexCount, const u16* indexList, u32 triangleCount)
void drawIndexedTriangleFan(const S3DVertex2TCoords* vertices,
u32 vertexCount, const u16* indexList, u32 triangleCount)
EDriverFeatures.h
New driver feature enums
EVDF_MULTIPLE_RENDER_TARGETS,
EVDF_MRT_BLEND,
EVDF_MRT_COLOR_MASK,
EVDF_MRT_BLEND_FUNC,
EVDF_GEOMETRY_SHADER,
IGUIWindow.h
New method
virtual core::rect<s32> getClientRect() const = 0;
IGUIContextMenu.h
New enum
enum ECONTEXT_MENU_CLOSE
New method
virtual void setCloseHandling(ECONTEXT_MENU_CLOSE onClose) = 0;
virtual ECONTEXT_MENU_CLOSE getCloseHandling() const = 0;
virtual u32 insertItem(u32 idx, const wchar_t* text, s32 commandId=-1, bool enabled=true,
bool hasSubMenu=false, bool checked=false, bool autoChecking=false) = 0;
virtual s32 findItemWithCommandId(s32 commandId, u32 idxStartSearch=0) const = 0;
virtual void setItemAutoChecking(u32 idx, bool autoChecking) = 0;
virtual bool getItemAutoChecking(u32 idx) const = 0;
virtual void setEventParent(IGUIElement *parent) = 0;
New parameter
virtual u32 addItem(const wchar_t* text, s32 commandId=-1, bool enabled=true,
bool hasSubMenu=false, bool checked=false, bool autoChecking=false) = 0;
SIrrCreationParameters.h
New parameter (LoggingLevel)
createDevice
matrix4.h
New method
bool equals(const core::CMatrix4<T>& other, const T tolerance=(T)ROUNDING_ERROR_f64) const;
SSkinMeshBuffer.h
Renamed method (from MoveTo_2TCoords)
virtual void convertTo2TCoords()
Renamed method (from MoveTo_Tangents)
virtual void convertToTangents()
SVertexManipulator.h
New classes (for vertex manipulation)
class SVertexColorSetManipulator : public IVertexManipulator
class SVertexColorSetAlphaManipulator : public IVertexManipulator
class SVertexColorInvertManipulator : public IVertexManipulator
class SVertexColorThresholdManipulator : public IVertexManipulator
class SVertexColorBrightnessManipulator : public IVertexManipulator
class SVertexColorContrastManipulator : public IVertexManipulator
class SVertexColorContrastBrightnessManipulator : public IVertexManipulator
class SVertexColorGammaManipulator : public IVertexManipulator
;
class SVertexColorScaleManipulator : public IVertexManipulator
class SVertexColorDesaturateToLightnessManipulator : public IVertexManipulator
class SVertexColorDesaturateToAverageManipulator : public IVertexManipulator
class SVertexColorDesaturateToLuminanceManipulator : public IVertexManipulator
class SVertexColorInterpolateLinearManipulator : public IVertexManipulator
class SVertexColorInterpolateQuadraticManipulator : public IVertexManipulator
class SVertexPositionScaleManipulator : public IVertexManipulator
;
class SVertexPositionScaleAlongNormalsManipulator : public IVertexManipulator
class SVertexPositionTransformManipulator : public IVertexManipulator
class SVertexTCoordsScaleManipulator : public IVertexManipulator
IMeshCache.h
Renamed method (from getMeshByFilename)
virtual IAnimatedMesh* getMeshByName(const io::path& name) = 0;
Renamed method and changed return type (from getMeshFilename/io::path)
virtual const io::SNamedPath& getMeshName(u32 index) const = 0;
virtual const io::SNamedPath& getMeshName(const IAnimatedMesh* const mesh) const = 0;
virtual const io::SNamedPath& getMeshName(const IMesh* const mesh) const = 0;
Renamed method (from setMeshFilename)
virtual bool renameMesh(u32 index, const io::path& name) = 0;
virtual bool renameMesh(const IAnimatedMesh* const mesh, const io::path& name) = 0;
virtual bool renameMesh(const IMesh* const mesh, const io::path& name) = 0;
IGUIElement.h
Changed parameter (to const-ref)
IGUIElement(EGUI_ELEMENT_TYPE type, IGUIEnvironment* environment, IGUIElement* parent,
s32 id, const core::rect<s32>& rectangle)
New method
virtual bool hasType(EGUI_ELEMENT_TYPE type) const
irrString.h
Changed parameter (to template with allocator) in all methods with templates
Made destructor non-virtual
~string()
Added parameter
s32 find(const B* const str, const u32 start = 0) const
New method
void remove(T c)
void remove(const string<T,TAlloc> toRemove)
void removeChars(const string<T,TAlloc> & characters)
template<class container>
u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
vector2d.h
Use tolerance to compare, changed order function to total order
bool operator<=(const vector2d<T>&other) const
bool operator>=(const vector2d<T>&other) const
bool operator<(const vector2d<T>&other) const
bool operator>(const vector2d<T>&other) const

View File

@ -47,6 +47,9 @@ int main()
which video 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.
Instead of copying this whole code into your app, you can simply include
driverChoice.h from Irrlicht's include directory. The function
driverChoiceConsole does exactly the same.
*/
// ask user for driver
@ -54,8 +57,8 @@ int main()
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) OpenGL-ES1\n (e) Software Renderer\n (f) Burning's Software Renderer\n"\
" (a) OpenGL 1.5\n (b) Direct3D 9.0c\n (c) Direct3D 8.1\n"\
" (d) OpenGL-ES1\n (e) Burning's Software Renderer\n (f) Software Renderer\n"\
" (g) NullDevice\n (otherKey) exit\n\n");
char i;
@ -63,12 +66,12 @@ int main()
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'a': driverType = video::EDT_OPENGL; break;
case 'b': driverType = video::EDT_DIRECT3D9;break;
case 'c': driverType = video::EDT_DIRECT3D8;break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_SOFTWARE; break;
case 'f': driverType = video::EDT_BURNINGSVIDEO;break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_SOFTWARE; break;
case 'g': driverType = video::EDT_NULL; break;
default: return 1;
}

View File

@ -20,7 +20,7 @@ To start, I include the header files, use the irr namespace,
and tell the linker to link with the .lib file.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -167,28 +167,10 @@ the engine, create the scene node and a camera, and look at the result.
*/
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 0;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device

View File

@ -7,7 +7,7 @@
<Option compiler="gcc" />
<Build>
<Target title="Windows">
<Option output="../../bin/gcc/Movement" prefix_auto="0" extension_auto="1" />
<Option output="..\..\bin\Win32-gcc\Movement" prefix_auto="0" extension_auto="1" />
<Option type="1" />
<Option compiler="gcc" />
<Option projectResourceIncludeDirsRelation="1" />
@ -17,12 +17,12 @@
<Add option="-D_IRR_STATIC_LIB_" />
</Compiler>
<Linker>
<Add directory="../../lib/Win32-gcc" />
<Add directory="..\..\lib\Win32-gcc" />
</Linker>
</Target>
<Target title="Linux">
<Option platforms="Unix;" />
<Option output="../../bin/Linux/Movement" prefix_auto="0" extension_auto="0" />
<Option output="..\..\bin\Linux\Movement" prefix_auto="0" extension_auto="0" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
@ -32,7 +32,7 @@
<Linker>
<Add library="Xxf86vm" />
<Add library="GL" />
<Add directory="../../lib/Linux" />
<Add directory="..\..\lib\Linux" />
</Linker>
</Target>
</Build>
@ -42,7 +42,7 @@
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add directory="../../include" />
<Add directory="..\..\include" />
</Compiler>
<Linker>
<Add library="Irrlicht" />
@ -51,6 +51,7 @@
<Extensions>
<code_completion />
<debugger />
<envvars />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -18,7 +18,7 @@ and tell the linker to link with the .lib file.
#endif
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -70,28 +70,10 @@ different possibilities to move and animate scene nodes.
*/
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 0;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device
MyEventReceiver receiver;

View File

@ -11,7 +11,7 @@ a counter variable for changing the creation position of a window,
and a pointer to a listbox.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -159,27 +159,9 @@ example:
int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device and exit if creation failed

View File

@ -10,7 +10,7 @@ As always, I include the header files, use the irr namespace,
and tell the linker to link with the .lib file.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -24,28 +24,10 @@ a caption, and get a pointer to the video driver.
*/
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 0;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device

View File

@ -1,17 +1,17 @@
/** Example 007 Collision
We will describe 2 methods: Automatic collision detection for moving through 3d worlds
with stair climbing and sliding, and manual scene node and triangle picking using a
ray. In this case, we will use a ray coming out from the camera, but you can use
any ray.
We will describe 2 methods: Automatic collision detection for moving through
3d worlds with stair climbing and sliding, and manual scene node and triangle
picking using a ray. In this case, we will use a ray coming out from the
camera, but you can use any ray.
To start, we take the program from tutorial 2, which loads and displays a quake
3 level. We will use the level to walk in it and to pick triangles from. In
addition we'll place 3 animated models into it for triangle picking. The
following code starts up the engine and loads a quake 3 level, as per tutorial 2.
To start, we take the program from tutorial 2, which loads and displays a
quake 3 level. We will use the level to walk in it and to pick triangles from.
In addition we'll place 3 animated models into it for triangle picking. The
following code starts up the engine and loads the level, as per tutorial 2.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -37,28 +37,10 @@ enum
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 0;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device

View File

@ -14,6 +14,7 @@ runs slow on your hardware.
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -33,26 +34,9 @@ int main()
const bool shadows = (i == 'y');
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
/*
Create device and exit if creation failed. We make the stencil flag

View File

@ -14,7 +14,7 @@ statements, so we do not need to write the whole names of all classes. In this
tutorial, we use a lot stuff from the gui namespace.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
using namespace gui;
@ -168,9 +168,9 @@ void loadModel(const c8* fn)
{
// modify the name if it a .pk3 file
core::stringc filename(fn);
io::path filename(fn);
core::stringc extension;
io::path extension;
core::getFileNameExtension(extension, filename);
extension.make_lower();
@ -648,27 +648,9 @@ is quite useful for a mesh viewer.
int main(int argc, char* argv[])
{
// ask user for driver
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D8;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char key;
std::cin >> key;
switch(key)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device and exit if creation failed
MyEventReceiver receiver;

View File

@ -14,6 +14,7 @@ nearly all other tutorials:
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -114,33 +115,16 @@ in this example, if he selected a driver which is capable of doing so.
*/
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// ask the user if we should use high level shaders for this example
if (driverType == video::EDT_DIRECT3D9 ||
driverType == video::EDT_OPENGL)
{
char i;
printf("Please press 'y' if you want to use high level shaders.\n");
std::cin >> i;
if (i == 'y')

View File

@ -8,29 +8,30 @@
<Build>
<Target title="Windows">
<Option platforms="Windows;" />
<Option output="../../bin/gcc/PerPixelLighting" prefix_auto="0" extension_auto="1" />
<Option output="..\..\bin\Win32-gcc\PerPixelLighting" prefix_auto="0" extension_auto="1" />
<Option type="1" />
<Option compiler="gcc" />
<Option projectResourceIncludeDirsRelation="1" />
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add option="-W" />
</Compiler>
<Linker>
<Add directory="..\..\lib\Win32-gcc" />
</Linker>
</Target>
<Target title="Linux">
<Option platforms="Unix;" />
<Option output="../../bin/Linux/PerPixelLighting" prefix_auto="0" extension_auto="0" />
<Option output="..\..\bin\Linux\PerPixelLighting" prefix_auto="0" extension_auto="0" />
<Option type="1" />
<Option compiler="gcc" />
<Option projectResourceIncludeDirsRelation="1" />
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add option="-D_IRR_STATIC_LIB_" />
<Add option="-W" />
</Compiler>
<Linker>
<Add library="Xxf86vm" />
<Add library="GL" />
<Add directory="../../lib/Linux" />
<Add directory="..\..\lib\Linux" />
</Linker>
</Target>
</Build>
@ -38,18 +39,18 @@
<Add alias="All" targets="Windows;" />
</VirtualTargets>
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add directory="../../include" />
<Add option="-W" />
<Add directory="..\..\include" />
</Compiler>
<Linker>
<Add library="Irrlicht" />
<Add directory="../../lib/gcc" />
</Linker>
<Unit filename="main.cpp" />
<Extensions>
<code_completion />
<debugger />
<envvars />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -9,7 +9,7 @@ At first, we need to include all headers and do the stuff we always do, like in
nearly all other tutorials.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -277,8 +277,8 @@ int main()
EMF_FOG_ENABLE to true to enable fog in the room.
*/
scene::IMesh* tangentMesh = smgr->getMeshManipulator()->createMeshWithTangents(
roomMesh->getMesh(0));
scene::IMesh* tangentMesh = smgr->getMeshManipulator()->
createMeshWithTangents(roomMesh->getMesh(0));
room = smgr->addMeshSceneNode(tangentMesh);
room->setMaterialTexture(0,

View File

@ -15,7 +15,7 @@ switches to wireframe mode, the 'P' key to pointcloud mode, and the 'D' key
toggles between solid and detail mapped material.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -79,33 +79,16 @@ private:
/*
The start of the main function starts like in most other example. We ask the user
for the desired renderer and start it up. This time with the advanced parameter handling.
The start of the main function starts like in most other example. We ask the
user for the desired renderer and start it up. This time with the advanced
parameter handling.
*/
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device with full flexibility over creation parameters
// you can add more parameters if desired, check irr::SIrrlichtCreationParameters

View File

@ -9,7 +9,7 @@ for the rendering driver, create the Irrlicht Device:
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -19,28 +19,10 @@ using namespace irr;
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device and exit if creation failed

View File

@ -71,7 +71,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib opengl32.lib"
OutputFile="..\..\bin\Win32-VisualStudio\14.Win32Window.exe"
LinkIncremental="0"
SuppressStartupBanner="true"

View File

@ -15,6 +15,7 @@ windows book for details.
#else
#include <windows.h> // this example only runs with windows
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -55,30 +56,11 @@ static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
Now ask for the driver and create the Windows specific window.
*/
int main()
//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hpre, LPSTR cmd, int cc)
{
// ask user for driver
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D8;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char key;
std::cin >> key;
switch(key)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
printf("Select the render window (some dead window may exist too):\n"\
" (a) Window with button (via CreationParam)\n"\
@ -86,6 +68,7 @@ int main()
" (c) Own Irrlicht window (default behavior)\n"\
" (otherKey) exit\n\n");
char key;
std::cin >> key;
if (key != 'a' && key != 'b' && key != 'c')
return 1;

View File

@ -11,7 +11,8 @@ Lets start: Create an Irrlicht device and setup the window.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
#ifdef _MSC_VER
@ -21,27 +22,9 @@ using namespace irr;
int main(int argc, char** argv)
{
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device and exit if creation failed

View File

@ -9,7 +9,7 @@ the irrlicht header files and an additional file to be able
to ask the user for a driver type using the console.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
/*
define which Quake3 Level should be loaded
@ -36,20 +36,6 @@ to ask the user for a driver type using the console.
#define QUAKE3_MAP_NAME "maps/20kdm2.bsp"
#endif
/*
As already written in the HelloWorld example, in the Irrlicht
Engine, everything can be found in the namespace 'irr'.
To get rid of the irr:: in front of the name of every class,
we tell the compiler that we use that namespace from now on,
and we will not have to write that 'irr::'.
There are 5 other sub namespaces 'core', 'scene', 'video',
'io' and 'gui'. Unlike in the HelloWorld example,
we do not a 'using namespace' for these 5 other namespaces
because in this way you will see what can be found in which
namespace. But if you like, you can also include the namespaces
like in the previous example. Code just like you want to.
*/
using namespace irr;
using namespace scene;
@ -63,7 +49,9 @@ to make it easy, we use a pragma comment lib:
#endif
//! produces a serie of screenshots
/*
A class to produce a series of screenshots
*/
class CScreenShotFactory : public IEventReceiver
{
public:
@ -129,27 +117,9 @@ int IRRCALLCONV main(int argc, char* argv[])
*/
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device and exit if creation failed
const core::dimension2du videoDim(800,600);
@ -222,7 +192,7 @@ int IRRCALLCONV main(int argc, char* argv[])
if (mesh)
{
scene::IMesh * const geometry = mesh->getMesh(quake3::E_Q3_MESH_GEOMETRY);
node = smgr->addOctreeSceneNode(geometry, 0, -1, 1024);
node = smgr->addOctreeSceneNode(geometry, 0, -1, 4096);
}
// create an event receiver for making screenshots

View File

@ -11,7 +11,7 @@ nothing to say about it)
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
@ -75,26 +75,10 @@ Just take care of the maps position.
*/
int main(int argc, char** argv)
{
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
//Instance of the EventReceiver
MyEventReceiver receiver;

View File

@ -14,7 +14,7 @@ devices.
#endif
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -102,28 +102,10 @@ different possibilities to move and animate scene nodes.
*/
int main()
{
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 0;
}
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device
MyEventReceiver receiver;

View File

@ -7,14 +7,10 @@ node callbacks, are left out for simplicity of the example.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#if defined(_MSC_VER)
#pragma comment(lib, "Irrlicht.lib")
@ -51,7 +47,7 @@ using namespace gui;
This light manager is also an event receiver; this is purely for simplicity in this example,
it's neither necessary nor recommended for a real application.
*/
class CMyLightManager : public ILightManager, public IEventReceiver
class CMyLightManager : public scene::ILightManager, public IEventReceiver
{
typedef enum
{
@ -66,16 +62,16 @@ class CMyLightManager : public ILightManager, public IEventReceiver
// These data represent the state information that this light manager
// is interested in.
ISceneManager * SceneManager;
core::array<ILightSceneNode*> * SceneLightList;
E_SCENE_NODE_RENDER_PASS CurrentRenderPass;
ISceneNode * CurrentSceneNode;
scene::ISceneManager * SceneManager;
core::array<scene::ILightSceneNode*> * SceneLightList;
scene::E_SCENE_NODE_RENDER_PASS CurrentRenderPass;
scene::ISceneNode * CurrentSceneNode;
public:
CMyLightManager(ISceneManager* sceneManager)
CMyLightManager(scene::ISceneManager* sceneManager)
: Mode(NO_MANAGEMENT), RequestedMode(NO_MANAGEMENT),
SceneManager(sceneManager), SceneLightList(0),
CurrentRenderPass(ESNRP_NONE), CurrentSceneNode(0)
CurrentRenderPass(scene::ESNRP_NONE), CurrentSceneNode(0)
{ }
virtual ~CMyLightManager(void) { }
@ -115,7 +111,7 @@ public:
// This is called before the first scene node is rendered.
virtual void OnPreRender(core::array<ILightSceneNode*> & lightList)
virtual void OnPreRender(core::array<scene::ILightSceneNode*> & lightList)
{
// Update the mode; changing it here ensures that it's consistent throughout a render
Mode = RequestedMode;
@ -135,16 +131,16 @@ public:
(*SceneLightList)[i]->setVisible(true);
}
virtual void OnRenderPassPreRender(E_SCENE_NODE_RENDER_PASS renderPass)
virtual void OnRenderPassPreRender(scene::E_SCENE_NODE_RENDER_PASS renderPass)
{
// I don't have to do anything here except remember which render pass I am in.
CurrentRenderPass = renderPass;
}
virtual void OnRenderPassPostRender(E_SCENE_NODE_RENDER_PASS renderPass)
virtual void OnRenderPassPostRender(scene::E_SCENE_NODE_RENDER_PASS renderPass)
{
// I only want solid nodes to be lit, so after the solid pass, turn all lights off.
if(ESNRP_SOLID == renderPass)
if(scene::ESNRP_SOLID == renderPass)
{
for(u32 i = 0; i < SceneLightList->size(); ++i)
(*SceneLightList)[i]->setVisible(false);
@ -152,22 +148,22 @@ public:
}
// This is called before the specified scene node is rendered
virtual void OnNodePreRender(ISceneNode* node)
virtual void OnNodePreRender(scene::ISceneNode* node)
{
CurrentSceneNode = node;
// This light manager only considers solid objects, but you are free to manipulate
// lights during any phase, depending on your requirements.
if(ESNRP_SOLID != CurrentRenderPass)
if (scene::ESNRP_SOLID != CurrentRenderPass)
return;
// And in fact for this example, I only want to consider lighting for cube scene
// nodes. You will probably want to deal with lighting for (at least) mesh /
// animated mesh scene nodes as well.
if(node->getType() != ESNT_CUBE)
if (node->getType() != scene::ESNT_CUBE)
return;
if(LIGHTS_NEAREST_NODE == Mode)
if (LIGHTS_NEAREST_NODE == Mode)
{
// This is a naive implementation that prioritises every light in the scene
// by its proximity to the node being rendered. This produces some flickering
@ -182,7 +178,7 @@ public:
u32 i;
for(i = 0; i < SceneLightList->size(); ++i)
{
ILightSceneNode* lightNode = (*SceneLightList)[i];
scene::ILightSceneNode* lightNode = (*SceneLightList)[i];
f64 distance = lightNode->getAbsolutePosition().getDistanceFromSQ(nodePosition);
sortingArray.push_back(LightDistanceElement(lightNode, distance));
}
@ -202,23 +198,23 @@ public:
// on all lights that are found under that node in the scene graph.
// This is a general purpose algorithm that doesn't use any special
// knowledge of how this particular scene graph is organised.
for(u32 i = 0; i < SceneLightList->size(); ++i)
for (u32 i = 0; i < SceneLightList->size(); ++i)
{
ILightSceneNode* lightNode = (*SceneLightList)[i];
SLight & lightData = lightNode->getLightData();
scene::ILightSceneNode* lightNode = (*SceneLightList)[i];
video::SLight & lightData = lightNode->getLightData();
if(ELT_DIRECTIONAL != lightData.Type)
if (video::ELT_DIRECTIONAL != lightData.Type)
lightNode->setVisible(false);
}
ISceneNode * parentZone = findZone(node);
if(parentZone)
scene::ISceneNode * parentZone = findZone(node);
if (parentZone)
turnOnZoneLights(parentZone);
}
}
// Called after the specified scene node is rendered
virtual void OnNodePostRender(ISceneNode* node)
virtual void OnNodePostRender(scene::ISceneNode* node)
{
// I don't need to do any light management after individual node rendering.
}
@ -226,12 +222,12 @@ public:
private:
// Find the empty scene node that is the parent of the specified node
ISceneNode * findZone(ISceneNode * node)
scene::ISceneNode * findZone(scene::ISceneNode * node)
{
if(!node)
return 0;
if(node->getType() == ESNT_EMPTY)
if(node->getType() == scene::ESNT_EMPTY)
return node;
return findZone(node->getParent());
@ -239,15 +235,15 @@ private:
// Turn on all lights that are children (directly or indirectly) of the
// specified scene node.
void turnOnZoneLights(ISceneNode * node)
void turnOnZoneLights(scene::ISceneNode * node)
{
core::list<ISceneNode*> const & children = node->getChildren();
for (core::list<ISceneNode*>::ConstIterator child = children.begin();
core::list<scene::ISceneNode*> const & children = node->getChildren();
for (core::list<scene::ISceneNode*>::ConstIterator child = children.begin();
child != children.end();
++child)
{
if((*child)->getType() == ESNT_LIGHT)
static_cast<ILightSceneNode*>(*child)->setVisible(true);
if((*child)->getType() == scene::ESNT_LIGHT)
static_cast<scene::ILightSceneNode*>(*child)->setVisible(true);
else // Assume that lights don't have any children that are also lights
turnOnZoneLights(*child);
}
@ -260,10 +256,10 @@ private:
public:
LightDistanceElement() {};
LightDistanceElement(ILightSceneNode* n, f64 d)
LightDistanceElement(scene::ILightSceneNode* n, f64 d)
: node(n), distance(d) { }
ILightSceneNode* node;
scene::ILightSceneNode* node;
f64 distance;
// Lower distance elements are sorted to the start of the array
@ -279,48 +275,27 @@ private:
*/
int main(int argumentCount, char * argumentValues[])
{
char driverChoice;
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
if(argumentCount > 1)
driverChoice = argumentValues[1][0];
else
{
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
IrrlichtDevice *device = createDevice(driverType,
dimension2d<u32>(640, 480), 32);
std::cin >> driverChoice;
}
video::E_DRIVER_TYPE driverType;
switch(driverChoice)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 0;
}
IrrlichtDevice *device = createDevice(driverType, dimension2d<u32>(640, 480), 32,
false, false, false, 0);
if(!device)
return -1;
f32 const lightRadius = 60.f; // Enough to reach the far side of each 'zone'
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* guienv = device->getGUIEnvironment();
gui::IGUISkin* skin = guienv->getSkin();
if (skin)
{
skin->setColor(EGDC_BUTTON_TEXT, SColor(255, 255, 255, 255));
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
gui::IGUIFont* font = guienv->getFont("../../media/fontlucida.png");
if(font)
skin->setFont(font);
@ -337,38 +312,38 @@ Add several "zones". You could use this technique to light individual rooms, fo
for(f32 zoneY = -60.f; zoneY <= 60.f; zoneY += 60.f)
{
// Start with an empty scene node, which we will use to represent a zone.
ISceneNode * zoneRoot = smgr->addEmptySceneNode();
scene::ISceneNode * zoneRoot = smgr->addEmptySceneNode();
zoneRoot->setPosition(vector3df(zoneX, zoneY, 0));
// Each zone contains a rotating cube
IMeshSceneNode * node = smgr->addCubeSceneNode(15, zoneRoot);
ISceneNodeAnimator * rotation = smgr->createRotationAnimator(vector3df(0.25f, 0.5f, 0.75f));
scene::IMeshSceneNode * node = smgr->addCubeSceneNode(15, zoneRoot);
scene::ISceneNodeAnimator * rotation = smgr->createRotationAnimator(vector3df(0.25f, 0.5f, 0.75f));
node->addAnimator(rotation);
rotation->drop();
// And each cube has three lights attached to it. The lights are attached to billboards so
// that we can see where they are. The billboards are attached to the cube, so that the
// lights are indirect descendents of the same empty scene node as the cube.
IBillboardSceneNode * billboard = smgr->addBillboardSceneNode(node);
scene::IBillboardSceneNode * billboard = smgr->addBillboardSceneNode(node);
billboard->setPosition(vector3df(0, -14, 30));
billboard->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
billboard->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
billboard->setMaterialFlag(video::EMF_LIGHTING, false);
ILightSceneNode * light = smgr->addLightSceneNode(billboard, vector3df(0, 0, 0), SColorf(1, 0, 0), lightRadius);
scene::ILightSceneNode * light = smgr->addLightSceneNode(billboard, vector3df(0, 0, 0), video::SColorf(1, 0, 0), lightRadius);
billboard = smgr->addBillboardSceneNode(node);
billboard->setPosition(vector3df(-21, -14, -21));
billboard->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
billboard->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
billboard->setMaterialFlag(video::EMF_LIGHTING, false);
light = smgr->addLightSceneNode(billboard, vector3df(0, 0, 0), SColorf(0, 1, 0), lightRadius);
light = smgr->addLightSceneNode(billboard, vector3df(0, 0, 0), video::SColorf(0, 1, 0), lightRadius);
billboard = smgr->addBillboardSceneNode(node);
billboard->setPosition(vector3df(21, -14, -21));
billboard->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
billboard->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
billboard->setMaterialFlag(video::EMF_LIGHTING, false);
light = smgr->addLightSceneNode(billboard, vector3df(0, 0, 0), SColorf(0, 0, 1), lightRadius);
light = smgr->addLightSceneNode(billboard, vector3df(0, 0, 0), video::SColorf(0, 0, 1), lightRadius);
// Each cube also has a smaller cube rotating around it, to show that the cubes are being
// lit by the lights in their 'zone', not just lights that are their direct children.
@ -386,7 +361,7 @@ Add several "zones". You could use this technique to light individual rooms, fo
while(device->run())
{
driver->beginScene(true, true, SColor(255,100,101,140));
driver->beginScene(true, true, video::SColor(255,100,101,140));
smgr->drawAll();
guienv->drawAll();
driver->endScene();

View File

@ -21,7 +21,7 @@ Copyright 2006-2009 Burningwater, Thomas Alten
#include "q3factory.h"
#include "sound.h"
#include <iostream>
#include "driverChoice.h"
/*
Game Data is used to hold Data which is needed to drive the game
@ -1771,6 +1771,7 @@ void CQuake3EventHandler::useItem( Q3Player * player)
node->setMaterialFlag(EMF_LIGHTING, false);
node->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture("fireball.bmp"));
node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
f32 length = (f32)(end - start).getLength();
@ -1884,6 +1885,7 @@ void CQuake3EventHandler::createParticleImpacts( u32 now )
anim->drop();
pas->setMaterialFlag(video::EMF_LIGHTING, false);
pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
pas->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA );
pas->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture( smoke[g].texture ));
}
@ -1923,8 +1925,85 @@ void CQuake3EventHandler::Render()
if ( 0 == driver )
return;
driver->beginScene(true, true, SColor(0,0,0,0));
Game->Device->getSceneManager ()->drawAll();
// TODO: This does not work, yet.
const bool anaglyph=false;
if (anaglyph)
{
scene::ICameraSceneNode* cameraOld = Game->Device->getSceneManager()->getActiveCamera();
driver->beginScene(true, true, SColor(0,0,0,0));
driver->getOverrideMaterial().Material.ColorMask = ECP_NONE;
driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK;
driver->getOverrideMaterial().EnablePasses = ESNRP_SKY_BOX +
ESNRP_SOLID +
ESNRP_TRANSPARENT +
ESNRP_TRANSPARENT_EFFECT +
ESNRP_SHADOW;
Game->Device->getSceneManager()->drawAll();
driver->clearZBuffer();
const vector3df oldPosition = cameraOld->getPosition();
const vector3df oldTarget = cameraOld->getTarget();
const matrix4 startMatrix = cameraOld->getAbsoluteTransformation();
const vector3df focusPoint = (oldTarget -
cameraOld->getAbsolutePosition()).setLength(10000) +
cameraOld->getAbsolutePosition() ;
scene::ICameraSceneNode* camera = cameraOld;//Game->Device->getSceneManager()->addCameraSceneNode();
//Left eye...
vector3df pos;
matrix4 move;
move.setTranslation( vector3df(-1.5f,0.0f,0.0f) );
pos=(startMatrix*move).getTranslation();
driver->getOverrideMaterial().Material.ColorMask = ECP_RED;
driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK;
driver->getOverrideMaterial().EnablePasses =
ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT|
ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW;
camera->setPosition(pos);
camera->setTarget(focusPoint);
Game->Device->getSceneManager()->drawAll();
driver->clearZBuffer();
//Right eye...
move.setTranslation( vector3df(1.5f,0.0f,0.0f) );
pos=(startMatrix*move).getTranslation();
driver->getOverrideMaterial().Material.ColorMask = ECP_GREEN + ECP_BLUE;
driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK;
driver->getOverrideMaterial().EnablePasses =
ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT|
ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW;
camera->setPosition(pos);
camera->setTarget(focusPoint);
Game->Device->getSceneManager()->drawAll();
driver->getOverrideMaterial().Material.ColorMask=ECP_ALL;
driver->getOverrideMaterial().EnableFlags=0;
driver->getOverrideMaterial().EnablePasses=0;
if (camera != cameraOld)
{
Game->Device->getSceneManager()->setActiveCamera(cameraOld);
camera->remove();
}
else
{
camera->setPosition(oldPosition);
camera->setTarget(oldTarget);
}
}
else
{
driver->beginScene(true, true, SColor(0,0,0,0));
Game->Device->getSceneManager()->drawAll();
}
Game->Device->getGUIEnvironment()->drawAll();
driver->endScene();
}
@ -2083,23 +2162,10 @@ int IRRCALLCONV main(int argc, char* argv[])
if ( game.retVal == 0 )
{
game.setDefault ();
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Video (TM) Thomas Alten\n"\
" (otherKey) exit\n\n");
char i = 'a';
std::cin >> i;
switch(i)
{
case 'a': game.deviceParam.DriverType = EDT_DIRECT3D9;break;
case 'b': game.deviceParam.DriverType = EDT_DIRECT3D8;break;
case 'c': game.deviceParam.DriverType = EDT_OPENGL; break;
case 'd': game.deviceParam.DriverType = EDT_OGLES1; break;
case 'e': game.deviceParam.DriverType = EDT_BURNINGSVIDEO;break;
default: game.retVal = 3; break;
}
// ask user for driver
game.deviceParam.DriverType=driverChoiceConsole();
if (game.deviceParam.DriverType==video::EDT_COUNT)
game.retVal = 3;
}
runGame ( &game );
} while ( game.retVal < 3 );
@ -2109,4 +2175,3 @@ int IRRCALLCONV main(int argc, char* argv[])
/*
**/

View File

@ -5,11 +5,10 @@ Only the default non-shader materials are used in here.
You have two nodes to make it easier to see which difference your settings will make.
Additionally you have one lightscenenode and you can set the global ambient values.
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
@ -791,9 +790,9 @@ protected:
// returns true when it was succesful initialized, otherwise false.
bool init(int argc, char *argv[])
{
// ask user for the driver which should be used
Config.DriverType = getDriverTypeFromConsole();
if ( (int)Config.DriverType < 0 )
// ask user for driver
Config.DriverType=driverChoiceConsole();
if (Config.DriverType==video::EDT_COUNT)
return false;
// create the device with the settings from our config
@ -870,30 +869,6 @@ protected:
return true;
}
// Ask the user which driver to use
video::E_DRIVER_TYPE getDriverTypeFromConsole()
{
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': return video::EDT_DIRECT3D9;
case 'b': return video::EDT_DIRECT3D8;
case 'c': return video::EDT_OPENGL;
case 'd': return video::EDT_SOFTWARE;
case 'e': return video::EDT_BURNINGSVIDEO;
case 'f': return video::EDT_NULL;
default: return video::E_DRIVER_TYPE(-1);
}
}
// Update one frame
bool update()
{

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Irrlicht Example 23 SMeshHandling" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Windows">
<Option platforms="Windows;" />
<Option output="../../bin/Win32-gcc/SMeshHandling" prefix_auto="0" extension_auto="1" />
<Option type="1" />
<Option compiler="gcc" />
</Target>
<Target title="Linux">
<Option platforms="Unix;" />
<Option output="../../bin/Linux/SMeshHandling" prefix_auto="0" extension_auto="0" />
<Option type="1" />
<Option compiler="gcc" />
<Linker>
<Add library="Irrlicht" />
<Add directory="../../lib/Linux" />
</Linker>
</Target>
</Build>
<Compiler>
<Add directory="../../include" />
</Compiler>
<Linker>
<Add option="../../lib/Win32-gcc/libIrrlicht.a" />
</Linker>
<Unit filename="main.cpp" />
<Extensions>
<code_completion />
<envvars />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -11,7 +11,7 @@ Ok, let's start with the headers (I think there's nothing to say about it)
*/
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
@ -327,26 +327,9 @@ the user to navigate around it.
int main(int argc, char* argv[])
{
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(driverType,

View File

@ -714,6 +714,7 @@ void CDemo::createParticleImpacts()
paf->drop();
pas->setMaterialFlag(video::EMF_LIGHTING, false);
pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
pas->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/smoke.bmp"));
pas->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);

View File

@ -18,7 +18,8 @@ namespace scene
EAC_OFF = 0,
EAC_BOX = 1,
EAC_FRUSTUM_BOX = 2,
EAC_FRUSTUM_SPHERE = 4
EAC_FRUSTUM_SPHERE = 4,
EAC_OCC_QUERY = 8
};
//! Names for culling type
@ -28,6 +29,7 @@ namespace scene
"box", // camera box against node box
"frustum_box", // camera frustum against node box
"frustum_sphere", // camera frustum against node sphere
"occ_query", // occlusion query
0
};

View File

@ -106,6 +106,9 @@ namespace video
//! Supports geometry shaders
EVDF_GEOMETRY_SHADER,
//! Supports occlusion queries
EVDF_OCCLUSION_QUERY,
//! Only used for counting the elements of this enum
EVDF_COUNT
};

View File

@ -53,7 +53,10 @@ namespace video
EDT_OPENGL,
//! OpenGL-ES device, for embedded and mobile systems
EDT_OGLES1
EDT_OGLES1,
//! No driver, just for counting the elements
EDT_COUNT
};
} // end namespace video

View File

@ -75,7 +75,10 @@ namespace video
EMF_COLOR_MASK = 0x8000,
//! ColorMaterial enum for vertex color interpretation
EMF_COLOR_MATERIAL = 0x10000
EMF_COLOR_MATERIAL = 0x10000,
//! Flag for enabling/disabling mipmap usage
EMF_USE_MIP_MAPS = 0x20000
};
} // end namespace video

View File

@ -161,9 +161,11 @@ namespace irr
EGET_ELEMENT_FOCUSED,
//! The mouse cursor hovered over a gui element.
/** If an element has sub-elements you also get this message for the subelements */
EGET_ELEMENT_HOVERED,
//! The mouse cursor left the hovered element.
/** If an element has sub-elements you also get this message for the subelements */
EGET_ELEMENT_LEFT,
//! An element would like to close.
@ -180,10 +182,12 @@ namespace irr
//! A checkbox has changed its check state.
EGET_CHECKBOX_CHANGED,
//! A new item in a listbox was seleted.
//! A new item in a listbox was selected.
/** NOTE: You also get this event currently when the same item was clicked again after more than 500 ms. */
EGET_LISTBOX_CHANGED,
//! An item in the listbox was selected, which was already selected.
/** NOTE: You get the event currently only if the item was clicked again within 500 ms or selected by "enter" or "space". */
EGET_LISTBOX_SELECTED_AGAIN,
//! A file has been selected in the file dialog

View File

@ -35,7 +35,7 @@ public:
//! Opens a file for read access.
/** \param filename: Name of file to open.
\return Returns a pointer to the created file interface.
\return Pointer to the created file interface.
The returned pointer should be dropped when no longer needed.
See IReferenceCounted::drop() for more information. */
virtual IReadFile* createAndOpenFile(const path& filename) =0;
@ -47,7 +47,7 @@ public:
\param fileName: The name given to this file
\param deleteMemoryWhenDropped: True if the memory should be deleted
along with the IReadFile when it is dropped.
\return Returns a pointer to the created file interface.
\return Pointer to the created file interface.
The returned pointer should be dropped when no longer needed.
See IReferenceCounted::drop() for more information.
*/
@ -74,7 +74,7 @@ public:
\param fileName: The name given to this file
\param deleteMemoryWhenDropped: True if the memory should be deleted
along with the IWriteFile when it is dropped.
\return Returns a pointer to the created file interface.
\return Pointer to the created file interface.
The returned pointer should be dropped when no longer needed.
See IReferenceCounted::drop() for more information.
*/
@ -85,7 +85,7 @@ public:
/** \param filename: Name of file to open.
\param append: If the file already exist, all write operations are
appended to the file.
\return Returns a pointer to the created file interface. 0 is returned, if the
\return Pointer to the created file interface. 0 is returned, if the
file could not created or opened for writing.
The returned pointer should be dropped when no longer needed.
See IReferenceCounted::drop() for more information. */
@ -99,6 +99,8 @@ public:
default Irrlicht supports ZIP, PAK, TAR, PNK, and directories as
archives. You can provide your own archive types by implementing
IArchiveLoader and passing an instance to addArchiveLoader.
Irrlicht supports AES-encrypted zip files, and the advanced compression
techniques lzma and bzip2.
\param filename: Filename of the archive to add to the file system.
\param ignoreCase: If set to true, files in the archive can be accessed without
writing all letters in the right case.
@ -109,7 +111,7 @@ public:
you use a different extension then you can use this parameter to force
a specific type of archive.
\param password An optional password, which is used in case of encrypted archives.
\return Returns true if the archive was added successfully, false if not. */
\return True if the archive was added successfully, false if not. */
virtual bool addFileArchive(const path& filename, bool ignoreCase=true,
bool ignorePaths=true,
E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN,
@ -120,14 +122,14 @@ public:
engine, for example proprietary or encrypted file storage. */
virtual void addArchiveLoader(IArchiveLoader* loader) =0;
//! Returns the number of archives currently attached to the file system
//! Get the number of archives currently attached to the file system
virtual u32 getFileArchiveCount() const =0;
//! Removes an archive from the file system.
/** This will close the archive and free any file handles, but will not close resources which have already
been loaded and are now cached, for example textures and meshes.
\param index: The index of the archive to remove
\return Returns true on success, false on failure */
\return True on success, false on failure */
virtual bool removeFileArchive(u32 index) =0;
//! Removes an archive from the file system.
@ -135,7 +137,7 @@ public:
close resources which have already been loaded and are now cached, for
example textures and meshes.
\param filename The archive of the given name will be removed
\return Returns true on success, false on failure */
\return True on success, false on failure */
virtual bool removeFileArchive(const path& filename) =0;
//! Changes the search order of attached archives.
@ -144,7 +146,7 @@ public:
\param relative: The relative change in position, archives with a lower index are searched first */
virtual bool moveFileArchive(u32 sourceIndex, s32 relative) =0;
//! Returns the archive at a given index.
//! Get the archive at a given index.
virtual IFileArchive* getFileArchive(u32 index) =0;
//! Adds a zip archive to the file system.
@ -159,7 +161,7 @@ public:
writing all letters in the right case.
\param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path.
\return Returns true if the archive was added successfully, false if not. */
\return True if the archive was added successfully, false if not. */
virtual bool addZipFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true)
{
return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_ZIP);
@ -175,7 +177,7 @@ public:
writing all letters in the right case.
\param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path.
\return Returns true if the archive was added successful, false if not. */
\return True if the archive was added successful, false if not. */
virtual bool addFolderFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true)
{
return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_FOLDER);
@ -193,7 +195,7 @@ public:
writing all letters in the right case.
\param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path.(should not use with Quake2 paks
\return Returns true if the archive was added successful, false if not. */
\return True if the archive was added successful, false if not. */
virtual bool addPakFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true)
{
return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_PAK);
@ -215,12 +217,12 @@ public:
\result Absolute filename which points to the same file. */
virtual path getAbsolutePath(const path& filename) const =0;
//! Returns the directory a file is located in.
//! Get the directory a file is located in.
/** \param filename: The file to get the directory from.
\return String containing the directory of the file. */
virtual path getFileDir(const path& filename) const =0;
//! Returns the base part of a filename, i.e. the name without the directory part.
//! Get the base part of a filename, i.e. the name without the directory part.
/** If no directory is prefixed, the full name is returned.
\param filename: The file to get the basename from
\param keepExtension True if filename with extension is returned otherwise everything
@ -247,7 +249,7 @@ public:
//! Determines if a file exists and could be opened.
/** \param filename is the string identifying the file which should be tested for existence.
\return Returns true if file exists, and false if it does not exist or an error occured. */
\return True if file exists, and false if it does not exist or an error occured. */
virtual bool existFile(const path& filename) const =0;
//! Creates a XML Reader from a file which returns all parsed strings as wide characters (wchar_t*).

View File

@ -75,12 +75,12 @@ public:
error log and can be catched with a custom event receiver. */
virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
@ -155,12 +155,12 @@ public:
error log and can be catched with a custom event receiver. */
virtual s32 addHighLevelShaderMaterialFromFiles(
const io::path& vertexShaderProgramFileName,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const io::path& pixelShaderProgramFileName = "",
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const io::path& geometryShaderProgramFileName="",
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const io::path& pixelShaderProgramFileName,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const io::path& geometryShaderProgramFileName,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
@ -233,12 +233,12 @@ public:
the error log and can be catched with a custom event receiver. */
virtual s32 addHighLevelShaderMaterialFromFiles(
io::IReadFile* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
io::IReadFile* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
io::IReadFile* geometryShaderProgram = 0,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
io::IReadFile* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
io::IReadFile* geometryShaderProgram,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,

View File

@ -187,6 +187,7 @@ public:
}
//! The alignment defines how the borders of this element will be positioned when the parent element is resized.
void setAlignment(EGUI_ALIGNMENT left, EGUI_ALIGNMENT right, EGUI_ALIGNMENT top, EGUI_ALIGNMENT bottom)
{
AlignLeft = left;

View File

@ -78,7 +78,7 @@ namespace gui
//! sets the selected item. Set this to 0 if no item should be selected
virtual void setSelected(const wchar_t *item) = 0;
//! set whether the listbox should scroll to new or newly selected items
//! set whether the listbox should scroll to newly selected items
virtual void setAutoScrollEnabled(bool scroll) = 0;
//! returns true if automatic scrolling is enabled, false if not.

View File

@ -26,9 +26,9 @@ namespace gui
//! gets the maximum value of the scrollbar.
virtual s32 getMax() const = 0;
//! sets the maximum value of the scrollbar.
virtual void setMin(s32 max) = 0;
//! gets the maximum value of the scrollbar.
//! sets the minimum value of the scrollbar.
virtual void setMin(s32 min) = 0;
//! gets the minimum value of the scrollbar.
virtual s32 getMin() const = 0;
//! gets the small step value

View File

@ -163,7 +163,9 @@ namespace gui
//! minimal space to reserve for messagebox text-width
EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH,
//! maximal space to reserve for messagebox text-width
EGDS_MESSAGE_BOX_MAX_TEST_WIDTH,
EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH,
//! deprecated - this was a typo. Should be removed for 1.8
EGDS_MESSAGE_BOX_MAX_TEST_WIDTH = EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH,
//! minimal space to reserve for messagebox text-height
EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT,
//! maximal space to reserve for messagebox text-height

View File

@ -64,6 +64,16 @@ namespace scene
\param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false, bool angleWeighted = false) const = 0;
//! Recalculates tangents, requires a tangent mesh
/** \param mesh Mesh on which the operation is performed.
\param recalculateNormals If the normals shall be recalculated, otherwise original normals of the mesh are used unchanged.
\param smooth If the normals shall be smoothed.
\param angleWeighted If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision.
*/
virtual void recalculateTangents(IMesh* mesh,
bool recalculateNormals=false, bool smooth=false,
bool angleWeighted=false) const=0;
//! Scales the actual mesh, not a scene node.
/** \param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */
@ -171,11 +181,12 @@ namespace scene
\param smooth The normals/tangents are smoothed across the
meshbuffer's faces if this flag is set.
\param angleWeighted Improved smoothing calculation used
\param recalculateTangents Whether are actually calculated, or just the mesh with proper type is created.
\return Mesh consisting only of S3DVertexTangents vertices. If
you no longer need the cloned mesh, you should call
IMesh::drop(). See IReferenceCounted::drop() for more
information. */
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const = 0;
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false, bool recalculateTangents=true) const = 0;
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices.
/** \param mesh Input mesh

View File

@ -521,7 +521,7 @@ namespace scene
their geometry because it is their only reason for existence,
for example the OctreeSceneNode.
\param state The culling state to be used. */
void setAutomaticCulling( E_CULLING_TYPE state)
void setAutomaticCulling( u32 state)
{
AutomaticCullingState = state;
}
@ -529,9 +529,8 @@ namespace scene
//! Gets the automatic culling state.
/** \return The automatic culling state. */
E_CULLING_TYPE getAutomaticCulling() const
u32 getAutomaticCulling() const
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return AutomaticCullingState;
}
@ -687,7 +686,7 @@ namespace scene
out->addVector3d("Scale", getScale() );
out->addBool ("Visible", IsVisible );
out->addEnum ("AutomaticCulling", AutomaticCullingState, AutomaticCullingNames);
out->addInt ("AutomaticCulling", AutomaticCullingState);
out->addInt ("DebugDataVisible", DebugDataVisible );
out->addBool ("IsDebugObject", IsDebugObject );
}
@ -712,8 +711,12 @@ namespace scene
setScale(in->getAttributeAsVector3d("Scale"));
IsVisible = in->getAttributeAsBool("Visible");
AutomaticCullingState = (scene::E_CULLING_TYPE) in->getAttributeAsEnumeration("AutomaticCulling",
s32 tmpState = in->getAttributeAsEnumeration("AutomaticCulling",
scene::AutomaticCullingNames);
if (tmpState != -1)
AutomaticCullingState = (u32)tmpState;
else
AutomaticCullingState = in->getAttributeAsInt("AutomaticCulling");
DebugDataVisible = in->getAttributeAsInt("DebugDataVisible");
IsDebugObject = in->getAttributeAsBool("IsDebugObject");
@ -825,7 +828,7 @@ namespace scene
s32 ID;
//! Automatic culling state
E_CULLING_TYPE AutomaticCullingState;
u32 AutomaticCullingState;
//! Flag if debug data should be drawn, such as Bounding Boxes.
s32 DebugDataVisible;

View File

@ -22,7 +22,7 @@ namespace video
enum E_TEXTURE_CREATION_FLAG
{
/** Forces the driver to create 16 bit textures always, independent of
which format the file on disk has. When choosing this you may loose
which format the file on disk has. When choosing this you may lose
some color detail, but gain much speed and memory. 16 bit textures can
be transferred twice as fast as 32 bit textures and only use half of
the space in memory.
@ -94,7 +94,11 @@ public:
pixels. After lock() has been called and all operations on the pixels
are done, you must call unlock().
Locks are not accumulating, hence one unlock will do for an arbitrary
number of previous locks.
number of previous locks. You should avoid locking different levels without
unlocking inbetween, though, because only the last level locked will be
unlocked.
The size of the i-th mipmap level is defined as max(getSize().Width>>i,1)
and max(getSize().Height>>i,1)
\param readOnly Specifies that no changes to the locked texture are
made. Unspecified behavior will arise if still write access happens.
\param mipmapLevel Number of the mipmapLevel to lock. 0 is main texture.
@ -105,7 +109,8 @@ public:
virtual void* lock(bool readOnly = false, u32 mipmapLevel=0) = 0;
//! Unlock function. Must be called after a lock() to the texture.
/** One should avoid to call unlock more than once before another lock. */
/** One should avoid to call unlock more than once before another lock.
The last locked mip level will be unlocked. */
virtual void unlock() = 0;
//! Get original size of the texture.
@ -133,7 +138,7 @@ public:
/** \return The color format of texture. */
virtual ECOLOR_FORMAT getColorFormat() const = 0;
//! Get pitch of texture (in bytes).
//! Get pitch of the main texture (in bytes).
/** The pitch is the amount of bytes used for a row of pixels in a
texture.
\return Pitch of texture in bytes. */
@ -149,11 +154,19 @@ public:
}
//! Regenerates the mip map levels of the texture.
/** Required after modifying the texture, usually after calling unlock(). */
/** Required after modifying the texture, usually after calling unlock().
\param mipmapData Optional parameter to pass in image data which will be
used instead of the previously stored or automatically generated mipmap
data. The data has to be a continuous pixel data for all mipmaps until
1x1 pixel. Each mipmap has to be half the width and height of the previous
level. At least one pixel will be always kept.*/
virtual void regenerateMipMapLevels(void* mipmapData=0) = 0;
//! Check whether the texture is a render target
/** \return True if this is a render target, otherwise false. */
/** Render targets can be set as such in the video driver, in order to
render a scene into the texture. Once unbound as render target, they can
be used just as usual textures again.
\return True if this is a render target, otherwise false. */
virtual bool isRenderTarget() const { return false; }
//! Get name of texture (in most cases this is the filename)

View File

@ -31,7 +31,9 @@ namespace io
namespace scene
{
class IMeshBuffer;
class IMesh;
class IMeshManipulator;
class ISceneNode;
} // end namespace scene
namespace video
@ -184,6 +186,7 @@ namespace video
case EMF_NORMALIZE_NORMALS: material.NormalizeNormals = Material.NormalizeNormals; break;
case EMF_ANTI_ALIASING: material.AntiAliasing = Material.AntiAliasing; break;
case EMF_COLOR_MASK: material.ColorMask = Material.ColorMask; break;
case EMF_USE_MIP_MAPS: material.UseMipMaps = Material.UseMipMaps; break;
case EMF_BILINEAR_FILTER: material.TextureLayer[0].BilinearFilter = Material.TextureLayer[0].BilinearFilter; break;
case EMF_TRILINEAR_FILTER: material.TextureLayer[0].TrilinearFilter = Material.TextureLayer[0].TrilinearFilter; break;
case EMF_ANISOTROPIC_FILTER: material.TextureLayer[0].AnisotropicFilter = Material.TextureLayer[0].AnisotropicFilter; break;
@ -429,6 +432,43 @@ namespace video
//! Remove all hardware buffers
virtual void removeAllHardwareBuffers() =0;
//! Create occlusion query.
/** Use node for identification and mesh for occlusion test. */
virtual void createOcclusionQuery(scene::ISceneNode* node,
const scene::IMesh* mesh=0) =0;
//! Remove occlusion query.
virtual void removeOcclusionQuery(scene::ISceneNode* node) =0;
//! Remove all occlusion queries.
virtual void removeAllOcclusionQueries() =0;
//! Run occlusion query. Draws mesh stored in query.
/** If the mesh shall not be rendered visible, use
overrideMaterial to disable the color and depth buffer. */
virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false) =0;
//! Run all occlusion queries. Draws all meshes stored in queries.
/** If the meshes shall not be rendered visible, use
overrideMaterial to disable the color and depth buffer. */
virtual void runAllOcclusionQueries(bool visible=false) =0;
//! Update occlusion query. Retrieves results from GPU.
/** If the query shall not block, set the flag to false.
Update might not occur in this case, though */
virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true) =0;
//! Update all occlusion queries. Retrieves results from GPU.
/** If the query shall not block, set the flag to false.
Update might not occur in this case, though */
virtual void updateAllOcclusionQueries(bool block=true) =0;
//! Return query result.
/** Return value is the number of visible pixels/fragments.
The value is a safe approximation, i.e. can be larger than the
actual value of pixels. */
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const =0;
//! Sets a boolean alpha channel on the texture based on a color key.
/** This makes the texture fully transparent at the texels where
this color key can be found when using for example draw2DImage
@ -1066,9 +1106,9 @@ namespace video
virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled=true) =0;
//! Returns if a texture creation flag is enabled or disabled.
/** You can change this value using setTextureCreationMode().
/** You can change this value using setTextureCreationFlag().
\param flag Texture creation flag.
\return The current texture creation mode. */
\return The current texture creation flag enabled mode. */
virtual bool getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const =0;
//! Creates a software image from a file.
@ -1106,8 +1146,8 @@ namespace video
/** Requires that there is a suitable image writer registered
for writing the image.
\param image Image to write.
\param file An already open io::IWriteFile object. The name will be used to determine
the appropriate image writer to use.
\param file An already open io::IWriteFile object. The name
will be used to determine the appropriate image writer to use.
\param param Control parameter for the backend (e.g. compression
level).
\return True on successful write. */
@ -1344,7 +1384,7 @@ namespace video
enabled or disabled. */
virtual void enableMaterial2D(bool enable=true) =0;
//! Returns the graphics card vendor name.
//! Get the graphics card vendor name.
virtual core::stringc getVendorInfo() =0;
//! Only used by the engine internally.
@ -1359,8 +1399,21 @@ namespace video
\param flag Default behavior is to disable ZWrite, i.e. false. */
virtual void setAllowZWriteOnTransparent(bool flag) =0;
//! Returns the maximum texture size supported.
//! Get the maximum texture size supported.
virtual core::dimension2du getMaxTextureSize() const =0;
//! Color conversion convenience function
/** Convert an image (as array of pixels) from source to destination
array, thereby converting the color format. The pixel size is
determined by the color formats.
\param sP Pointer to source
\param sF Color format of source
\param sN Number of pixels to convert, both array must be large enough
\param dP Pointer to destination
\param dF Color format of destination
*/
virtual void convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN,
void* dP, ECOLOR_FORMAT dF) const =0;
};
} // end namespace video

View File

@ -8,11 +8,11 @@
//! Irrlicht SDK Version
#define IRRLICHT_VERSION_MAJOR 1
#define IRRLICHT_VERSION_MINOR 7
#define IRRLICHT_VERSION_REVISION 0
#define IRRLICHT_VERSION_REVISION 1
// This flag will be defined only in SVN, the official release code will have
// it undefined
#define IRRLICHT_VERSION_SVN -beta
#define IRRLICHT_SDK_VERSION "1.7.0-beta"
#define IRRLICHT_SDK_VERSION "1.7.1-beta"
#include <stdio.h> // TODO: Although included elsewhere this is required at least for mingw
@ -111,9 +111,9 @@
//! Define _IRR_COMPILE_WITH_DIRECT3D_8_ and _IRR_COMPILE_WITH_DIRECT3D_9_ to
//! compile the Irrlicht engine with Direct3D8 and/or DIRECT3D9.
/** If you only want to use the software device or opengl this can be useful.
/** If you only want to use the software device or opengl you can disable those defines.
This switch is mostly disabled because people do not get the g++ compiler compile
directX header files, and directX is only available on windows platforms. If you
directX header files, and directX is only available on Windows platforms. If you
are using Dev-Cpp, and want to compile this using a DX dev pack, you can define
_IRR_COMPILE_WITH_DX9_DEV_PACK_. So you simply need to add something like this
to the compiler settings: -DIRR_COMPILE_WITH_DX9_DEV_PACK
@ -384,7 +384,7 @@ defined. */
//! Define _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ if you want to read AES-encrypted ZIP archives
#define _IRR_COMPILE_WITH_ZIP_ENCRYPTION_
//! Define _IRR_COMPILE_WITH_BZIP2_ if you want to support bzip2 compressed zip archives
/** bzip2 is superior to the original zip file compression modes, but requires
/** bzip2 is superior to the original zip file compression modes, but requires
a certain amount of memory for decompression and adds several files to the
library. */
#define _IRR_COMPILE_WITH_BZIP2_

View File

@ -89,6 +89,15 @@ struct S3DVertex
{
return EVT_STANDARD;
}
S3DVertex getInterpolated(const S3DVertex& other, f32 d)
{
d = core::clamp(d, 0.0f, 1.0f);
return S3DVertex(Pos.getInterpolated(other.Pos, d),
Normal.getInterpolated(other.Normal, d),
Color.getInterpolated(other.Color, d),
TCoords.getInterpolated(other.TCoords, d));
}
};
@ -158,6 +167,16 @@ struct S3DVertex2TCoords : public S3DVertex
{
return EVT_2TCOORDS;
}
S3DVertex2TCoords getInterpolated(const S3DVertex2TCoords& other, f32 d)
{
d = core::clamp(d, 0.0f, 1.0f);
return S3DVertex2TCoords(Pos.getInterpolated(other.Pos, d),
Normal.getInterpolated(other.Normal, d),
Color.getInterpolated(other.Color, d),
TCoords.getInterpolated(other.TCoords, d),
TCoords2.getInterpolated(other.TCoords2, d));
}
};
@ -219,6 +238,17 @@ struct S3DVertexTangents : public S3DVertex
{
return EVT_TANGENTS;
}
S3DVertexTangents getInterpolated(const S3DVertexTangents& other, f32 d)
{
d = core::clamp(d, 0.0f, 1.0f);
return S3DVertexTangents(Pos.getInterpolated(other.Pos, d),
Normal.getInterpolated(other.Normal, d),
Color.getInterpolated(other.Color, d),
TCoords.getInterpolated(other.TCoords, d),
Tangent.getInterpolated(other.Tangent, d),
Binormal.getInterpolated(other.Binormal, d));
}
};

View File

@ -106,7 +106,7 @@ namespace video
//! Returns the alpha component from A1R5G5B5 color
/** In Irrlicht, alpha refers to opacity.
/** In Irrlicht, alpha refers to opacity.
\return The alpha value of the color. 0 is transparent, 1 is opaque. */
inline u32 getAlpha(u16 color)
{
@ -172,7 +172,7 @@ namespace video
: color(clr) {}
//! Returns the alpha component of the color.
/** The alpha component defines how opaque a color is.
/** The alpha component defines how opaque a color is.
\return The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */
u32 getAlpha() const { return color>>24; }
@ -297,10 +297,10 @@ namespace video
{
d = core::clamp(d, 0.f, 1.f);
const f32 inv = 1.0f - d;
return SColor((u32)(other.getAlpha()*inv + getAlpha()*d),
(u32)(other.getRed()*inv + getRed()*d),
(u32)(other.getGreen()*inv + getGreen()*d),
(u32)(other.getBlue()*inv + getBlue()*d));
return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d),
(u32)core::round32(other.getRed()*inv + getRed()*d),
(u32)core::round32(other.getGreen()*inv + getGreen()*d),
(u32)core::round32(other.getBlue()*inv + getBlue()*d));
}
//! Returns interpolated color. ( quadratic )
@ -374,7 +374,7 @@ namespace video
//! Converts this color to a SColor without floats.
SColor toSColor() const
{
return SColor((u32)(a*255.0f), (u32)(r*255.0f), (u32)(g*255.0f), (u32)(b*255.0f));
return SColor((u32)core::round32(a*255.0f), (u32)core::round32(r*255.0f), (u32)core::round32(g*255.0f), (u32)core::round32(b*255.0f));
}
//! Sets three color components to new values at once.
@ -492,7 +492,8 @@ namespace video
inline void SColorHSL::fromRGB(const SColor &color)
{
const f32 maxVal = (f32)core::max_(color.getRed(), color.getGreen(), color.getBlue());
const u32 maxValInt = core::max_(color.getRed(), color.getGreen(), color.getBlue());
const f32 maxVal = (f32)maxValInt;
const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue());
Luminance = (maxVal/minVal)*0.5f;
if (core::equals(maxVal, minVal))
@ -512,11 +513,11 @@ namespace video
Saturation = (delta)/(2-maxVal-minVal);
}
if (maxVal==color.getRed())
if (maxValInt == color.getRed())
Hue = (color.getGreen()-color.getBlue())/delta;
else if (maxVal==color.getGreen())
else if (maxValInt == color.getGreen())
Hue = 2+(color.getBlue()-color.getRed())/delta;
else if (maxVal==color.getBlue())
else // blue is max
Hue = 4+(color.getRed()-color.getGreen())/delta;
Hue *= (60.0f * core::DEGTORAD);
@ -571,7 +572,7 @@ namespace video
rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) /
(60.0f * core::DEGTORAD);
return (u32) (rm1 * 255.f);
return (u32) core::round32(rm1 * 255.f);
}
} // end namespace video

View File

@ -197,7 +197,7 @@ namespace video
ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL),
ColorMaterial(ECM_DIFFUSE),
Wireframe(false), PointCloud(false), GouraudShading(true), Lighting(true), ZWriteEnable(true),
BackfaceCulling(true), FrontfaceCulling(false), FogEnable(false), NormalizeNormals(false)
BackfaceCulling(true), FrontfaceCulling(false), FogEnable(false), NormalizeNormals(false), UseMipMaps(true)
{ }
//! Copy constructor
@ -246,6 +246,7 @@ namespace video
AntiAliasing = other.AntiAliasing;
ColorMask = other.ColorMask;
ColorMaterial = other.ColorMaterial;
UseMipMaps = other.UseMipMaps;
return *this;
}
@ -377,6 +378,10 @@ namespace video
/** Always use this if the mesh lit and scaled. Default: false */
bool NormalizeNormals:1;
//! Shall mipmaps be used if available
/** Sometimes, disabling mipmap usage can be useful. Default: true */
bool UseMipMaps:1;
//! Gets the texture transformation matrix for level i
/** \param i The desired level. Must not be larger than MATERIAL_MAX_TEXTURES.
\return Texture matrix for texture level i. */
@ -492,6 +497,8 @@ namespace video
case EMF_COLOR_MATERIAL:
ColorMaterial = value?ECM_DIFFUSE:ECM_NONE;
break;
case EMF_USE_MIP_MAPS:
UseMipMaps = value;
default:
break;
}
@ -545,6 +552,8 @@ namespace video
return (ColorMask!=ECP_NONE);
case EMF_COLOR_MATERIAL:
return (ColorMaterial != ECM_NONE);
case EMF_USE_MIP_MAPS:
return UseMipMaps;
}
return false;
@ -577,7 +586,8 @@ namespace video
NormalizeNormals != b.NormalizeNormals ||
AntiAliasing != b.AntiAliasing ||
ColorMask != b.ColorMask ||
ColorMaterial != b.ColorMaterial;
ColorMaterial != b.ColorMaterial ||
UseMipMaps != b.UseMipMaps;
for (u32 i=0; (i<MATERIAL_MAX_TEXTURES) && !different; ++i)
{
different |= (TextureLayer[i] != b.TextureLayer[i]);

View File

@ -67,7 +67,7 @@ namespace scene
video::SColor high) : Threshold(threshold), Low(low), High(high) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color = (vertex.Color.getAverage()>Threshold)?High:Low;
vertex.Color = ((u8)vertex.Color.getAverage()>Threshold)?High:Low;
}
private:
u8 Threshold;

View File

@ -222,16 +222,18 @@ class aabbox3d
otherwise false. */
bool isFullInside(const aabbox3d<T>& other) const
{
return MinEdge >= other.MinEdge && MaxEdge <= other.MaxEdge;
return (MinEdge.X >= other.MinEdge.X && MinEdge.Y >= other.MinEdge.Y && MinEdge.Z >= other.MinEdge.Z &&
MaxEdge.X <= other.MaxEdge.X && MaxEdge.Y <= other.MaxEdge.Y && MaxEdge.Z <= other.MaxEdge.Z);
}
//! Determines if the box intersects with another box.
//! Determines if the axis-aligned box intersects with another axis-aligned box.
/** \param other: Other box to check a intersection with.
\return True if there is an intersection with the other box,
otherwise false. */
bool intersectsWithBox(const aabbox3d<T>& other) const
{
return (MinEdge <= other.MaxEdge && MaxEdge >= other.MinEdge);
return (MinEdge.X <= other.MaxEdge.X && MinEdge.Y <= other.MaxEdge.Y && MinEdge.Z <= other.MaxEdge.Z &&
MaxEdge.X >= other.MinEdge.X && MaxEdge.Y >= other.MinEdge.Y && MaxEdge.Z >= other.MinEdge.Z);
}
//! Tests if the box intersects with a line

42
include/driverChoice.h Normal file
View File

@ -0,0 +1,42 @@
// Copyright (C) 2009-2010 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __E_DRIVER_CHOICE_H_INCLUDED__
#define __E_DRIVER_CHOICE_H_INCLUDED__
#include <iostream>
#include "EDriverTypes.h"
namespace irr
{
//! ask user for driver
static irr::video::E_DRIVER_TYPE driverChoiceConsole(bool allDrivers=true)
{
const char* const names[] = {"NullDriver","Software Renderer","Burning's Video","Direct3D 8.1","Direct3D 9.0c","OpenGL 1.x/2.x/3.x"};
printf("Please select the driver you want:\n");
irr::u32 i=0;
for (i=irr::video::EDT_COUNT; i>0; --i)
{
if (allDrivers || (irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1))))
printf(" (%c) %s\n", 'a'+irr::video::EDT_COUNT-i, names[i-1]);
}
char c;
std::cin >> c;
c = irr::video::EDT_COUNT+'a'-c;
for (i=irr::video::EDT_COUNT; i>0; --i)
{
if (!(allDrivers || (irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1)))))
--c;
if ((char)i==c)
return irr::video::E_DRIVER_TYPE(i-1);
}
return irr::video::EDT_COUNT;
}
} // end namespace irr
#endif

View File

@ -13,18 +13,18 @@
#include <limits.h> // For INT_MAX / UINT_MAX
#if defined(_IRR_SOLARIS_PLATFORM_) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) || defined (_WIN32_WCE)
#define sqrtf(X) (f32)sqrt((f64)(X))
#define sinf(X) (f32)sin((f64)(X))
#define cosf(X) (f32)cos((f64)(X))
#define asinf(X) (f32)asin((f64)(X))
#define acosf(X) (f32)acos((f64)(X))
#define atan2f(X,Y) (f32)atan2((f64)(X),(f64)(Y))
#define ceilf(X) (f32)ceil((f64)(X))
#define floorf(X) (f32)floor((f64)(X))
#define powf(X,Y) (f32)pow((f64)(X),(f64)(Y))
#define fmodf(X,Y) (f32)fmod((f64)(X),(f64)(Y))
#define fabsf(X) (f32)fabs((f64)(X))
#define logf(X) (f32)log((f64)(X))
#define sqrtf(X) (irr::f32)sqrt((irr::f64)(X))
#define sinf(X) (irr::f32)sin((irr::f64)(X))
#define cosf(X) (irr::f32)cos((irr::f64)(X))
#define asinf(X) (irr::f32)asin((irr::f64)(X))
#define acosf(X) (irr::f32)acos((irr::f64)(X))
#define atan2f(X,Y) (irr::f32)atan2((irr::f64)(X),(irr::f64)(Y))
#define ceilf(X) (irr::f32)ceil((irr::f64)(X))
#define floorf(X) (irr::f32)floor((irr::f64)(X))
#define powf(X,Y) (irr::f32)pow((irr::f64)(X),(irr::f64)(Y))
#define fmodf(X,Y) (irr::f32)fmod((irr::f64)(X),(irr::f64)(Y))
#define fabsf(X) (irr::f32)fabs((irr::f64)(X))
#define logf(X) (irr::f32)log((irr::f64)(X))
#endif
#ifndef FLT_MAX
@ -162,10 +162,14 @@ namespace core
}
//! swaps the content of the passed parameters
template <class T>
inline void swap(T& a, T& b)
// Note: We use the same trick as boost and use two template arguments to
// avoid ambiguity when swapping objectsof an Irrlicht type that has not
// it's own swap overload. Otherwise we get conflicts with some compilers
// in combination with stl.
template <class T1, class T2>
inline void swap(T1& a, T2& b)
{
T c(a);
T1 c(a);
a = b;
b = c;
}

View File

@ -79,7 +79,7 @@ public:
: array(0), allocated(1), used(1)
{
array = allocator.allocate(1); // new T[1];
array[0] = 0x0;
array[0] = 0;
}
@ -188,6 +188,85 @@ public:
}
//! Constructs a string from a long
explicit string(long number)
: array(0), allocated(0), used(0)
{
// store if negative and make positive
bool negative = false;
if (number < 0)
{
number *= -1;
negative = true;
}
// temporary buffer for 16 numbers
c8 tmpbuf[16]={0};
u32 idx = 15;
// special case '0'
if (!number)
{
tmpbuf[14] = '0';
*this = &tmpbuf[14];
return;
}
// add numbers
while(number && idx)
{
--idx;
tmpbuf[idx] = (c8)('0' + (number % 10));
number /= 10;
}
// add sign
if (negative)
{
--idx;
tmpbuf[idx] = '-';
}
*this = &tmpbuf[idx];
}
//! Constructs a string from an unsigned long
explicit string(unsigned long number)
: array(0), allocated(0), used(0)
{
// temporary buffer for 16 numbers
c8 tmpbuf[16]={0};
u32 idx = 15;
// special case '0'
if (!number)
{
tmpbuf[14] = '0';
*this = &tmpbuf[14];
return;
}
// add numbers
while(number && idx)
{
--idx;
tmpbuf[idx] = (c8)('0' + (number % 10));
number /= 10;
}
*this = &tmpbuf[idx];
}
//! Constructor for copying a string from a pointer with a given length
template <class B>
string(const B* const c, u32 length)
@ -402,6 +481,12 @@ public:
return used-1;
}
//! Informs if the string is empty or not.
//! \return True if the string is empty, false if not.
bool empty() const
{
return (size() == 0);
}
//! Returns character string
/** \return pointer to C-style NUL terminated string. */
@ -412,18 +497,20 @@ public:
//! Makes the string lower case.
void make_lower()
string<T,TAlloc>& make_lower()
{
for (u32 i=0; i<used; ++i)
array[i] = locale_lower ( array[i] );
return *this;
}
//! Makes the string upper case.
void make_upper()
string<T,TAlloc>& make_upper()
{
for (u32 i=0; i<used; ++i)
array[i] = locale_upper ( array[i] );
return *this;
}
@ -511,7 +598,7 @@ public:
//! Appends a character to this string
/** \param character: Character to append. */
void append(T character)
string<T,TAlloc>& append(T character)
{
if (used + 1 > allocated)
reallocate(used + 1);
@ -520,15 +607,18 @@ public:
array[used-2] = character;
array[used-1] = 0;
return *this;
}
//! Appends a char string to this string
/** \param other: Char string to append. */
void append(const T* const other)
/** \param length: The length of the string to append. */
string<T,TAlloc>& append(const T* const other, u32 length=0xffffffff)
{
if (!other)
return;
return *this;
u32 len = 0;
const T* p = other;
@ -537,6 +627,8 @@ public:
++len;
++p;
}
if (len > length)
len = length;
if (used + len > allocated)
reallocate(used + len);
@ -548,13 +640,18 @@ public:
array[l+used] = *(other+l);
used += len;
return *this;
}
//! Appends a string to this string
/** \param other: String to append. */
void append(const string<T,TAlloc>& other)
string<T,TAlloc>& append(const string<T,TAlloc>& other)
{
if (other.size() == 0)
return *this;
--used;
u32 len = other.size()+1;
@ -565,18 +662,23 @@ public:
array[used+l] = other[l];
used += len;
return *this;
}
//! Appends a string of the length l to this string.
/** \param other: other String to append to this string.
\param length: How much characters of the other string to add to this one. */
void append(const string<T,TAlloc>& other, u32 length)
string<T,TAlloc>& append(const string<T,TAlloc>& other, u32 length)
{
if (other.size() == 0)
return *this;
if (other.size() < length)
{
append(other);
return;
return *this;
}
if (used + length > allocated)
@ -591,6 +693,8 @@ public:
// ensure proper termination
array[used]=0;
++used;
return *this;
}
@ -625,9 +729,9 @@ public:
this should be strlen(c)
\return Position where one of the characters has been found,
or -1 if not found. */
s32 findFirstChar(const T* const c, u32 count) const
s32 findFirstChar(const T* const c, u32 count=1) const
{
if (!c)
if (!c || !count)
return -1;
for (u32 i=0; i<used; ++i)
@ -647,8 +751,11 @@ public:
\return Position where the character has been found,
or -1 if not found. */
template <class B>
s32 findFirstCharNotInList(const B* const c, u32 count) const
s32 findFirstCharNotInList(const B* const c, u32 count=1) const
{
if (!c || !count)
return -1;
for (u32 i=0; i<used-1; ++i)
{
u32 j;
@ -671,8 +778,11 @@ public:
\return Position where the character has been found,
or -1 if not found. */
template <class B>
s32 findLastCharNotInList(const B* const c, u32 count) const
s32 findLastCharNotInList(const B* const c, u32 count=1) const
{
if (!c || !count)
return -1;
for (s32 i=(s32)(used-2); i>=0; --i)
{
u32 j;
@ -724,9 +834,9 @@ public:
this should be strlen(c)
\return Position where one of the characters has been found,
or -1 if not found. */
s32 findLastChar(const T* const c, u32 count) const
s32 findLastChar(const T* const c, u32 count=1) const
{
if (!c)
if (!c || !count)
return -1;
for (s32 i=used-1; i>=0; --i)
@ -854,7 +964,7 @@ public:
//! Appends a string representation of a number to this string
/** \param i Number to append. */
string<T,TAlloc>& operator += (const unsigned long& i)
string<T,TAlloc>& operator += (const unsigned long i)
{
append(string<T,TAlloc>(i));
return *this;
@ -882,17 +992,133 @@ public:
//! Replaces all characters of a special type with another one
/** \param toReplace Character to replace.
\param replaceWith Character replacing the old one. */
void replace(T toReplace, T replaceWith)
string<T,TAlloc>& replace(T toReplace, T replaceWith)
{
for (u32 i=0; i<used; ++i)
if (array[i] == toReplace)
array[i] = replaceWith;
return *this;
}
//! Replaces all instances of a string with another one.
/** \param toReplace The string to replace.
\param replaceWith The string replacing the old one. */
string<T,TAlloc>& replace(const string<T,TAlloc>& toReplace, const string<T,TAlloc>& replaceWith)
{
if (toReplace.size() == 0)
return *this;
const T* other = toReplace.c_str();
const T* replace = replaceWith.c_str();
const u32 other_size = toReplace.size();
const u32 replace_size = replaceWith.size();
// Determine the delta. The algorithm will change depending on the delta.
s32 delta = replace_size - other_size;
// A character for character replace. The string will not shrink or grow.
if (delta == 0)
{
s32 pos = 0;
while ((pos = find(other, pos)) != -1)
{
for (u32 i = 0; i < replace_size; ++i)
array[pos + i] = replace[i];
++pos;
}
return *this;
}
// We are going to be removing some characters. The string will shrink.
if (delta < 0)
{
u32 i = 0;
for (u32 pos = 0; pos < used; ++i, ++pos)
{
// Is this potentially a match?
if (array[pos] == *other)
{
// Check to see if we have a match.
u32 j;
for (j = 0; j < other_size; ++j)
{
if (array[pos + j] != other[j])
break;
}
// If we have a match, replace characters.
if (j == other_size)
{
for (j = 0; j < replace_size; ++j)
array[i + j] = replace[j];
i += replace_size - 1;
pos += other_size - 1;
continue;
}
}
// No match found, just copy characters.
array[i] = array[pos];
}
array[i-1] = 0;
used = i;
return *this;
}
// We are going to be adding characters, so the string size will increase.
// Count the number of times toReplace exists in the string so we can allocate the new size.
u32 find_count = 0;
s32 pos = 0;
while ((pos = find(other, pos)) != -1)
{
++find_count;
++pos;
}
// Re-allocate the string now, if needed.
u32 len = delta * find_count;
if (used + len > allocated)
reallocate(used + len);
// Don't take the string terminator into account.
--used;
// Start replacing.
pos = 0;
while ((pos = find(other, pos)) != -1)
{
T* start = array + pos + other_size - 1;
T* ptr = array + used;
T* end = array + used + delta;
// Shift characters to make room for the string.
while (ptr != start)
{
*end = *ptr;
--ptr;
--end;
}
// Add the new string now.
for (u32 i = 0; i < replace_size; ++i)
array[pos + i] = replace[i];
pos += replace_size;
used += delta;
}
// Terminate the string and return ourself.
array[used] = 0;
++used;
return *this;
}
//! Removes characters from a string.
/** \param c: Character to remove. */
void remove(T c)
string<T,TAlloc>& remove(T c)
{
u32 pos = 0;
u32 found = 0;
@ -907,15 +1133,18 @@ public:
array[pos++] = array[i];
}
used -= found;
array[used] = 0;
array[used-1] = 0;
return *this;
}
//! Removes a string from the string.
/** \param toRemove: String to remove. */
void remove(const string<T,TAlloc> toRemove)
string<T,TAlloc>& remove(const string<T,TAlloc>& toRemove)
{
u32 size = toRemove.size();
if ( size == 0 )
return *this;
u32 pos = 0;
u32 found = 0;
for (u32 i=0; i<used; ++i)
@ -937,14 +1166,18 @@ public:
array[pos++] = array[i];
}
used -= found;
array[used] = 0;
array[used-1] = 0;
return *this;
}
//! Removes characters from a string.
/** \param characters: Characters to remove. */
void removeChars(const string<T,TAlloc> & characters)
string<T,TAlloc>& removeChars(const string<T,TAlloc> & characters)
{
if (characters.size() == 0)
return *this;
u32 pos = 0;
u32 found = 0;
for (u32 i=0; i<used; ++i)
@ -967,7 +1200,9 @@ public:
array[pos++] = array[i];
}
used -= found;
array[used] = 0;
array[used-1] = 0;
return *this;
}
@ -991,7 +1226,7 @@ public:
/** May be slow, because all elements
following after the erased element have to be copied.
\param index: Index of element to be erased. */
void erase(u32 index)
string<T,TAlloc>& erase(u32 index)
{
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
@ -999,10 +1234,11 @@ public:
array[i-1] = array[i];
--used;
return *this;
}
//! verify the existing string.
void validate()
string<T,TAlloc>& validate()
{
// terminate on existing null
for (u32 i=0; i<allocated; ++i)
@ -1010,20 +1246,22 @@ public:
if (array[i] == 0)
{
used = i + 1;
return;
return *this;
}
}
// terminate
if ( allocated > 0 )
{
used = allocated - 1;
array[used] = 0;
used = allocated;
array[used-1] = 0;
}
else
{
used = 0;
}
return *this;
}
//! gets the last char of a string or null

View File

@ -217,5 +217,9 @@ code like 'code', but some generate warnings so we use this macro here */
((irr::u32)(irr::u8)(c0) | ((irr::u32)(irr::u8)(c1) << 8) | \
((irr::u32)(irr::u8)(c2) << 16) | ((irr::u32)(irr::u8)(c3) << 24 ))
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#define _strcmpi(a,b) strcmpi(a,b)
#endif
#endif // __IRR_TYPES_H_INCLUDED__

View File

@ -366,15 +366,29 @@ namespace io
};
template <typename T>
struct xmlChar
{
T c;
xmlChar<T>() {}
xmlChar<T>(char in) : c(static_cast<T>(in)) {}
xmlChar<T>(wchar_t in) : c(static_cast<T>(in)) {}
explicit xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {}
explicit xmlChar<T>(unsigned int in) : c(static_cast<T>(in)) {}
explicit xmlChar<T>(unsigned long in) : c(static_cast<T>(in)) {}
operator T() const { return c; }
void operator=(int t) { c=static_cast<T>(t); }
};
//! defines the utf-16 type.
/** Not using wchar_t for this because
wchar_t has 16 bit on windows and 32 bit on other operating systems. */
typedef unsigned short char16;
typedef xmlChar<unsigned short> char16;
//! defines the utf-32 type.
/** Not using wchar_t for this because
wchar_t has 16 bit on windows and 32 bit on other operating systems. */
typedef unsigned long char32;
typedef xmlChar<unsigned int> char32;
//! A UTF-8 or ASCII character xml parser.
/** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser.

View File

@ -184,7 +184,7 @@
#include "vector2d.h"
#include "vector3d.h"
/*! \mainpage Irrlicht Engine 1.6 API documentation
/*! \mainpage Irrlicht Engine 1.7 API documentation
*
* <div align="center"><img src="logobig.png" ></div>
*

View File

@ -69,13 +69,15 @@ class line2d
//! Tests if this line intersects with another line.
/** \param l: Other line to test intersection with.
\param checkOnlySegments: Default is to check intersection between the begin and endpoints.
When set to false the function will check for the first intersection point when extending the lines.
\param out: If there is an intersection, the location of the
intersection will be stored in this vector.
\return True if there is an intersection, false if not. */
bool intersectWith(const line2d<T>& l, vector2d<T>& out) const
bool intersectWith(const line2d<T>& l, vector2d<T>& out, bool checkOnlySegments=true) const
{
// Uses the method given at:
// http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
// http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
const f32 commonDenominator = (l.end.Y - l.start.Y)*(end.X - start.X) -
(l.end.X - l.start.X)*(end.Y - start.Y);
@ -83,10 +85,10 @@ class line2d
(l.end.Y - l.start.Y)*(start.X -l.start.X);
const f32 numeratorB = (end.X - start.X)*(start.Y - l.start.Y) -
(end.Y - start.Y)*(start.X -l.start.X);
(end.Y - start.Y)*(start.X -l.start.X);
if(equals(commonDenominator, 0.f))
{
{
// The lines are either coincident or parallel
if(equals(numeratorA, 0.f) && equals(numeratorB, 0.f))
{
@ -109,17 +111,17 @@ class line2d
// Get the point of intersection on this line, checking that
// it is within the line segment.
const f32 uA = numeratorA / commonDenominator;
if(uA < 0.f || uA > 1.f)
if(checkOnlySegments && (uA < 0.f || uA > 1.f) )
return false; // Outside the line segment
const f32 uB = numeratorB / commonDenominator;
if(uB < 0.f || uB > 1.f)
if(checkOnlySegments && (uB < 0.f || uB > 1.f))
return false; // Outside the line segment
// Calculate the intersection point.
out.X = start.X + uA * (end.X - start.X);
out.Y = start.Y + uA * (end.Y - start.Y);
return true;
return true;
}
//! Get unit vector of the line.

View File

@ -22,16 +22,15 @@
//#define USE_MATRIX_TEST_DEBUG
#if defined( USE_MATRIX_TEST_DEBUG )
#include <windows.h>
struct MatrixTest
{
MatrixTest () : ID(0), Calls(0) {}
char buf[256];
int Calls;
int ID;
};
static MatrixTest MTest;
struct MatrixTest
{
MatrixTest () : ID(0), Calls(0) {}
char buf[256];
int Calls;
int ID;
};
static MatrixTest MTest;
#endif
@ -64,7 +63,7 @@ namespace core
//! Copy constructor
/** \param other Other matrix to copy from
\param constructor Choose the initialization style */
CMatrix4( const CMatrix4<T>& other,eConstructor constructor = EM4CONST_COPY);
CMatrix4(const CMatrix4<T>& other, eConstructor constructor = EM4CONST_COPY);
//! Simple operator for directly accessing every element of the matrix.
T& operator()(const s32 row, const s32 col)
@ -125,17 +124,20 @@ namespace core
CMatrix4<T>& operator-=(const CMatrix4<T>& other);
//! set this matrix to the product of two matrices
/** Calculate b*a */
inline CMatrix4<T>& setbyproduct(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
//! Set this matrix to the product of two matrices
/** no optimization used,
/** Calculate b*a, no optimization used,
use it if you know you never have a identity matrix */
CMatrix4<T>& setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
//! Multiply by another matrix.
/** Calculate other*this */
CMatrix4<T> operator*(const CMatrix4<T>& other) const;
//! Multiply by another matrix.
/** Calculate and return other*this */
CMatrix4<T>& operator*=(const CMatrix4<T>& other);
//! Multiply by scalar.
@ -258,6 +260,9 @@ namespace core
//! Builds a left-handed perspective projection matrix based on a field of view
CMatrix4<T>& buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
//! Builds a left-handed perspective projection matrix based on a field of view, with far plane at infinity
CMatrix4<T>& buildProjectionMatrixPerspectiveFovInfinityLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 epsilon=0);
//! Builds a right-handed perspective projection matrix.
CMatrix4<T>& buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
@ -851,7 +856,7 @@ namespace core
const core::vector3d<T> scale = getScale();
const core::vector3d<f64> invScale(core::reciprocal(scale.X),core::reciprocal(scale.Y),core::reciprocal(scale.Z));
f64 Y = -asin(mat[2]*invScale.X);
f64 Y = -asin(core::clamp(mat[2]*invScale.X, -1.0, 1.0));
const f64 C = cos(Y);
Y *= RADTODEG64;
@ -1413,7 +1418,7 @@ namespace core
{
const f64 h = reciprocal(tan(fieldOfViewRadians*0.5));
_IRR_DEBUG_BREAK_IF(aspectRatio==0.f); //divide by zero
const T w = h / aspectRatio;
const T w = static_cast<T>(h / aspectRatio);
_IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero
M[0] = w;
@ -1452,7 +1457,7 @@ namespace core
{
const f64 h = reciprocal(tan(fieldOfViewRadians*0.5));
_IRR_DEBUG_BREAK_IF(aspectRatio==0.f); //divide by zero
const T w = (T)(h / aspectRatio);
const T w = static_cast<T>(h / aspectRatio);
_IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero
M[0] = w;
@ -1482,6 +1487,42 @@ namespace core
}
// Builds a left-handed perspective projection matrix based on a field of view, with far plane culling at infinity
template <class T>
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovInfinityLH(
f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 epsilon)
{
const f64 h = reciprocal(tan(fieldOfViewRadians*0.5));
_IRR_DEBUG_BREAK_IF(aspectRatio==0.f); //divide by zero
const T w = static_cast<T>(h / aspectRatio);
M[0] = w;
M[1] = 0;
M[2] = 0;
M[3] = 0;
M[4] = 0;
M[5] = (T)h;
M[6] = 0;
M[7] = 0;
M[8] = 0;
M[9] = 0;
M[10] = (T)(1.f-epsilon);
M[11] = 1;
M[12] = 0;
M[13] = 0;
M[14] = (T)(zNear*(epsilon-1.f));
M[15] = 0;
#if defined ( USE_MATRIX_TEST )
definitelyIdentityMatrix=false;
#endif
return *this;
}
// Builds a left-handed orthogonal projection matrix.
template <class T>
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoLH(
@ -1817,22 +1858,22 @@ namespace core
inline CMatrix4<T>& CMatrix4<T>::buildRotateFromTo(const core::vector3df& from, const core::vector3df& to)
{
// unit vectors
core::vector3df f ( from );
core::vector3df t ( to );
f.normalize ();
t.normalize ();
core::vector3df f(from);
core::vector3df t(to);
f.normalize();
t.normalize();
// axis multiplication by sin
core::vector3df vs ( t.crossProduct ( f ) );
core::vector3df vs(t.crossProduct(f));
// axis of rotation
core::vector3df v ( vs );
core::vector3df v(vs);
v.normalize();
// cosinus angle
T ca = f.dotProduct ( t );
T ca = f.dotProduct(t);
core::vector3df vt ( v * ( (T) 1 - ca ) );
core::vector3df vt(v * (1 - ca));
M[0] = vt.X * v.X + ca;
M[5] = vt.Y * v.Y + ca;
@ -1844,84 +1885,78 @@ namespace core
M[1] = vt.X - vs.Z;
M[2] = vt.Z + vs.Y;
M[3] = (T) 0;
M[3] = 0;
M[4] = vt.X + vs.Z;
M[6] = vt.Y - vs.X;
M[7] = (T) 0;
M[7] = 0;
M[8] = vt.Z - vs.Y;
M[9] = vt.Y + vs.X;
M[11] = (T) 0;
M[11] = 0;
M[12] = (T) 0;
M[13] = (T) 0;
M[14] = (T) 0;
M[15] = (T) 1;
M[12] = 0;
M[13] = 0;
M[14] = 0;
M[15] = 1;
return *this;
}
//! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis
/** \param camPos: viewer position in world coo
\param center: object position in world-coo and rotation pivot
/** \param camPos: viewer position in world coord
\param center: object position in world-coord, rotation pivot
\param translation: object final translation from center
\param axis: axis to rotate about
\param from: source vector to rotate from
*/
template <class T>
inline void CMatrix4<T>::buildAxisAlignedBillboard( const core::vector3df& camPos,
const core::vector3df& center,
const core::vector3df& translation,
const core::vector3df& axis,
const core::vector3df& from
)
inline void CMatrix4<T>::buildAxisAlignedBillboard(
const core::vector3df& camPos,
const core::vector3df& center,
const core::vector3df& translation,
const core::vector3df& axis,
const core::vector3df& from)
{
// axis of rotation
core::vector3df up = axis;
up.normalize ();
core::vector3df forward = camPos - center;
forward.normalize();
core::vector3df right = up.crossProduct ( forward );
right.normalize ();
up.normalize();
const core::vector3df forward = (camPos - center).normalize();
const core::vector3df right = up.crossProduct(forward).normalize();
// correct look vector
core::vector3df look = right.crossProduct ( up );
const core::vector3df look = right.crossProduct(up);
// rotate from to
// axis multiplication by sin
core::vector3df vs = look.crossProduct ( from );
const core::vector3df vs = look.crossProduct(from);
// cosinus angle
f32 ca = from.dotProduct ( look );
const f32 ca = from.dotProduct(look);
core::vector3df vt ( up * ( 1.f - ca ) );
core::vector3df vt(up * (1.f - ca));
M[0] = vt.X * up.X + ca;
M[5] = vt.Y * up.Y + ca;
M[10] = vt.Z * up.Z + ca;
M[0] = static_cast<T>(vt.X * up.X + ca);
M[5] = static_cast<T>(vt.Y * up.Y + ca);
M[10] = static_cast<T>(vt.Z * up.Z + ca);
vt.X *= up.Y;
vt.Z *= up.X;
vt.Y *= up.Z;
M[1] = vt.X - vs.Z;
M[2] = vt.Z + vs.Y;
M[3] = (T) 0;
M[1] = static_cast<T>(vt.X - vs.Z);
M[2] = static_cast<T>(vt.Z + vs.Y);
M[3] = 0;
M[4] = vt.X + vs.Z;
M[6] = vt.Y - vs.X;
M[7] = (T) 0;
M[4] = static_cast<T>(vt.X + vs.Z);
M[6] = static_cast<T>(vt.Y - vs.X);
M[7] = 0;
M[8] = vt.Z - vs.Y;
M[9] = vt.Y + vs.X;
M[11] = (T) 0;
setRotationCenter ( center, translation );
M[8] = static_cast<T>(vt.Z - vs.Y);
M[9] = static_cast<T>(vt.Y + vs.X);
M[11] = 0;
setRotationCenter(center, translation);
}

View File

@ -82,6 +82,10 @@ class quaternion
//! Sets new quaternion from other quaternion
inline quaternion& set(const core::quaternion& quat);
//! returns if this quaternion equals the other one, taking floating point rounding errors into account
inline bool equals(const quaternion& other,
const f32 tolerance = ROUNDING_ERROR_f32 ) const;
//! Normalizes the quaternion
inline quaternion& normalize();
@ -462,6 +466,17 @@ inline quaternion& quaternion::set(const core::quaternion& quat)
return (*this=quat);
}
//! returns if this quaternion equals the other one, taking floating point rounding errors into account
inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const
{
return core::equals(X, other.X, tolerance) &&
core::equals(Y, other.Y, tolerance) &&
core::equals(Z, other.Z, tolerance) &&
core::equals(W, other.W, tolerance);
}
// normalizes the quaternion
inline quaternion& quaternion::normalize()
{
@ -613,6 +628,17 @@ inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const
{
return makeIdentity();
}
else if (d <= -1.0f) // exactly opposite
{
core::vector3df axis(1.0f, 0.f, 0.f);
axis = axis.crossProduct(core::vector3df(X,Y,Z));
if (axis.getLength()==0)
{
axis.set(0.f,1.f,0.f);
axis.crossProduct(core::vector3df(X,Y,Z));
}
return this->fromAngleAxis(core::PI, axis);
}
const f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt
const f32 invs = 1.f / s;

View File

@ -327,7 +327,7 @@ namespace core
this vector. The calculation assumes the pole at (0,1,0) and
returns the angles in X and Y.
*/
vector3d<T> getSphericalCoordinateAngles()
vector3d<T> getSphericalCoordinateAngles() const
{
vector3d<T> angle;
const f64 length = X*X + Y*Y + Z*Z;

View File

@ -350,23 +350,6 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop,
InterpolationBuffer->setDirty();
}
//! calculates the bounding box
void CAnimatedMeshMD2::calculateBoundingBox()
{
InterpolationBuffer->BoundingBox.reset(0,0,0);
if (FrameCount)
{
u32 defaultFrame = 1;
if (defaultFrame>=FrameCount)
defaultFrame = 0;
// for (u32 j=0; j<FrameList[defaultFrame].size(); ++j)
// InterpolationBuffer->BoundingBox.addInternalPoint(FrameList[defaultFrame].pointer()[j].Pos);
}
}
//! sets a flag of all contained materials to a new value
void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
@ -375,7 +358,6 @@ void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalu
}
//! set the hardware mapping hint, for driver
void CAnimatedMeshMD2::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint,
E_BUFFER_TYPE buffer)

View File

@ -122,9 +122,6 @@ namespace scene
//! named animations
core::array< SAnimationData > AnimationData;
//! calculates the bounding box
virtual void calculateBoundingBox();
u32 FrameCount;
private:

View File

@ -1060,9 +1060,15 @@ ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager*
if (!newManager) newManager = SceneManager;
CAnimatedMeshSceneNode * newNode =
new CAnimatedMeshSceneNode(Mesh, newParent, newManager, ID, RelativeTranslation,
new CAnimatedMeshSceneNode(Mesh, NULL, newManager, ID, RelativeTranslation,
RelativeRotation, RelativeScale);
if ( newParent )
{
newNode->setParent(newParent); // not in constructor because virtual overload for updateAbsolutePosition won't be called
newNode->drop();
}
newNode->cloneMembers(this, newManager);
newNode->Materials = Materials;
@ -1088,7 +1094,6 @@ ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager*
newNode->RenderFromIdentity = RenderFromIdentity;
newNode->MD3Special = MD3Special;
(void)newNode->drop();
return newNode;
}

View File

@ -601,7 +601,7 @@ bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint)
core::vector3df oldScale[2];
CSkinnedMesh::SRotationKey *oldRotKey=0;
core::quaternion oldRot[2];
bool isFirst[3]={true};
bool isFirst[3]={true,true,true};
while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats
{
s32 frame;

View File

@ -225,13 +225,14 @@ ISceneNode* CBillboardSceneNode::clone(ISceneNode* newParent, ISceneManager* new
if (!newManager)
newManager = SceneManager;
CBillboardSceneNode* nb = new CBillboardSceneNode(newParent,
CBillboardSceneNode* nb = new CBillboardSceneNode(newParent,
newManager, ID, RelativeTranslation, Size);
nb->cloneMembers(this, newManager);
nb->Material = Material;
nb->drop();
if ( newParent )
nb->drop();
return nb;
}

View File

@ -14,7 +14,7 @@ namespace scene
//! constructor
CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::vector3df& lookat)
: ICameraSceneNode(parent, mgr, id, position),
Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
@ -25,14 +25,14 @@ CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 i
#endif
// set default projection
Fovy = core::PI / 2.5f; // Field of view, in radians.
Fovy = core::PI / 2.5f; // Field of view, in radians.
const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0;
if (d)
Aspect = (f32)d->getCurrentRenderTargetSize().Width /
(f32)d->getCurrentRenderTargetSize().Height;
else
Aspect = 4.0f / 3.0f; // Aspect ratio.
Aspect = 4.0f / 3.0f; // Aspect ratio.
recalculateProjectionMatrix();
recalculateViewArea();
@ -99,10 +99,10 @@ const core::matrix4& CCameraSceneNode::getViewMatrixAffector() const
//! It is possible to send mouse and key events to the camera. Most cameras
//! may ignore this input, but camera scene nodes which are created for
//! may ignore this input, but camera scene nodes which are created for
//! example with scene::ISceneManager::addMayaCameraSceneNode or
//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input
//! for changing their position, look at target or whatever.
//! for changing their position, look at target or whatever.
bool CCameraSceneNode::OnEvent(const SEvent& event)
{
if (!InputReceiverEnabled)
@ -111,7 +111,7 @@ bool CCameraSceneNode::OnEvent(const SEvent& event)
// send events to event receiving animators
ISceneNodeAnimatorList::Iterator ait = Animators.begin();
for (; ait != Animators.end(); ++ait)
if ((*ait)->isEventReceiverEnabled() && (*ait)->OnEvent(event))
return true;
@ -173,25 +173,25 @@ const core::vector3df& CCameraSceneNode::getUpVector() const
}
f32 CCameraSceneNode::getNearValue() const
f32 CCameraSceneNode::getNearValue() const
{
return ZNear;
}
f32 CCameraSceneNode::getFarValue() const
f32 CCameraSceneNode::getFarValue() const
{
return ZFar;
}
f32 CCameraSceneNode::getAspectRatio() const
f32 CCameraSceneNode::getAspectRatio() const
{
return Aspect;
}
f32 CCameraSceneNode::getFOV() const
f32 CCameraSceneNode::getFOV() const
{
return Fovy;
}
@ -243,7 +243,7 @@ void CCameraSceneNode::OnRegisterSceneNode()
//! render
void CCameraSceneNode::render()
{
{
core::vector3df pos = getAbsolutePosition();
core::vector3df tgtv = Target - pos;
tgtv.normalize();
@ -327,7 +327,7 @@ void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute
TargetAndRotationAreBound = in->getAttributeAsBool("Binding");
recalculateProjectionMatrix();
recalculateViewArea();
recalculateViewArea();
}
@ -353,12 +353,13 @@ ISceneNode* CCameraSceneNode::clone(ISceneNode* newParent, ISceneManager* newMan
if (!newManager)
newManager = SceneManager;
CCameraSceneNode* nb = new CCameraSceneNode(newParent,
CCameraSceneNode* nb = new CCameraSceneNode(newParent,
newManager, ID, RelativeTranslation, Target);
nb->cloneMembers(this, newManager);
nb->drop();
if ( newParent )
nb->drop();
return nb;
}

View File

@ -211,6 +211,7 @@ namespace
if (m)
{
m->setName(getId());
// m->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
// m->setDebugDataVisible(scene::EDS_FULL);
}
return m;
@ -445,6 +446,7 @@ void CColladaFileLoader::readColladaSection(io::IXMLReaderUTF8* reader)
if (reader->isEmptyElement())
return;
// todo: patch level needs to be handled
const f32 version = core::fast_atof(core::stringc(reader->getAttributeValue("version")).c_str());
Version = core::floor32(version)*10000+core::round32(core::fract(version)*1000.0f);
// Version 1.4 can be checked for by if (Version >= 10400)
@ -663,7 +665,7 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader)
}
else
if ((instanceSceneName == reader->getNodeName()))
readInstanceNode(reader, SceneManager->getRootSceneNode(), 0);
readInstanceNode(reader, SceneManager->getRootSceneNode(), 0, 0,instanceSceneName);
else
if (extraNodeName == reader->getNodeName())
skipSection(reader, false);
@ -714,14 +716,18 @@ void CColladaFileLoader::readAssetSection(io::IXMLReaderUTF8* reader)
//! reads a <node> section and its content
void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, CScenePrefab* p)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading node");
#endif
if (reader->isEmptyElement())
{
return;
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading empty node");
#endif
}
core::stringc name = readId(reader);
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading node", name);
#endif
core::matrix4 transform; // transformation of this node
core::aabbox3df bbox;
@ -774,7 +780,7 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
(instanceLightName == reader->getNodeName()))
{
scene::ISceneNode* newnode = 0;
readInstanceNode(reader, parent, &newnode, nodeprefab);
readInstanceNode(reader, parent, &newnode, nodeprefab, reader->getNodeName());
if (node && newnode)
{
@ -1081,16 +1087,17 @@ core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader)
//! reads any kind of <instance*> node
void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader,
scene::ISceneNode* parent, scene::ISceneNode** outNode, CScenePrefab* p)
scene::ISceneNode* parent, scene::ISceneNode** outNode,
CScenePrefab* p, const core::stringc& type)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading instance");
#endif
// find prefab of the specified id
core::stringc url = reader->getAttributeValue("url");
uriToId(url);
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading instance", url);
#endif
if (!reader->isEmptyElement())
{
while(reader->read())
@ -1108,12 +1115,13 @@ void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader,
break;
}
}
instantiateNode(parent, outNode, p, url);
instantiateNode(parent, outNode, p, url, type);
}
void CColladaFileLoader::instantiateNode(scene::ISceneNode* parent,
scene::ISceneNode** outNode, CScenePrefab* p, const core::stringc& url)
scene::ISceneNode** outNode, CScenePrefab* p, const core::stringc& url,
const core::stringc& type)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA instantiate node");
@ -1140,6 +1148,14 @@ void CColladaFileLoader::instantiateNode(scene::ISceneNode* parent,
return;
}
}
if (p)
{
if (instanceGeometryName==type)
{
Prefabs.push_back(new CGeometryPrefab(url));
p->Childs.push_back(Prefabs.getLast());
}
}
}
@ -1181,15 +1197,14 @@ void CColladaFileLoader::readCameraPrefab(io::IXMLReaderUTF8* reader)
//! reads a <image> element and stores it in the image section
void CColladaFileLoader::readImage(io::IXMLReaderUTF8* reader)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading image");
#endif
// add image to list of loaded images.
Images.push_back(SColladaImage());
SColladaImage& image=Images.getLast();
image.Id = readId(reader);
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading image", core::stringc(image.Id));
#endif
image.Dimension.Height = (u32)reader->getAttributeValueAsInt("height");
image.Dimension.Width = (u32)reader->getAttributeValueAsInt("width");
@ -1241,15 +1256,14 @@ void CColladaFileLoader::readImage(io::IXMLReaderUTF8* reader)
//! reads a <texture> element and stores it in the texture section
void CColladaFileLoader::readTexture(io::IXMLReaderUTF8* reader)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading texture");
#endif
// add texture to list of loaded textures.
Textures.push_back(SColladaTexture());
SColladaTexture& texture=Textures.getLast();
texture.Id = readId(reader);
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading texture", core::stringc(texture.Id));
#endif
if (!reader->isEmptyElement())
{
@ -1267,15 +1281,14 @@ void CColladaFileLoader::readTexture(io::IXMLReaderUTF8* reader)
//! reads a <material> element and stores it in the material section
void CColladaFileLoader::readMaterial(io::IXMLReaderUTF8* reader)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading material");
#endif
// add material to list of loaded materials.
Materials.push_back(SColladaMaterial());
SColladaMaterial& material = Materials.getLast();
material.Id = readId(reader);
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading material", core::stringc(material.Id));
#endif
if (Version >= 10400)
{
@ -1338,10 +1351,6 @@ void CColladaFileLoader::readMaterial(io::IXMLReaderUTF8* reader)
void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * effect)
{
#ifdef COLLADA_READER_DEBUG
if (!effect) os::Printer::log("COLLADA reading effect");
#endif
static const core::stringc constantNode("constant");
static const core::stringc lambertNode("lambert");
static const core::stringc phongNode("phong");
@ -1365,6 +1374,9 @@ void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect *
effect->Transparency = 1.f;
effect->Mat.Lighting=true;
effect->Mat.NormalizeNormals=true;
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading effect", core::stringc(effect->Id));
#endif
}
while(reader->read())
{
@ -1426,8 +1438,7 @@ void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect *
if (reader->getNodeType() == io::EXN_ELEMENT &&
textureNodeName == reader->getNodeName())
{
const core::stringc tname = reader->getAttributeValue("texture");
effect->Mat.setTexture(0, getTextureFromImage(tname));
effect->Textures.push_back(reader->getAttributeValue("texture"));
break;
}
else
@ -1536,6 +1547,10 @@ void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect *
const SColladaMaterial* CColladaFileLoader::findMaterial(const core::stringc& materialName)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA find material", materialName);
#endif
// do a quick lookup in the materials
SColladaMaterial matToFind;
matToFind.Id = materialName;
@ -1553,6 +1568,7 @@ const SColladaMaterial* CColladaFileLoader::findMaterial(const core::stringc& ma
{
// found the effect, instantiate by copying into the material
Materials[mat].Mat = Effects[effect].Mat;
Materials[mat].Mat.setTexture(0, getTextureFromImage(Effects[effect].Textures[0]));
Materials[mat].Transparency = Effects[effect].Transparency;
// and indicate the material is instantiated by removing the effect ref
Materials[mat].InstanceEffectId = "";
@ -1634,20 +1650,16 @@ void CColladaFileLoader::readBindMaterialSection(io::IXMLReaderUTF8* reader, con
//! reads a <geometry> element and stores it as mesh if possible
void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading geometry");
#endif
core::stringc id = readId(reader);
core::stringc VertexPositionSource; // each mesh has exactly one <vertex> member, containing
// a POSITION input. This string stores the source of this input.
core::array<SSource> sources;
bool okToReadArray = false;
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading geometry", id);
#endif
SAnimatedMesh* amesh = new SAnimatedMesh();
scene::SMesh* mesh = new SMesh();
amesh->addMesh(mesh);
core::array<SSource> sources;
bool okToReadArray = false;
// handles geometry node and the mesh childs in this loop
// read sources with arrays and accessor for each mesh
@ -1728,9 +1740,6 @@ void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
#endif
// read vertex input position source
readColladaInputs(reader, verticesSectionName);
SColladaInput* input = getColladaInput(ECIS_POSITION);
if (input)
VertexPositionSource = input->Source;
}
else
// lines and linestrips missing
@ -1739,7 +1748,7 @@ void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
trianglesSectionName == nodeName)
{
// read polygons section
readPolygonSection(reader, VertexPositionSource, sources, mesh, id);
readPolygonSection(reader, sources, mesh, id);
}
else
// trifans, and tristrips missing
@ -1829,9 +1838,21 @@ void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
amesh->drop();
// create geometry prefab
CGeometryPrefab* prefab = new CGeometryPrefab(id.c_str());
prefab->Mesh = mesh;
Prefabs.push_back(prefab);
u32 i;
for (i=0; i<Prefabs.size(); ++i)
{
if (Prefabs[i]->getId()==id)
{
((CGeometryPrefab*)Prefabs[i])->Mesh=mesh;
break;
}
}
if (i==Prefabs.size())
{
CGeometryPrefab* prefab = new CGeometryPrefab(id);
prefab->Mesh = mesh;
Prefabs.push_back(prefab);
}
// store as dummy mesh if no instances will be created
if (!CreateInstances && !DummyMesh)
@ -1849,8 +1870,8 @@ struct SPolygon
//! reads a polygons section and creates a mesh from it
void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
const core::stringc& vertexPositionSource, core::array<SSource>& sources,
scene::SMesh* mesh, const core::stringc& geometryId)
core::array<SSource>& sources, scene::SMesh* mesh,
const core::stringc& geometryId)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading polygon section");
@ -1869,7 +1890,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
u32 inputSemanticCount = 0;
bool unresolvedInput=false;
u32 maxOffset = 0;
Inputs.clear();
core::array<SColladaInput> localInputs;
// read all <input> and primitives
if (!reader->isEmptyElement())
@ -1883,52 +1904,25 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
if (inputTagName == nodeName)
{
// read input tag
readColladaInput(reader);
readColladaInput(reader, localInputs);
// resolve input source
SColladaInput& inp = Inputs.getLast();
core::stringc sourceArrayURI;
SColladaInput& inp = localInputs.getLast();
// get input source array id, if it is a vertex input, take
// the <vertex><input>-source attribute.
if (inp.Semantic == ECIS_VERTEX)
sourceArrayURI = vertexPositionSource;
else
sourceArrayURI = inp.Source;
uriToId(sourceArrayURI);
// find source array (we'll ignore accessors for this implementation)
u32 s;
for (s=0; s<sources.size(); ++s)
{
if (sources[s].Id == sourceArrayURI)
inp.Source = Inputs[0].Source;
for (u32 i=1; i<Inputs.size(); ++i)
{
// slot found
inp.Data = sources[s].Array.Data.pointer();
inp.Stride = sources[s].Accessors[0].Stride;
break;
localInputs.push_back(Inputs[i]);
uriToId(localInputs.getLast().Source);
maxOffset = core::max_(maxOffset,localInputs.getLast().Offset);
++inputSemanticCount;
}
}
if (s == sources.size())
{
os::Printer::log("COLLADA Warning, polygon input source not found",
sourceArrayURI.c_str());
unresolvedInput=true;
}
else
{
#ifdef COLLADA_READER_DEBUG
// print slot
core::stringc tmp = "Added slot ";
tmp += inputSemanticNames[inp.Semantic];
tmp += " sourceArray:";
tmp += sourceArrayURI;
os::Printer::log(tmp.c_str());
#endif
}
uriToId(inp.Source);
maxOffset = core::max_(maxOffset,inp.Offset);
++inputSemanticCount;
}
@ -1998,7 +1992,6 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
for (u32 i = 0; i < vCounts.size(); i++)
{
const int polyVCount = vCounts[i];
core::array<int> polyCorners;
for (u32 j = 0; j < polyVCount * inputSemanticCount; j++)
@ -2029,10 +2022,43 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
}
} // end while reader->read()
if (inputSemanticCount == 0 || unresolvedInput)
return; // we cannot create the mesh if one of the input semantics wasn't found.
// find source array (we'll ignore accessors for this implementation)
for (u32 i=0; i<localInputs.size(); ++i)
{
SColladaInput& inp = localInputs[i];
u32 s;
for (s=0; s<sources.size(); ++s)
{
if (sources[s].Id == inp.Source)
{
// slot found
inp.Data = sources[s].Array.Data.pointer();
inp.Stride = sources[s].Accessors[0].Stride;
break;
}
}
if (!polygons.size())
if (s == sources.size())
{
os::Printer::log("COLLADA Warning, polygon input source not found",
inp.Source.c_str());
inp.Semantic=ECIS_COUNT; // for unknown
unresolvedInput=true;
}
else
{
#ifdef COLLADA_READER_DEBUG
// print slot
core::stringc tmp = "Added slot ";
tmp += inputSemanticNames[inp.Semantic];
tmp += " sourceArray:";
tmp += inp.Source;
os::Printer::log(tmp.c_str());
#endif
}
}
if ((inputSemanticCount == 0) || !polygons.size())
return; // cancel if there are no polygons anyway.
// analyze content of Inputs to create a fitting mesh buffer
@ -2084,47 +2110,47 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
vtx.Color.set(255,255,255,255);
// for all input semantics
for (u32 k=0; k<Inputs.size(); ++k)
for (u32 k=0; k<localInputs.size(); ++k)
{
if (!Inputs[k].Data)
if (!localInputs[k].Data)
continue;
// build vertex from input semantics.
const u32 idx = Inputs[k].Stride*polygons[i].Indices[v+Inputs[k].Offset];
const u32 idx = localInputs[k].Stride*polygons[i].Indices[v+localInputs[k].Offset];
switch(Inputs[k].Semantic)
switch(localInputs[k].Semantic)
{
case ECIS_POSITION:
case ECIS_VERTEX:
vtx.Pos.X = Inputs[k].Data[idx+0];
vtx.Pos.X = localInputs[k].Data[idx+0];
if (FlipAxis)
{
vtx.Pos.Z = Inputs[k].Data[idx+1];
vtx.Pos.Y = Inputs[k].Data[idx+2];
vtx.Pos.Z = localInputs[k].Data[idx+1];
vtx.Pos.Y = localInputs[k].Data[idx+2];
}
else
{
vtx.Pos.Y = Inputs[k].Data[idx+1];
vtx.Pos.Z = Inputs[k].Data[idx+2];
vtx.Pos.Y = localInputs[k].Data[idx+1];
vtx.Pos.Z = localInputs[k].Data[idx+2];
}
break;
case ECIS_NORMAL:
vtx.Normal.X = Inputs[k].Data[idx+0];
vtx.Normal.X = localInputs[k].Data[idx+0];
if (FlipAxis)
{
vtx.Normal.Z = Inputs[k].Data[idx+1];
vtx.Normal.Y = Inputs[k].Data[idx+2];
vtx.Normal.Z = localInputs[k].Data[idx+1];
vtx.Normal.Y = localInputs[k].Data[idx+2];
}
else
{
vtx.Normal.Y = Inputs[k].Data[idx+1];
vtx.Normal.Z = Inputs[k].Data[idx+2];
vtx.Normal.Y = localInputs[k].Data[idx+1];
vtx.Normal.Z = localInputs[k].Data[idx+2];
}
break;
case ECIS_TEXCOORD:
case ECIS_UV:
vtx.TCoords.X = Inputs[k].Data[idx+0];
vtx.TCoords.Y = 1-Inputs[k].Data[idx+1];
vtx.TCoords.X = localInputs[k].Data[idx+0];
vtx.TCoords.Y = 1-localInputs[k].Data[idx+1];
break;
case ECIS_TANGENT:
break;
@ -2216,48 +2242,48 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
{
// build vertex from input semantics.
const u32 idx = Inputs[k].Stride*polygons[i].Indices[v+Inputs[k].Offset];
const u32 idx = localInputs[k].Stride*polygons[i].Indices[v+Inputs[k].Offset];
switch(Inputs[k].Semantic)
switch(localInputs[k].Semantic)
{
case ECIS_POSITION:
case ECIS_VERTEX:
vtx.Pos.X = Inputs[k].Data[idx+0];
vtx.Pos.X = localInputs[k].Data[idx+0];
if (FlipAxis)
{
vtx.Pos.Z = Inputs[k].Data[idx+1];
vtx.Pos.Y = Inputs[k].Data[idx+2];
vtx.Pos.Z = localInputs[k].Data[idx+1];
vtx.Pos.Y = localInputs[k].Data[idx+2];
}
else
{
vtx.Pos.Y = Inputs[k].Data[idx+1];
vtx.Pos.Z = Inputs[k].Data[idx+2];
vtx.Pos.Y = localInputs[k].Data[idx+1];
vtx.Pos.Z = localInputs[k].Data[idx+2];
}
break;
case ECIS_NORMAL:
vtx.Normal.X = Inputs[k].Data[idx+0];
vtx.Normal.X = localInputs[k].Data[idx+0];
if (FlipAxis)
{
vtx.Normal.Z = Inputs[k].Data[idx+1];
vtx.Normal.Y = Inputs[k].Data[idx+2];
vtx.Normal.Z = localInputs[k].Data[idx+1];
vtx.Normal.Y = localInputs[k].Data[idx+2];
}
else
{
vtx.Normal.Y = Inputs[k].Data[idx+1];
vtx.Normal.Z = Inputs[k].Data[idx+2];
vtx.Normal.Y = localInputs[k].Data[idx+1];
vtx.Normal.Z = localInputs[k].Data[idx+2];
}
break;
case ECIS_TEXCOORD:
case ECIS_UV:
if (k==secondTexCoordSetIndex)
{
vtx.TCoords2.X = Inputs[k].Data[idx+0];
vtx.TCoords2.Y = 1-Inputs[k].Data[idx+1];
vtx.TCoords2.X = localInputs[k].Data[idx+0];
vtx.TCoords2.Y = 1-localInputs[k].Data[idx+1];
}
else
{
vtx.TCoords.X = Inputs[k].Data[idx+0];
vtx.TCoords.Y = 1-Inputs[k].Data[idx+1];
vtx.TCoords.X = localInputs[k].Data[idx+0];
vtx.TCoords.Y = 1-localInputs[k].Data[idx+1];
}
break;
case ECIS_TANGENT:
@ -2312,6 +2338,9 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
// add mesh buffer
mesh->addMeshBuffer(buffer);
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA added meshbuffer", core::stringc(buffer->getVertexCount())+" vertices, "+core::stringc(buffer->getIndexCount())+" indices.");
#endif
buffer->drop();
}
@ -2414,7 +2443,7 @@ SColladaInput* CColladaFileLoader::getColladaInput(ECOLLADA_INPUT_SEMANTIC input
//! reads a collada input tag and adds it to the input parameter
void CColladaFileLoader::readColladaInput(io::IXMLReaderUTF8* reader)
void CColladaFileLoader::readColladaInput(io::IXMLReaderUTF8* reader, core::array<SColladaInput>& inputs)
{
// parse param
SColladaInput p;
@ -2439,7 +2468,7 @@ void CColladaFileLoader::readColladaInput(io::IXMLReaderUTF8* reader)
p.Set = (u32)reader->getAttributeValueAsInt("set");
// add input
Inputs.push_back(p);
inputs.push_back(p);
}
//! parses all collada inputs inside an element and stores them in Inputs
@ -2452,7 +2481,7 @@ void CColladaFileLoader::readColladaInputs(io::IXMLReaderUTF8* reader, const cor
if (reader->getNodeType() == io::EXN_ELEMENT &&
inputTagName == reader->getNodeName())
{
readColladaInput(reader);
readColladaInput(reader, Inputs);
}
else
if (reader->getNodeType() == io::EXN_ELEMENT_END)
@ -2724,7 +2753,7 @@ core::stringc CColladaFileLoader::readId(io::IXMLReaderUTF8* reader)
video::ITexture* CColladaFileLoader::getTextureFromImage(core::stringc uri)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA searching texture", uri.c_str());
os::Printer::log("COLLADA searching texture", uri);
#endif
video::IVideoDriver* driver = SceneManager->getVideoDriver();
for (;;)

View File

@ -131,9 +131,10 @@ struct SColladaMaterial
//! Collada effect (materials, shaders, and programs)
struct SColladaEffect
{
video::SMaterial Mat;
core::stringc Id;
f32 Transparency;
core::array<core::stringc> Textures;
video::SMaterial Mat;
inline bool operator< (const SColladaEffect & other) const
{
@ -247,12 +248,14 @@ private:
f32 readFloatNode(io::IXMLReaderUTF8* reader);
//! reads a <instance> node
void readInstanceNode(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent,
scene::ISceneNode** outNode, CScenePrefab* p=0);
void readInstanceNode(io::IXMLReaderUTF8* reader,
scene::ISceneNode* parent, scene::ISceneNode** outNode,
CScenePrefab* p=0, const core::stringc& type=core::stringc());
//! creates a scene node from Prefabs (with name given in 'url')
void instantiateNode(scene::ISceneNode* parent, scene::ISceneNode** outNode=0,
CScenePrefab* p=0, const core::stringc& url="");
CScenePrefab* p=0, const core::stringc& url="",
const core::stringc& type=core::stringc());
//! reads a <light> element and stores it as prefab
void readLightPrefab(io::IXMLReaderUTF8* reader);
@ -306,7 +309,7 @@ private:
void readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName);
//! reads a collada input tag and adds it to the input parameter
void readColladaInput(io::IXMLReaderUTF8* reader);
void readColladaInput(io::IXMLReaderUTF8* reader, core::array<SColladaInput>& inputs);
//! returns a collada input or none if not found
SColladaInput* getColladaInput(ECOLLADA_INPUT_SEMANTIC input);
@ -319,8 +322,8 @@ private:
//! reads a polygons section and creates a mesh from it
void readPolygonSection(io::IXMLReaderUTF8* reader,
const core::stringc& vertexPositionSource, core::array<SSource>& sources,
scene::SMesh* mesh, const core::stringc& geometryId);
core::array<SSource>& sources, scene::SMesh* mesh,
const core::stringc& geometryId);
//! finds a material, possible instancing it
const SColladaMaterial * findMaterial(const core::stringc & materialName);
@ -353,7 +356,9 @@ private:
core::array<SColladaMaterial> Materials;
core::array<SColladaInput> Inputs;
core::array<SColladaEffect> Effects;
//! meshbuffer reference ("geomid/matname") -> index into MeshesToBind
core::map<core::stringc,u32> MaterialsToBind;
//! Array of buffers for each material binding
core::array< core::array<irr::scene::IMeshBuffer*> > MeshesToBind;
io::CAttributes Parameters;

View File

@ -24,7 +24,7 @@ namespace scene
| / | /
|/ | /
0------11,1/
000 100
000 100
*/
//! constructor
@ -190,13 +190,14 @@ ISceneNode* CCubeSceneNode::clone(ISceneNode* newParent, ISceneManager* newManag
if (!newManager)
newManager = SceneManager;
CCubeSceneNode* nb = new CCubeSceneNode(Size, newParent,
CCubeSceneNode* nb = new CCubeSceneNode(Size, newParent,
newManager, ID, RelativeTranslation);
nb->cloneMembers(this, newManager);
nb->getMaterial(0) = getMaterial(0);
nb->drop();
if ( newParent )
nb->drop();
return nb;
}

View File

@ -440,9 +440,12 @@ bool CD3D8Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
if (StencilBuffer)
flags |= D3DCLEAR_STENCIL;
hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0);
if (FAILED(hr))
os::Printer::log("Direct3D8 clear failed.", ELL_WARNING);
if (flags)
{
hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0);
if (FAILED(hr))
os::Printer::log("Direct3D8 clear failed.", ELL_WARNING);
}
hr = pID3DDevice->BeginScene();
if (FAILED(hr))
@ -1582,7 +1585,7 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
const D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) &&
material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
const D3DTEXTUREFILTERTYPE tftMip = material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT;
const D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE;
if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC)
pID3DDevice->SetTextureStageState(st, D3DTSS_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy));

View File

@ -35,7 +35,8 @@ CD3D9Driver::CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window,
MaxTextureUnits(0), MaxUserClipPlanes(0),
MaxLightDistance(0.f), LastSetLight(-1), Cached2DModeSignature(0),
ColorFormat(ECF_A8R8G8B8), DeviceLost(false),
Fullscreen(fullscreen), DriverWasReset(true), AlphaToCoverageSupport(false)
Fullscreen(fullscreen), DriverWasReset(true), OcclusionQuerySupport(false),
AlphaToCoverageSupport(false)
{
#ifdef _DEBUG
setDebugName("CD3D9Driver");
@ -72,9 +73,13 @@ CD3D9Driver::~CD3D9Driver()
{
deleteMaterialRenders();
deleteAllTextures();
// drop the main depth buffer
DepthBuffers[0]->drop();
removeAllOcclusionQueries();
removeAllHardwareBuffers();
for (u32 i=0; i<DepthBuffers.size(); ++i)
{
DepthBuffers[i]->drop();
}
DepthBuffers.clear();
// drop d3d9
@ -424,6 +429,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES);
MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes;
OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK);
if (VendorID==0x10DE)//NVidia
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
@ -513,9 +519,12 @@ bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
if (StencilBuffer)
flags |= D3DCLEAR_STENCIL;
hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0);
if (FAILED(hr))
os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING);
if (flags)
{
hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0);
if (FAILED(hr))
os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING);
}
hr = pID3DDevice->BeginScene();
if (FAILED(hr))
@ -633,6 +642,8 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_INDEPENDENTWRITEMASKS) != 0;
case EVDF_MRT_BLEND:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0;
case EVDF_OCCLUSION_QUERY:
return OcclusionQuerySupport;
default:
return false;
};
@ -1225,6 +1236,98 @@ void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer)
}
//! Create occlusion query.
/** Use node for identification and mesh for occlusion test. */
void CD3D9Driver::createOcclusionQuery(scene::ISceneNode* node,
const scene::IMesh* mesh)
{
if (!queryFeature(EVDF_OCCLUSION_QUERY))
return;
CNullDriver::createOcclusionQuery(node, mesh);
const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
if ((index != -1) && (OcclusionQueries[index].PID == 0))
pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[index].PID));
}
//! Remove occlusion query.
void CD3D9Driver::removeOcclusionQuery(scene::ISceneNode* node)
{
const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
if (index != -1)
{
if (OcclusionQueries[index].PID != 0)
reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Release();
CNullDriver::removeOcclusionQuery(node);
}
}
//! Run occlusion query. Draws mesh stored in query.
/** If the mesh shall not be rendered visible, use
overrideMaterial to disable the color and depth buffer. */
void CD3D9Driver::runOcclusionQuery(scene::ISceneNode* node, bool visible)
{
if (!node)
return;
const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
if (index != -1)
{
if (OcclusionQueries[index].PID)
reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Issue(D3DISSUE_BEGIN);
CNullDriver::runOcclusionQuery(node,visible);
if (OcclusionQueries[index].PID)
reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Issue(D3DISSUE_END);
}
}
//! Update occlusion query. Retrieves results from GPU.
/** If the query shall not block, set the flag to false.
Update might not occur in this case, though */
void CD3D9Driver::updateOcclusionQuery(scene::ISceneNode* node, bool block)
{
const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
if (index != -1)
{
// not yet started
if (OcclusionQueries[index].Run==u32(~0))
return;
bool available = block?true:false;
int tmp=0;
if (!block)
available=(reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), 0)==S_OK);
else
{
do
{
HRESULT hr = reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), D3DGETDATA_FLUSH);
available = (hr == S_OK);
if (hr!=S_FALSE)
break;
} while (!available);
}
if (available)
OcclusionQueries[index].Result = tmp;
}
}
//! Return query result.
/** Return value is the number of visible pixels/fragments.
The value is a safe approximation, i.e. can be larger than the
actual value of pixels. */
u32 CD3D9Driver::getOcclusionQueryResult(scene::ISceneNode* node) const
{
const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
if (index != -1)
return OcclusionQueries[index].Result;
else
return ~0;
}
//! draws a vertex primitive list
void CD3D9Driver::drawVertexPrimitiveList(const void* vertices,
u32 vertexCount, const void* indexList, u32 primitiveCount,
@ -2184,7 +2287,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) &&
material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
D3DTEXTUREFILTERTYPE tftMip = material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT;
D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE;
if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC)
pID3DDevice->SetSamplerState(st, D3DSAMP_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy));
@ -2252,10 +2355,11 @@ void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail)
// USE THE ZPASS METHOD
pID3DDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_INCR );
pID3DDevice->SetRenderState( D3DRS_STENCILREF, 0x1 );
pID3DDevice->SetRenderState( D3DRS_STENCILREF, 0x0 );
pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff );
pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
@ -2269,8 +2373,8 @@ void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail)
// USE THE ZFAIL METHOD
pID3DDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR );
pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState( D3DRS_STENCILREF, 0x0 );
@ -2310,8 +2414,9 @@ void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha)
pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1);
pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL);
//pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL);
pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff );
pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff );
@ -2597,13 +2702,13 @@ void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32
// ZPASS Method
// Draw front-side of shadow volume in stencil/z only
pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW );
pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT);
pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
// Now reverse cull order so front sides of shadow volume are written.
pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT);
pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR);
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
}
else
@ -2611,13 +2716,13 @@ void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32
// ZFAIL Method
// Draw front-side of shadow volume in stencil/z only
pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW );
pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT );
pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR);
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
// Now reverse cull order so front sides of shadow volume are written.
pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT );
pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
}
}
@ -2728,9 +2833,17 @@ bool CD3D9Driver::reset()
}
for (i=0; i<DepthBuffers.size(); ++i)
{
if(DepthBuffers[i]->Surface)
if (DepthBuffers[i]->Surface)
DepthBuffers[i]->Surface->Release();
}
for (i=0; i<OcclusionQueries.size(); ++i)
{
if (OcclusionQueries[i].PID)
{
reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[i].PID)->Release();
OcclusionQueries[i].PID=0;
}
}
// this does not require a restore in the reset method, it's updated
// automatically in the next render cycle.
removeAllHardwareBuffers();
@ -2750,7 +2863,7 @@ bool CD3D9Driver::reset()
pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
D3DSURFACE_DESC desc;
// restore other depth buffers
// dpeth format is taken from main depth buffer
// depth format is taken from main depth buffer
DepthBuffers[0]->Surface->GetDesc(&desc);
// multisampling is taken from rendertarget
D3DSURFACE_DESC desc2;
@ -2776,6 +2889,10 @@ bool CD3D9Driver::reset()
&(DepthBuffers[i]->Surface),
NULL);
}
for (i=0; i<OcclusionQueries.size(); ++i)
{
pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[i].PID));
}
if (FAILED(hr))
{

View File

@ -16,6 +16,9 @@
#include "CNullDriver.h"
#include "IMaterialRendererServices.h"
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
#endif
#include <d3d9.h>
namespace irr
@ -116,6 +119,30 @@ namespace video
//! Draw hardware buffer
virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer);
//! Create occlusion query.
/** Use node for identification and mesh for occlusion test. */
virtual void createOcclusionQuery(scene::ISceneNode* node,
const scene::IMesh* mesh=0);
//! Remove occlusion query.
virtual void removeOcclusionQuery(scene::ISceneNode* node);
//! Run occlusion query. Draws mesh stored in query.
/** If the mesh shall not be rendered visible, use
overrideMaterial to disable the color and depth buffer. */
virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false);
//! Update occlusion query. Retrieves results from GPU.
/** If the query shall not block, set the flag to false.
Update might not occur in this case, though */
virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true);
//! Return query result.
/** Return value is the number of visible pixels/fragments.
The value is a safe approximation, i.e. can be larger then the
actual value of pixels. */
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const;
//! draws a vertex primitive list
virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
@ -344,12 +371,12 @@ namespace video
//! language.
virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
@ -432,6 +459,7 @@ namespace video
bool DeviceLost;
bool Fullscreen;
bool DriverWasReset;
bool OcclusionQuerySupport;
bool AlphaToCoverageSupport;
};

View File

@ -9,6 +9,9 @@
#ifdef _IRR_WINDOWS_
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
#endif
#include <d3d9.h>
#include "IMaterialRenderer.h"

View File

@ -9,6 +9,9 @@
#ifdef _IRR_WINDOWS_
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
#endif
#include <d3d9.h>
#include "CD3D9ShaderMaterialRenderer.h"

View File

@ -9,6 +9,9 @@
#ifdef _IRR_WINDOWS_
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
#endif
#include <d3d9.h>
#include "CD3D9ShaderMaterialRenderer.h"

View File

@ -9,6 +9,9 @@
#ifdef _IRR_WINDOWS_
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
#endif
#include <d3d9.h>
#include <d3dx9shader.h>

View File

@ -10,6 +10,9 @@
#include "ITexture.h"
#include "IImage.h"
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
#endif
#include <d3d9.h>
namespace irr

View File

@ -54,13 +54,14 @@ ISceneNode* CEmptySceneNode::clone(ISceneNode* newParent, ISceneManager* newMana
if (!newManager)
newManager = SceneManager;
CEmptySceneNode* nb = new CEmptySceneNode(newParent,
CEmptySceneNode* nb = new CEmptySceneNode(newParent,
newManager, ID);
nb->cloneMembers(this, newManager);
nb->Box = Box;
nb->drop();
if ( newParent )
nb->drop();
return nb;
}

View File

@ -21,11 +21,11 @@
#include "CMemoryFile.h"
#include "CLimitReadFile.h"
#if defined (_IRR_WINDOWS_API_)
#if !defined ( _WIN32_WCE )
#include <direct.h> // for _chdir
#include <io.h> // for _access
#include <tchar.h>
#endif
#else
#if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
@ -603,7 +603,6 @@ IFileList* CFileSystem::createFileList()
//! Construct from native filesystem
if (FileSystemType == FILESYSTEM_NATIVE)
{
io::path fullPath;
// --------------------------------------------
//! Windows version
#ifdef _IRR_WINDOWS_API_
@ -611,18 +610,16 @@ IFileList* CFileSystem::createFileList()
r = new CFileList(Path, true, false);
struct _finddata_t c_file;
struct _tfinddata_t c_file;
long hFile;
if( (hFile = _findfirst( "*", &c_file )) != -1L )
if( (hFile = _tfindfirst( _T("*"), &c_file )) != -1L )
{
do
{
fullPath = Path + c_file.name;
r->addItem(fullPath, c_file.size, (_A_SUBDIR & c_file.attrib) != 0, 0);
r->addItem(Path + c_file.name, c_file.size, (_A_SUBDIR & c_file.attrib) != 0, 0);
}
while( _findnext( hFile, &c_file ) == 0 );
while( _tfindnext( hFile, &c_file ) == 0 );
_findclose( hFile );
}
@ -652,7 +649,6 @@ IFileList* CFileSystem::createFileList()
{
u32 size = 0;
bool isDirectory = false;
fullPath = Path + dirEntry->d_name;
if((strcmp(dirEntry->d_name, ".")==0) ||
(strcmp(dirEntry->d_name, "..")==0))
@ -673,7 +669,7 @@ IFileList* CFileSystem::createFileList()
}
#endif
r->addItem(fullPath, size, isDirectory, 0);
r->addItem(Path + dirEntry->d_name, size, isDirectory, 0);
}
closedir(dirHandle);
}
@ -703,12 +699,10 @@ IFileList* CFileSystem::createFileList()
{
if (core::isInSameDirectory(Path, merge->getFullFileName(j)) == 0)
{
io::path fullPath = merge->getFullFileName(j);
r->addItem(fullPath, merge->getFileSize(j), merge->isDirectory(j), 0);
r->addItem(merge->getFullFileName(j), merge->getFileSize(j), merge->isDirectory(j), 0);
}
}
}
}
if (r)
@ -751,8 +745,10 @@ bool CFileSystem::existFile(const io::path& filename) const
#else
return (_access(filename.c_str(), 0) != -1);
#endif
#else
#elif defined(F_OK)
return (access(filename.c_str(), F_OK) != -1);
#else
return (access(filename.c_str(), 0) != -1);
#endif
#endif
}

View File

@ -55,7 +55,7 @@ const wchar_t* IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE = L"type";
//! constructor
CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op)
: IGUIElement(EGUIET_ELEMENT, 0, 0, 0, core::rect<s32>(core::position2d<s32>(0,0), driver ? core::dimension2d<s32>(driver->getScreenSize()) : core::dimension2d<s32>(0,0))),
Driver(driver), Hovered(0), Focus(0), LastHoveredMousePos(0,0), CurrentSkin(0),
Driver(driver), Hovered(0), HoveredNoSubelement(0), Focus(0), LastHoveredMousePos(0,0), CurrentSkin(0),
FileSystem(fs), UserReceiver(0), Operator(op)
{
if (Driver)
@ -84,7 +84,9 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
//set tooltip default
ToolTip.LastTime = 0;
ToolTip.EnterTime = 0;
ToolTip.LaunchTime = 1000;
ToolTip.RelaunchTime = 500;
ToolTip.Element = 0;
// environment is root tab group
@ -96,6 +98,12 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
//! destructor
CGUIEnvironment::~CGUIEnvironment()
{
if ( HoveredNoSubelement && HoveredNoSubelement != this )
{
HoveredNoSubelement->drop();
HoveredNoSubelement = 0;
}
if (Hovered && Hovered != this)
{
Hovered->drop();
@ -359,6 +367,11 @@ void CGUIEnvironment::clear()
Hovered->drop();
Hovered = 0;
}
if ( HoveredNoSubelement && HoveredNoSubelement != this)
{
HoveredNoSubelement->drop();
HoveredNoSubelement = 0;
}
// get the root's children in case the root changes in future
const core::list<IGUIElement*>& children = getRootGUIElement()->getChildren();
@ -388,19 +401,12 @@ bool CGUIEnvironment::OnEvent(const SEvent& event)
//
void CGUIEnvironment::OnPostRender( u32 time )
{
// check tooltip
IGUIElement * hoveredNonSub = Hovered;
while ( hoveredNonSub && hoveredNonSub->isSubElement() )
{
hoveredNonSub = hoveredNonSub->getParent();
}
// launch tooltip
if ( time - ToolTip.LastTime >= ToolTip.LaunchTime &&
hoveredNonSub && hoveredNonSub != this &&
ToolTip.Element == 0 &&
hoveredNonSub != ToolTip.Element &&
hoveredNonSub->getToolTipText().size() &&
if ( ToolTip.Element == 0 &&
HoveredNoSubelement && HoveredNoSubelement != this &&
(time - ToolTip.EnterTime >= ToolTip.LaunchTime
|| (time - ToolTip.LastTime >= ToolTip.RelaunchTime && time - ToolTip.LastTime < ToolTip.LaunchTime)) &&
HoveredNoSubelement->getToolTipText().size() &&
getSkin() &&
getSkin()->getFont(EGDF_TOOLTIP)
)
@ -408,7 +414,7 @@ void CGUIEnvironment::OnPostRender( u32 time )
core::rect<s32> pos;
pos.UpperLeftCorner = LastHoveredMousePos;
core::dimension2du dim = getSkin()->getFont(EGDF_TOOLTIP)->getDimension(hoveredNonSub->getToolTipText().c_str());
core::dimension2du dim = getSkin()->getFont(EGDF_TOOLTIP)->getDimension(HoveredNoSubelement->getToolTipText().c_str());
dim.Width += getSkin()->getSize(EGDS_TEXT_DISTANCE_X)*2;
dim.Height += getSkin()->getSize(EGDS_TEXT_DISTANCE_Y)*2;
@ -418,7 +424,7 @@ void CGUIEnvironment::OnPostRender( u32 time )
pos.constrainTo(getAbsolutePosition());
ToolTip.Element = addStaticText(hoveredNonSub->getToolTipText().c_str(), pos, true, true, this, -1, true);
ToolTip.Element = addStaticText(HoveredNoSubelement->getToolTipText().c_str(), pos, true, true, this, -1, true);
ToolTip.Element->setOverrideColor(getSkin()->getColor(EGDC_TOOLTIP));
ToolTip.Element->setBackgroundColor(getSkin()->getColor(EGDC_TOOLTIP_BACKGROUND));
ToolTip.Element->setOverrideFont(getSkin()->getFont(EGDF_TOOLTIP));
@ -429,7 +435,22 @@ void CGUIEnvironment::OnPostRender( u32 time )
pos = ToolTip.Element->getRelativePosition();
pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + textHeight;
ToolTip.Element->setRelativePosition(pos);
}
if (ToolTip.Element && ToolTip.Element->isVisible() ) // (isVisible() check only because we might use visibility for ToolTip one day)
{
ToolTip.LastTime = time;
// got invisible or removed in the meantime?
if ( !HoveredNoSubelement ||
!HoveredNoSubelement->isVisible() ||
!HoveredNoSubelement->getParent()
) // got invisible or removed in the meantime?
{
ToolTip.Element->remove();
ToolTip.Element->drop();
ToolTip.Element = 0;
}
}
IGUIElement::OnPostRender ( time );
@ -440,50 +461,49 @@ void CGUIEnvironment::OnPostRender( u32 time )
void CGUIEnvironment::updateHoveredElement(core::position2d<s32> mousePos)
{
IGUIElement* lastHovered = Hovered;
IGUIElement* lastHoveredNoSubelement = HoveredNoSubelement;
LastHoveredMousePos = mousePos;
Hovered = getElementFromPoint(mousePos);
if (Hovered)
if ( ToolTip.Element && Hovered == ToolTip.Element )
{
u32 now = os::Timer::getTime();
// When the mouse is over the ToolTip we remove that so it will be re-created at a new position.
// Note that ToolTip.EnterTime does not get changed here, so it will be re-created at once.
ToolTip.Element->remove();
ToolTip.Element->drop();
ToolTip.Element = 0;
if (Hovered != this)
Hovered->grab();
// Get the real Hovered
Hovered = getElementFromPoint(mousePos);
}
if (Hovered != lastHovered)
// for tooltips we want the element itself and not some of it's subelements
HoveredNoSubelement = Hovered;
while ( HoveredNoSubelement && HoveredNoSubelement->isSubElement() )
{
HoveredNoSubelement = HoveredNoSubelement->getParent();
}
if (Hovered && Hovered != this)
Hovered->grab();
if ( HoveredNoSubelement && HoveredNoSubelement != this)
HoveredNoSubelement->grab();
if (Hovered != lastHovered)
{
SEvent event;
event.EventType = EET_GUI_EVENT;
if (lastHovered)
{
SEvent event;
event.EventType = EET_GUI_EVENT;
if (lastHovered)
{
event.GUIEvent.Caller = lastHovered;
event.GUIEvent.EventType = EGET_ELEMENT_LEFT;
lastHovered->OnEvent(event);
}
if (ToolTip.Element)
{
ToolTip.Element->remove();
ToolTip.Element->drop();
ToolTip.Element = 0;
ToolTip.LastTime += 500;
}
else
{
// boost tooltip generation for relaunch
if ( now - ToolTip.LastTime < ToolTip.LastTime )
{
ToolTip.LastTime += 500;
}
else
{
ToolTip.LastTime = now;
}
}
event.GUIEvent.Caller = lastHovered;
event.GUIEvent.EventType = EGET_ELEMENT_LEFT;
lastHovered->OnEvent(event);
}
if ( Hovered )
{
event.GUIEvent.Caller = Hovered;
event.GUIEvent.Element = Hovered;
event.GUIEvent.EventType = EGET_ELEMENT_HOVERED;
@ -491,8 +511,26 @@ void CGUIEnvironment::updateHoveredElement(core::position2d<s32> mousePos)
}
}
if ( lastHoveredNoSubelement != HoveredNoSubelement )
{
if (ToolTip.Element)
{
ToolTip.Element->remove();
ToolTip.Element->drop();
ToolTip.Element = 0;
}
if ( HoveredNoSubelement )
{
u32 now = os::Timer::getTime();
ToolTip.EnterTime = now;
}
}
if (lastHovered && lastHovered != this)
lastHovered->drop();
if (lastHoveredNoSubelement && lastHoveredNoSubelement != this)
lastHoveredNoSubelement->drop();
}

View File

@ -282,7 +282,9 @@ private:
{
IGUIStaticText* Element;
u32 LastTime;
u32 EnterTime;
u32 LaunchTime;
u32 RelaunchTime;
};
SToolTip ToolTip;
@ -293,6 +295,7 @@ private:
core::array<SSpriteBank> Banks;
video::IVideoDriver* Driver;
IGUIElement* Hovered;
IGUIElement* HoveredNoSubelement; // subelements replaced by their parent, so you only have 'real' elements here
IGUIElement* Focus;
core::position2d<s32> LastHoveredMousePos;
IGUISkin* CurrentSkin;

View File

@ -194,6 +194,7 @@ bool CGUIFileOpenDialog::OnEvent(const SEvent& event)
FileDirectory = L"";
FileName = FileList->getFullFileName(selected);
}
return true;
}
}
break;
@ -213,8 +214,8 @@ bool CGUIFileOpenDialog::OnEvent(const SEvent& event)
else
{
FileName = FileList->getFullFileName(selected);
return true;
}
return true;
}
}
break;

View File

@ -36,7 +36,7 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
IGUISkin* skin = Environment->getSkin();
const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE);
ScrollBar = new CGUIScrollBar(false, Environment, this, 0,
ScrollBar = new CGUIScrollBar(false, Environment, this, -1,
core::rect<s32>(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()),
!clip);
ScrollBar->setSubElement(true);
@ -450,6 +450,8 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
recalculateScrollPos();
gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED;
selectTime = now;
// post the news
if (Parent && !onlyHover)
{
@ -457,10 +459,9 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
event.EventType = EET_GUI_EVENT;
event.GUIEvent.Caller = this;
event.GUIEvent.Element = 0;
event.GUIEvent.EventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED;
event.GUIEvent.EventType = eventType;
Parent->OnEvent(event);
}
selectTime = now;
}

View File

@ -76,7 +76,7 @@ namespace gui
//! skin through getIcon
virtual void setSpriteBank(IGUISpriteBank* bank);
//! sets if automatic scrolling is enabled or not. Default is true.
//! set whether the listbox should scroll to newly selected items
virtual void setAutoScrollEnabled(bool scroll);
//! returns true if automatic scrolling is enabled, false if not.

View File

@ -122,7 +122,7 @@ void CGUIMessageBox::refreshControls()
core::rect<s32> staticRect;
staticRect.UpperLeftCorner.X = borderWidth;
staticRect.UpperLeftCorner.Y = titleHeight + borderWidth;
staticRect.LowerRightCorner.X = staticRect.UpperLeftCorner.X + skin->getSize(EGDS_MESSAGE_BOX_MAX_TEST_WIDTH);
staticRect.LowerRightCorner.X = staticRect.UpperLeftCorner.X + skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH);
staticRect.LowerRightCorner.Y = staticRect.UpperLeftCorner.Y + skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT);
if (!StaticText)
{
@ -321,6 +321,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
{
if (OkButton && event.KeyInput.Key == KEY_RETURN)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK;
Parent->OnEvent(outevent);
remove();
@ -329,6 +331,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
else
if ((CancelButton || CloseButton) && event.KeyInput.Key == KEY_ESCAPE)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL;
Parent->OnEvent(outevent);
remove();
@ -337,6 +341,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
else
if (YesButton && event.KeyInput.Key == KEY_KEY_Y)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES;
Parent->OnEvent(outevent);
remove();
@ -345,6 +351,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
else
if (NoButton && event.KeyInput.Key == KEY_KEY_N)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO;
Parent->OnEvent(outevent);
remove();
@ -357,6 +365,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
{
if (event.GUIEvent.Caller == OkButton)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK;
Parent->OnEvent(outevent);
remove();
@ -366,6 +376,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
if (event.GUIEvent.Caller == CancelButton ||
event.GUIEvent.Caller == CloseButton)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL;
Parent->OnEvent(outevent);
remove();
@ -374,6 +386,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
else
if (event.GUIEvent.Caller == YesButton)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES;
Parent->OnEvent(outevent);
remove();
@ -382,6 +396,8 @@ bool CGUIMessageBox::OnEvent(const SEvent& event)
else
if (event.GUIEvent.Caller == NoButton)
{
setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
Environment->setFocus(0);
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO;
Parent->OnEvent(outevent);
remove();

View File

@ -31,7 +31,7 @@ CGUIModalScreen::CGUIModalScreen(IGUIEnvironment* environment, IGUIElement* pare
bool CGUIModalScreen::canTakeFocus(IGUIElement* target) const
{
return (target && (target == this // this element can take it
return (target && ((const IGUIElement*)target == this // this element can take it
|| isMyChild(target) // own childs also
|| (target->getType() == EGUIET_MODAL_SCREEN )// other modals also fine
|| (target->getParent() && target->getParent()->getType() == EGUIET_MODAL_SCREEN ))) // childs of other modals will do

View File

@ -141,11 +141,11 @@ bool CGUIScrollBar::OnEvent(const SEvent& event)
{
case EMIE_MOUSE_WHEEL:
if (Environment->hasFocus(this))
{
{
// thanks to a bug report by REAPER
// thanks to tommi by tommi for another bugfix
// everybody needs a little thanking. hallo niko!;-)
setPos( getPos() +
setPos( getPos() +
( (s32)event.MouseInput.Wheel * SmallStep * (Horizontal ? 1 : -1 ) )
);
@ -205,7 +205,7 @@ bool CGUIScrollBar::OnEvent(const SEvent& event)
return isInside;
}
}
if (DraggedBySlider)
{
setPos(newPos);
@ -407,7 +407,7 @@ void CGUIScrollBar::setMax(s32 max)
setPos(Pos);
}
//! gets the maximum value of the scrollbar.
//! gets the minimum value of the scrollbar.
s32 CGUIScrollBar::getMin() const
{
return Min;

View File

@ -47,7 +47,7 @@ namespace gui
virtual s32 getMin() const;
//! sets the minimum value of the scrollbar.
virtual void setMin(s32 max);
virtual void setMin(s32 min);
//! gets the small step value
virtual s32 getSmallStep() const;

View File

@ -105,7 +105,7 @@ CGUISkin::CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver)
Sizes[EGDS_MESSAGE_BOX_GAP_SPACE] = 15;
Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH] = 0;
Sizes[EGDS_MESSAGE_BOX_MAX_TEST_WIDTH] = 500;
Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH] = 500;
Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT] = 0;
Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT] = 99999;
@ -452,19 +452,11 @@ void CGUISkin::draw3DSunkenPane(IGUIElement* element, video::SColor bgcolor,
//! draws a window background
/** Used for drawing the background of dialogs and windows.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param titleBarColor: Title color.
\param drawTitleBar: True to enable title drawing.
\param rect: Defining area where to draw.
\param clip: Clip area.
\return Returns rect where to draw title bar text. */
// return where to draw title bar text.
core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
bool drawTitleBar, video::SColor titleBarColor,
const core::rect<s32>& r,
const core::rect<s32>* cl,
const core::rect<s32>* clip,
core::rect<s32>* checkClientArea)
{
if (!Driver)
@ -482,7 +474,7 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
if ( !checkClientArea )
{
Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, cl);
Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
}
// left border
@ -490,7 +482,7 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
if ( !checkClientArea )
{
Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, cl);
Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
}
// right border dark outer line
@ -500,7 +492,7 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
if ( !checkClientArea )
{
Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, cl);
Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
}
// right border bright innner line
@ -510,7 +502,7 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
rect.LowerRightCorner.Y -= 1;
if ( !checkClientArea )
{
Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, cl);
Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
}
// bottom border dark outer line
@ -520,7 +512,7 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
rect.LowerRightCorner.X = r.LowerRightCorner.X;
if ( !checkClientArea )
{
Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, cl);
Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
}
// bottom border bright inner line
@ -530,7 +522,7 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
rect.LowerRightCorner.Y -= 1;
if ( !checkClientArea )
{
Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, cl);
Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
}
// client area for background
@ -548,20 +540,20 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
{
if (!UseGradient)
{
Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, cl);
Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip);
}
else if ( Type == EGST_BURNING_SKIN )
{
const video::SColor c1 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.9f );
const video::SColor c2 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.8f );
Driver->draw2DRectangle(rect, c1, c1, c2, c2, cl);
Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
}
else
{
const video::SColor c2 = getColor(EGDC_3D_SHADOW);
const video::SColor c1 = getColor(EGDC_3D_FACE);
Driver->draw2DRectangle(rect, c1, c1, c1, c2, cl);
Driver->draw2DRectangle(rect, c1, c1, c1, c2, clip);
}
}
@ -582,17 +574,17 @@ core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
{
// draw title bar
//if (!UseGradient)
// Driver->draw2DRectangle(titleBarColor, rect, cl);
// Driver->draw2DRectangle(titleBarColor, rect, clip);
//else
if ( Type == EGST_BURNING_SKIN )
{
const video::SColor c = titleBarColor.getInterpolated( 0xffffffff, 0.8f);
Driver->draw2DRectangle(rect, titleBarColor, titleBarColor, c, c, cl);
Driver->draw2DRectangle(rect, titleBarColor, titleBarColor, c, c, clip);
}
else
{
const video::SColor c = titleBarColor.getInterpolated(video::SColor(255,0,0,0), 0.2f);
Driver->draw2DRectangle(rect, titleBarColor, c, titleBarColor, c, cl);
Driver->draw2DRectangle(rect, titleBarColor, c, titleBarColor, c, clip);
}
}
}

View File

@ -178,7 +178,7 @@ bool CGUIWindow::OnEvent(const SEvent& event)
Dragging = false;
return true;
case EMIE_MOUSE_MOVED:
if ( !event.MouseInput.isLeftPressed() )
if (!event.MouseInput.isLeftPressed())
Dragging = false;
if (Dragging)
@ -219,7 +219,7 @@ void CGUIWindow::updateAbsolutePosition()
//! draws the element and its children
void CGUIWindow::draw()
{
if ( IsVisible )
if (IsVisible)
{
IGUISkin* skin = Environment->getSkin();
@ -229,27 +229,27 @@ void CGUIWindow::draw()
core::rect<s32> rect = AbsoluteRect;
// draw body fast
if ( DrawBackground )
{
rect = skin->draw3DWindowBackground(this, DrawTitlebar,
skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
AbsoluteRect, &AbsoluteClippingRect);
if (DrawBackground)
{
rect = skin->draw3DWindowBackground(this, DrawTitlebar,
skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
AbsoluteRect, &AbsoluteClippingRect);
if (DrawTitlebar && Text.size())
{
rect.UpperLeftCorner.X += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_X);
rect.UpperLeftCorner.Y += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_Y);
rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
if (DrawTitlebar && Text.size())
{
rect.UpperLeftCorner.X += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_X);
rect.UpperLeftCorner.Y += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_Y);
rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
IGUIFont* font = skin->getFont(EGDF_WINDOW);
if (font)
{
font->draw(Text.c_str(), rect,
skin->getColor(IsActive ? EGDC_ACTIVE_CAPTION:EGDC_INACTIVE_CAPTION),
false, true, &AbsoluteClippingRect);
}
}
}
IGUIFont* font = skin->getFont(EGDF_WINDOW);
if (font)
{
font->draw(Text.c_str(), rect,
skin->getColor(IsActive ? EGDC_ACTIVE_CAPTION:EGDC_INACTIVE_CAPTION),
false, true, &AbsoluteClippingRect);
}
}
}
}
IGUIElement::draw();
@ -276,12 +276,14 @@ IGUIButton* CGUIWindow::getMaximizeButton() const
return RestoreButton;
}
//! Returns true if the window is draggable, false if not
bool CGUIWindow::isDraggable() const
{
return IsDraggable;
}
//! Sets whether the window is draggable
void CGUIWindow::setDraggable(bool draggable)
{
@ -291,30 +293,35 @@ void CGUIWindow::setDraggable(bool draggable)
Dragging = false;
}
//! Set if the window background will be drawn
void CGUIWindow::setDrawBackground(bool draw)
{
DrawBackground = draw;
DrawBackground = draw;
}
//! Get if the window background will be drawn
bool CGUIWindow::getDrawBackground() const
{
return DrawBackground;
return DrawBackground;
}
//! Set if the window titlebar will be drawn
void CGUIWindow::setDrawTitlebar(bool draw)
{
DrawTitlebar = draw;
DrawTitlebar = draw;
}
//! Get if the window titlebar will be drawn
bool CGUIWindow::getDrawTitlebar() const
{
return DrawTitlebar;
return DrawTitlebar;
}
void CGUIWindow::updateClientRect()
{
if (! DrawBackground )
@ -323,58 +330,60 @@ void CGUIWindow::updateClientRect()
return;
}
IGUISkin* skin = Environment->getSkin();
skin->draw3DWindowBackground(this,
DrawTitlebar,
skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
AbsoluteRect, &AbsoluteClippingRect, &ClientRect);
skin->draw3DWindowBackground(this, DrawTitlebar,
skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
AbsoluteRect, &AbsoluteClippingRect, &ClientRect);
ClientRect -= AbsoluteRect.UpperLeftCorner;
}
//! Returns the rectangle of the drawable area (without border, without titlebar and without scrollbars)
core::rect<s32> CGUIWindow::getClientRect() const
{
return ClientRect;
}
//! Writes attributes of the element.
void CGUIWindow::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
{
IGUIWindow::serializeAttributes(out,options);
out->addBool("IsDraggable", IsDraggable);
out->addBool("DrawBackground", DrawBackground);
out->addBool("DrawTitlebar", DrawTitlebar);
out->addBool("IsDraggable", IsDraggable);
out->addBool("DrawBackground", DrawBackground);
out->addBool("DrawTitlebar", DrawTitlebar);
// Currently we can't just serialize attributes of sub-elements.
// To do this we either
// a) allow further serialization after attribute serialiation (second function, callback or event)
// b) add an IGUIElement attribute
// c) extend the attribute system to allow attributes to have sub-attributes
// We just serialize the most important info for now until we can do one of the above solutions.
out->addBool("IsCloseVisible", CloseButton->isVisible());
out->addBool("IsMinVisible", MinButton->isVisible());
out->addBool("IsRestoreVisible", RestoreButton->isVisible());
// Currently we can't just serialize attributes of sub-elements.
// To do this we either
// a) allow further serialization after attribute serialiation (second function, callback or event)
// b) add an IGUIElement attribute
// c) extend the attribute system to allow attributes to have sub-attributes
// We just serialize the most important info for now until we can do one of the above solutions.
out->addBool("IsCloseVisible", CloseButton->isVisible());
out->addBool("IsMinVisible", MinButton->isVisible());
out->addBool("IsRestoreVisible", RestoreButton->isVisible());
}
//! Reads attributes of the element
void CGUIWindow::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
{
IGUIWindow::deserializeAttributes(in,options);
IGUIWindow::deserializeAttributes(in,options);
Dragging = false;
Dragging = false;
IsActive = false;
IsDraggable = in->getAttributeAsBool("IsDraggable");
DrawBackground = in->getAttributeAsBool("DrawBackground");
DrawTitlebar = in->getAttributeAsBool("DrawTitlebar");
IsDraggable = in->getAttributeAsBool("IsDraggable");
DrawBackground = in->getAttributeAsBool("DrawBackground");
DrawTitlebar = in->getAttributeAsBool("DrawTitlebar");
CloseButton->setVisible( in->getAttributeAsBool("IsCloseVisible") );
MinButton->setVisible( in->getAttributeAsBool("IsMinVisible") );
RestoreButton->setVisible( in->getAttributeAsBool("IsRestoreVisible") );
CloseButton->setVisible(in->getAttributeAsBool("IsCloseVisible"));
MinButton->setVisible(in->getAttributeAsBool("IsMinVisible"));
RestoreButton->setVisible(in->getAttributeAsBool("IsRestoreVisible"));
updateClientRect();
updateClientRect();
}
} // end namespace gui
} // end namespace irr

View File

@ -265,7 +265,7 @@ IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture,
{
c8 textureName[64];
// create texture for this block
video::IImage* img = new video::CImage(texture->getColorFormat(), texture->getDimension());
video::IImage* img = new video::CImage(texture->getColorFormat(), core::dimension2d<u32>(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y)));
texture->copyTo(img, core::position2di(0,0), core::recti(
core::position2d<s32>(core::floor32(processed.X*thRel.X), core::floor32(processed.Y*thRel.Y)),
core::dimension2d<u32>(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y))), 0);
@ -329,11 +329,13 @@ IMesh* CGeometryCreator::createArrowMesh(const u32 tesselationCylinder,
for (u32 j=0; j<buffer->getVertexCount(); ++j)
buffer->getPosition(j).Y += cylinderHeight;
buffer->setDirty(EBT_VERTEX);
buffer->recalculateBoundingBox();
mesh->addMeshBuffer(buffer);
}
mesh2->drop();
mesh->setHardwareMappingHint(EHM_STATIC);
mesh->recalculateBoundingBox();
return mesh;
}

View File

@ -249,13 +249,16 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
else if (bestMode!=-1 &&
modes[i]->hdisplay >= Width &&
modes[i]->vdisplay >= Height &&
modes[i]->hdisplay < modes[bestMode]->hdisplay &&
modes[i]->vdisplay < modes[bestMode]->vdisplay)
modes[i]->hdisplay <= modes[bestMode]->hdisplay &&
modes[i]->vdisplay <= modes[bestMode]->vdisplay)
bestMode = i;
}
if (bestMode != -1)
{
os::Printer::log("Starting fullscreen mode...", ELL_INFORMATION);
os::Printer::log("Starting vidmode fullscreen mode...", ELL_INFORMATION);
os::Printer::log("hdisplay: ", core::stringc(modes[bestMode]->hdisplay).c_str(), ELL_INFORMATION);
os::Printer::log("vdisplay: ", core::stringc(modes[bestMode]->vdisplay).c_str(), ELL_INFORMATION);
XF86VidModeSwitchToMode(display, screennr, modes[bestMode]);
XF86VidModeSetViewPort(display, screennr, 0, 0);
UseXVidMode=true;
@ -283,12 +286,16 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
else if (bestMode!=-1 &&
(u32)modes[i].width >= Width &&
(u32)modes[i].height >= Height &&
modes[i].width < modes[bestMode].width &&
modes[i].height < modes[bestMode].height)
modes[i].width <= modes[bestMode].width &&
modes[i].height <= modes[bestMode].height)
bestMode = i;
}
if (bestMode != -1)
{
os::Printer::log("Starting randr fullscreen mode...", ELL_INFORMATION);
os::Printer::log("width: ", core::stringc(modes[bestMode].width).c_str(), ELL_INFORMATION);
os::Printer::log("height: ", core::stringc(modes[bestMode].height).c_str(), ELL_INFORMATION);
XRRSetScreenConfig(display,config,DefaultRootWindow(display),bestMode,oldRandrRotation,CurrentTime);
UseXRandR=true;
}
@ -1016,6 +1023,7 @@ bool CIrrDeviceLinux::run()
irrevent.KeyInput.Key = (EKEY_CODE)KeyMap[idx].Win32Key;
else
{
// Usually you will check keysymdef.h and add the corresponding key to createKeyMap.
irrevent.KeyInput.Key = (EKEY_CODE)0;
os::Printer::log("Could not find win32 key for x11 key.", core::stringc((int)mp.X11Key).c_str(), ELL_WARNING);
}
@ -1143,10 +1151,13 @@ void CIrrDeviceLinux::setWindowCaption(const wchar_t* text)
return;
XTextProperty txt;
XwcTextListToTextProperty(display, const_cast<wchar_t**>(&text), 1, XStdICCTextStyle, &txt);
XSetWMName(display, window, &txt);
XSetWMIconName(display, window, &txt);
XFree(txt.value);
if (Success==XwcTextListToTextProperty(display, const_cast<wchar_t**>(&text),
1, XStdICCTextStyle, &txt))
{
XSetWMName(display, window, &txt);
XSetWMIconName(display, window, &txt);
XFree(txt.value);
}
#endif
}
@ -1250,7 +1261,7 @@ video::ECOLOR_FORMAT CIrrDeviceLinux::getColorFormat() const
void CIrrDeviceLinux::setResizable(bool resize)
{
#ifdef _IRR_COMPILE_WITH_X11_
if (CreationParams.DriverType == video::EDT_NULL)
if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen )
return;
XUnmapWindow(display, window);
@ -1390,6 +1401,7 @@ void CIrrDeviceLinux::createKeyMap()
KeyMap.reallocate(84);
KeyMap.push_back(SKeyMap(XK_BackSpace, KEY_BACK));
KeyMap.push_back(SKeyMap(XK_Tab, KEY_TAB));
KeyMap.push_back(SKeyMap(XK_ISO_Left_Tab, KEY_TAB));
KeyMap.push_back(SKeyMap(XK_Linefeed, 0)); // ???
KeyMap.push_back(SKeyMap(XK_Clear, KEY_CLEAR));
KeyMap.push_back(SKeyMap(XK_Return, KEY_RETURN));

View File

@ -45,7 +45,7 @@ namespace irr
}
} // end namespace irr
// Get the codepage from the locale language id
// Get the codepage from the locale language id
// Based on the table from http://www.science.co.il/Language/Locale-Codes.asp?s=decimal
static unsigned int LocaleIdToCodepage(unsigned int lcid)
{
@ -203,7 +203,7 @@ static unsigned int LocaleIdToCodepage(unsigned int lcid)
return 1258;
}
return 65001; // utf-8
}
}
namespace
{
@ -215,7 +215,7 @@ namespace
irr::core::list<SEnvMapper> EnvMap;
HKL KEYBOARD_INPUT_HKL=0;
unsigned int KEYBOARD_INPUT_CODEPAGE = 1252;
unsigned int KEYBOARD_INPUT_CODEPAGE = 1252;
};
SEnvMapper* getEnvMapperFromHWnd(HWND hWnd)
@ -417,7 +417,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
sizeof(keyChars),
(WCHAR*)&unicodeChar,
1 );
event.KeyInput.Char = unicodeChar;
event.KeyInput.Char = unicodeChar;
}
else
event.KeyInput.Char = 0;
@ -452,8 +452,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_SYSCOMMAND:
// prevent screensaver or monitor powersave mode from starting
if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
(wParam & 0xFFF0) == SC_MONITORPOWER)
(wParam & 0xFFF0) == SC_MONITORPOWER ||
(wParam & 0xFFF0) == SC_KEYMENU
)
return 0;
break;
case WM_ACTIVATE:
@ -490,7 +493,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
// get the new codepage used for keyboard input
KEYBOARD_INPUT_HKL = GetKeyboardLayout(0);
KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) );
return 0;
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
@ -588,7 +591,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE);
// make sure everything gets updated to the real sizes
Resized = true;
Resized = true;
}
else if (CreationParams.WindowId)
{
@ -629,8 +632,8 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
SetForegroundWindow(HWnd);
// get the codepage used for keyboard input
KEYBOARD_INPUT_HKL = GetKeyboardLayout(0);
KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) );
KEYBOARD_INPUT_HKL = GetKeyboardLayout(0);
KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) );
}
@ -927,7 +930,13 @@ void CIrrDeviceWin32::closeDevice()
PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
PostQuitMessage(0);
PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
DestroyWindow(HWnd);
if (!ExternalWindow)
{
DestroyWindow(HWnd);
const fschar_t* ClassName = __TEXT("CIrrDeviceWin32");
HINSTANCE hInstance = GetModuleHandle(0);
UnregisterClass(ClassName, hInstance);
}
Close=true;
}
@ -1057,132 +1066,215 @@ video::IVideoModeList* CIrrDeviceWin32::getVideoModeList()
return &VideoModeList;
}
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
// Needed for old windows apis
#define PRODUCT_ULTIMATE 0x00000001
#define PRODUCT_HOME_BASIC 0x00000002
#define PRODUCT_HOME_PREMIUM 0x00000003
#define PRODUCT_ENTERPRISE 0x00000004
#define PRODUCT_HOME_BASIC_N 0x00000005
#define PRODUCT_BUSINESS 0x00000006
#define PRODUCT_STARTER 0x0000000B
#define PRODUCT_BUSINESS_N 0x00000010
#define PRODUCT_HOME_PREMIUM_N 0x0000001A
#define PRODUCT_ENTERPRISE_N 0x0000001B
#define PRODUCT_ULTIMATE_N 0x0000001C
#define PRODUCT_STARTER_N 0x0000002F
#define PRODUCT_PROFESSIONAL 0x00000030
#define PRODUCT_PROFESSIONAL_N 0x00000031
#define PRODUCT_STARTER_E 0x00000042
#define PRODUCT_HOME_BASIC_E 0x00000043
#define PRODUCT_HOME_PREMIUM_E 0x00000044
#define PRODUCT_PROFESSIONAL_E 0x00000045
#define PRODUCT_ENTERPRISE_E 0x00000046
#define PRODUCT_ULTIMATE_E 0x00000047
void CIrrDeviceWin32::getWindowsVersion(core::stringc& out)
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
OSVERSIONINFOEX osvi;
PGPI pGPI;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);
if (!bOsVersionInfoEx)
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (! GetVersionEx((OSVERSIONINFO *) &osvi))
return;
}
bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);
if (!bOsVersionInfoEx)
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (! GetVersionEx((OSVERSIONINFO *) &osvi))
return;
}
switch (osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
if (osvi.dwMajorVersion <= 4)
out.append("Microsoft Windows NT ");
else
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
out.append("Microsoft Windows 2000 ");
else
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
out.append("Microsoft Windows XP ");
else
if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
out.append("Microsoft Windows Vista ");
switch (osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
if (osvi.dwMajorVersion <= 4)
out.append("Microsoft Windows NT ");
else
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
out.append("Microsoft Windows 2000 ");
else
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
out.append("Microsoft Windows XP ");
else
if (osvi.dwMajorVersion == 6 )
{
if (osvi.dwMinorVersion == 0)
{
if (osvi.wProductType == VER_NT_WORKSTATION)
out.append("Microsoft Windows Vista ");
else
out.append("Microsoft Windows Server 2008 ");
}
else if (osvi.dwMinorVersion == 1)
{
if (osvi.wProductType == VER_NT_WORKSTATION)
out.append("Microsoft Windows 7 ");
else
out.append("Microsoft Windows Server 2008 R2 ");
}
}
if (bOsVersionInfoEx)
{
#ifdef VER_SUITE_ENTERPRISE
if (osvi.wProductType == VER_NT_WORKSTATION)
{
if (bOsVersionInfoEx)
{
if (osvi.dwMajorVersion == 6)
{
DWORD dwType;
pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
switch (dwType)
{
case PRODUCT_ULTIMATE:
case PRODUCT_ULTIMATE_E:
case PRODUCT_ULTIMATE_N:
out.append("Ultimate Edition ");
break;
case PRODUCT_PROFESSIONAL:
case PRODUCT_PROFESSIONAL_E:
case PRODUCT_PROFESSIONAL_N:
out.append("Professional Edition ");
break;
case PRODUCT_HOME_BASIC:
case PRODUCT_HOME_BASIC_E:
case PRODUCT_HOME_BASIC_N:
out.append("Home Basic Edition ");
break;
case PRODUCT_HOME_PREMIUM:
case PRODUCT_HOME_PREMIUM_E:
case PRODUCT_HOME_PREMIUM_N:
out.append("Home Premium Edition ");
break;
case PRODUCT_ENTERPRISE:
case PRODUCT_ENTERPRISE_E:
case PRODUCT_ENTERPRISE_N:
out.append("Enterprise Edition ");
break;
case PRODUCT_BUSINESS:
case PRODUCT_BUSINESS_N:
out.append("Business Edition ");
break;
case PRODUCT_STARTER:
case PRODUCT_STARTER_E:
case PRODUCT_STARTER_N:
out.append("Starter Edition ");
break;
}
}
#ifdef VER_SUITE_ENTERPRISE
else
if (osvi.wProductType == VER_NT_WORKSTATION)
{
#ifndef __BORLANDC__
if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
out.append("Personal ");
else
out.append("Professional ");
if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
out.append("Personal ");
else
out.append("Professional ");
#endif
}
else if (osvi.wProductType == VER_NT_SERVER)
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
out.append("DataCenter Server ");
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
out.append("Advanced Server ");
else
out.append("Server ");
}
#endif
}
else
{
HKEY hKey;
char szProductType[80];
DWORD dwBufLen;
}
else if (osvi.wProductType == VER_NT_SERVER)
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
out.append("DataCenter Server ");
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
out.append("Advanced Server ");
else
out.append("Server ");
}
#endif
}
else
{
HKEY hKey;
char szProductType[80];
DWORD dwBufLen;
RegOpenKeyEx( HKEY_LOCAL_MACHINE,
__TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"),
0, KEY_QUERY_VALUE, &hKey );
RegQueryValueEx( hKey, __TEXT("ProductType"), NULL, NULL,
(LPBYTE) szProductType, &dwBufLen);
RegCloseKey( hKey );
RegOpenKeyEx( HKEY_LOCAL_MACHINE,
__TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"),
0, KEY_QUERY_VALUE, &hKey );
RegQueryValueEx( hKey, __TEXT("ProductType"), NULL, NULL,
(LPBYTE) szProductType, &dwBufLen);
RegCloseKey( hKey );
if (_strcmpi( "WINNT", szProductType) == 0 )
out.append("Professional ");
if (_strcmpi( "LANMANNT", szProductType) == 0)
out.append("Server ");
if (_strcmpi( "SERVERNT", szProductType) == 0)
out.append("Advanced Server ");
}
if (_strcmpi( "WINNT", szProductType) == 0 )
out.append("Professional ");
if (_strcmpi( "LANMANNT", szProductType) == 0)
out.append("Server ");
if (_strcmpi( "SERVERNT", szProductType) == 0)
out.append("Advanced Server ");
}
// Display version, service pack (if any), and build number.
// Display version, service pack (if any), and build number.
char tmp[255];
char tmp[255];
if (osvi.dwMajorVersion <= 4 )
{
sprintf(tmp, "version %ld.%ld %s (Build %ld)",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
}
else
{
sprintf(tmp, "%s (Build %ld)", osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
}
if (osvi.dwMajorVersion <= 4 )
{
sprintf(tmp, "version %ld.%ld %s (Build %ld)",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
}
else
{
sprintf(tmp, "%s (Build %ld)", osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
}
out.append(tmp);
break;
out.append(tmp);
break;
case VER_PLATFORM_WIN32_WINDOWS:
case VER_PLATFORM_WIN32_WINDOWS:
IsNonNTWindows = true;
IsNonNTWindows = true;
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
{
out.append("Microsoft Windows 95 ");
if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
out.append("OSR2 " );
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
{
out.append("Microsoft Windows 95 ");
if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
out.append("OSR2 " );
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
{
out.append("Microsoft Windows 98 ");
if ( osvi.szCSDVersion[1] == 'A' )
out.append( "SE " );
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
{
out.append("Microsoft Windows 98 ");
if ( osvi.szCSDVersion[1] == 'A' )
out.append( "SE " );
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
out.append("Microsoft Windows Me ");
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
out.append("Microsoft Windows Me ");
break;
break;
case VER_PLATFORM_WIN32s:
case VER_PLATFORM_WIN32s:
IsNonNTWindows = true;
out.append("Microsoft Win32s ");
break;
}
IsNonNTWindows = true;
out.append("Microsoft Win32s ");
break;
}
}
//! Notifies the device, that it has been resized
@ -1341,7 +1433,7 @@ void CIrrDeviceWin32::pollJoysticks()
event.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
event.JoystickEvent.Joystick = (u8)joystick;
event.JoystickEvent.POV = (u16)info.dwPOV;
// set to undefined if no POV value was returned or the value
// is out of range

View File

@ -710,7 +710,13 @@ void CIrrDeviceWinCE::closeDevice()
PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
PostQuitMessage(0);
PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
DestroyWindow(HWnd);
if (!ExternalWindow)
{
DestroyWindow(HWnd);
const fschar_t* ClassName = __TEXT("CIrrDeviceWin32");
HINSTANCE hInstance = GetModuleHandle(0);
UnregisterClass(ClassName, hInstance);
}
Close=true;
}

View File

@ -183,7 +183,7 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
str += getVectorAsStringLine(vtx[j].Normal);
char tmp[12];
sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getBlue(), vtx[j].Color.getGreen());
sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getGreen(), vtx[j].Color.getBlue());
str += tmp;
str += getVectorAsStringLine(vtx[j].TCoords);
@ -203,7 +203,7 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
str += getVectorAsStringLine(vtx[j].Normal);
char tmp[12];
sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getBlue(), vtx[j].Color.getGreen());
sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getGreen(), vtx[j].Color.getBlue());
str += tmp;
str += getVectorAsStringLine(vtx[j].TCoords);
@ -225,7 +225,7 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
str += getVectorAsStringLine(vtx[j].Normal);
char tmp[12];
sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getBlue(), vtx[j].Color.getGreen());
sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getGreen(), vtx[j].Color.getBlue());
str += tmp;
str += getVectorAsStringLine(vtx[j].TCoords);

View File

@ -262,7 +262,8 @@ ISceneNode* CLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newMana
nb->LightData = LightData;
nb->BBox = BBox;
nb->drop();
if ( newParent )
nb->drop();
return nb;
}

View File

@ -359,10 +359,8 @@ bool CMD2MeshFileLoader::loadFile(io::IReadFile* file, CAnimatedMeshMD2* mesh)
delete [] triangles;
delete [] textureCoords;
// return
mesh->calculateBoundingBox();
// init buffer with start frame.
mesh->getMesh(0);
return true;
}

View File

@ -473,6 +473,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
jnt->LocalMatrix.setTranslation(
core::vector3df(pJoint->Translation[0], pJoint->Translation[1], -pJoint->Translation[2]) );
jnt->Animatedposition.set(jnt->LocalMatrix.getTranslation());
jnt->Animatedrotation.set(jnt->LocalMatrix.getRotationDegrees());
parentNames.push_back( (c8*)pJoint->ParentName );
@ -546,6 +548,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
}
core::array<MS3DVertexWeights> vertexWeights;
f32 weightFactor=0;
if ((pHeader->Version == 4) && (pPtr < buffer+fileSize))
{
@ -594,6 +597,10 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
#ifdef __BIG_ENDIAN__
subVersion = os::Byteswap::byteswap(subVersion);
#endif
if (subVersion==1)
weightFactor=1.f/255.f;
else
weightFactor=1.f/100.f;
pPtr += sizeof(s32);
#ifdef _IRR_DEBUG_MS3D_LOADER_
@ -730,7 +737,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
{
ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
sum -= (w->strength = vertexWeights[vertidx].weights[0]/100.f);
sum -= (w->strength = vertexWeights[vertidx].weights[0]*weightFactor);
w->vertex_id = index;
}
boneid = vertexWeights[vertidx].boneIds[0];
@ -738,7 +745,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
{
ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
sum -= (w->strength = vertexWeights[vertidx].weights[1]/100.f);
sum -= (w->strength = vertexWeights[vertidx].weights[1]*weightFactor);
w->vertex_id = index;
}
boneid = vertexWeights[vertidx].boneIds[1];
@ -746,7 +753,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
{
ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
sum -= (w->strength = vertexWeights[vertidx].weights[2]/100.f);
sum -= (w->strength = vertexWeights[vertidx].weights[2]*weightFactor);
w->vertex_id = index;
}
boneid = vertexWeights[vertidx].boneIds[2];

View File

@ -126,6 +126,167 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool
}
//! Recalculates tangents, requires a tangent mesh
void CMeshManipulator::recalculateTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const
{
if (!mesh || !mesh->getMeshBufferCount() || (mesh->getMeshBuffer(0)->getVertexType()!= video::EVT_TANGENTS))
return;
const u32 meshBufferCount = mesh->getMeshBufferCount();
for (u32 b=0; b<meshBufferCount; ++b)
{
IMeshBuffer* clone = mesh->getMeshBuffer(b);
const u32 vtxCnt = clone->getVertexCount();
const u32 idxCnt = clone->getIndexCount();
u16* idx = clone->getIndices();
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)clone->getVertices();
if (smooth)
{
u32 i;
for ( i = 0; i!= vtxCnt; ++i )
{
if (recalculateNormals)
v[i].Normal.set( 0.f, 0.f, 0.f );
v[i].Tangent.set( 0.f, 0.f, 0.f );
v[i].Binormal.set( 0.f, 0.f, 0.f );
}
//Each vertex gets the sum of the tangents and binormals from the faces around it
for ( i=0; i<idxCnt; i+=3)
{
// if this triangle is degenerate, skip it!
if (v[idx[i+0]].Pos == v[idx[i+1]].Pos ||
v[idx[i+0]].Pos == v[idx[i+2]].Pos ||
v[idx[i+1]].Pos == v[idx[i+2]].Pos
/*||
v[idx[i+0]].TCoords == v[idx[i+1]].TCoords ||
v[idx[i+0]].TCoords == v[idx[i+2]].TCoords ||
v[idx[i+1]].TCoords == v[idx[i+2]].TCoords */
)
continue;
//Angle-weighted normals look better, but are slightly more CPU intensive to calculate
core::vector3df weight(1.f,1.f,1.f);
if (angleWeighted)
weight = getAngleWeight(v[i+0].Pos,v[i+1].Pos,v[i+2].Pos);
core::vector3df localNormal;
core::vector3df localTangent;
core::vector3df localBinormal;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal += localNormal * weight.X;
v[idx[i+0]].Tangent += localTangent * weight.X;
v[idx[i+0]].Binormal += localBinormal * weight.X;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal += localNormal * weight.Y;
v[idx[i+1]].Tangent += localTangent * weight.Y;
v[idx[i+1]].Binormal += localBinormal * weight.Y;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal += localNormal * weight.Z;
v[idx[i+2]].Tangent += localTangent * weight.Z;
v[idx[i+2]].Binormal += localBinormal * weight.Z;
}
// Normalize the tangents and binormals
if (recalculateNormals)
{
for ( i = 0; i!= vtxCnt; ++i )
v[i].Normal.normalize();
}
for ( i = 0; i!= vtxCnt; ++i )
{
v[i].Tangent.normalize();
v[i].Binormal.normalize();
}
}
else
{
core::vector3df localNormal;
for (u32 i=0; i<idxCnt; i+=3)
{
calculateTangents(
localNormal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal=localNormal;
}
}
}
}
//! Clones a static IMesh into a modifyable SMesh.
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
{
@ -564,7 +725,7 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted, bool calculateTangents) const
{
if (!mesh)
return 0;
@ -573,221 +734,79 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
SMesh* clone = new SMesh();
const u32 meshBufferCount = mesh->getMeshBufferCount();
u32 b;
for (b=0; b<meshBufferCount; ++b)
for (u32 b=0; b<meshBufferCount; ++b)
{
const u32 idxCnt = mesh->getMeshBuffer(b)->getIndexCount();
const u16* idx = mesh->getMeshBuffer(b)->getIndices();
const IMeshBuffer* original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount();
const u16* idx = original->getIndices();
SMeshBufferTangents* buffer = new SMeshBufferTangents();
buffer->Material = mesh->getMeshBuffer(b)->getMaterial();
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt);
core::map<video::S3DVertexTangents, int> vertMap;
int vertLocation;
// copy vertices
buffer->Vertices.reallocate(idxCnt);
switch(mesh->getMeshBuffer(b)->getVertexType())
{
case video::EVT_STANDARD:
{
video::S3DVertex* v =
(video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<idxCnt; ++i)
buffer->Vertices.push_back(
video::S3DVertexTangents(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords));
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* v =
(video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<idxCnt; ++i)
buffer->Vertices.push_back(video::S3DVertexTangents(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords));
}
break;
case video::EVT_TANGENTS:
{
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<idxCnt; ++i)
buffer->Vertices.push_back(v[idx[i]]);
}
break;
}
// create new indices
buffer->Indices.set_used(idxCnt);
const video::E_VERTEX_TYPE vType = original->getVertexType();
video::S3DVertexTangents vNew;
for (u32 i=0; i<idxCnt; ++i)
buffer->Indices[i] = i;
{
switch(vType)
{
case video::EVT_STANDARD:
{
const video::S3DVertex* v =
(const video::S3DVertex*)original->getVertices();
vNew = video::S3DVertexTangents(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
}
break;
case video::EVT_2TCOORDS:
{
const video::S3DVertex2TCoords* v =
(const video::S3DVertex2TCoords*)original->getVertices();
vNew = video::S3DVertexTangents(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
}
break;
case video::EVT_TANGENTS:
{
const video::S3DVertexTangents* v =
(const video::S3DVertexTangents*)original->getVertices();
vNew = v[idx[i]];
}
break;
}
core::map<video::S3DVertexTangents, int>::Node* n = vertMap.find(vNew);
if (n)
{
vertLocation = n->getValue();
}
else
{
vertLocation = buffer->Vertices.size();
buffer->Vertices.push_back(vNew);
vertMap.insert(vNew, vertLocation);
}
//buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox());
buffer->recalculateBoundingBox ();
// create new indices
buffer->Indices[i] = vertLocation;
}
buffer->recalculateBoundingBox();
// add new buffer
clone->addMeshBuffer(buffer);
buffer->drop();
}
clone->recalculateBoundingBox ();
//clone->BoundingBox = mesh->getBoundingBox();
// now calculate tangents
for (b=0; b<meshBufferCount; ++b)
{
const u32 vtxCnt = mesh->getMeshBuffer(b)->getVertexCount();
const u32 idxCnt = clone->getMeshBuffer(b)->getIndexCount();
u16* idx = clone->getMeshBuffer(b)->getIndices();
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)clone->getMeshBuffer(b)->getVertices();
if (smooth)
{
u32 i;
for ( i = 0; i!= vtxCnt; ++i )
{
if (recalculateNormals)
v[i].Normal.set( 0.f, 0.f, 0.f );
v[i].Tangent.set( 0.f, 0.f, 0.f );
v[i].Binormal.set( 0.f, 0.f, 0.f );
}
//Each vertex gets the sum of the tangents and binormals from the faces around it
for ( i=0; i<idxCnt; i+=3)
{
// if this triangle is degenerate, skip it!
if (v[idx[i+0]].Pos == v[idx[i+1]].Pos ||
v[idx[i+0]].Pos == v[idx[i+2]].Pos ||
v[idx[i+1]].Pos == v[idx[i+2]].Pos
/*||
v[idx[i+0]].TCoords == v[idx[i+1]].TCoords ||
v[idx[i+0]].TCoords == v[idx[i+2]].TCoords ||
v[idx[i+1]].TCoords == v[idx[i+2]].TCoords */
)
continue;
//Angle-weighted normals look better, but are slightly more CPU intensive to calculate
core::vector3df weight(1.f,1.f,1.f);
if (angleWeighted)
weight = getAngleWeight(v[i+0].Pos,v[i+1].Pos,v[i+2].Pos);
core::vector3df localNormal;
core::vector3df localTangent;
core::vector3df localBinormal;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal += localNormal * weight.X;
v[idx[i+0]].Tangent += localTangent * weight.X;
v[idx[i+0]].Binormal += localBinormal * weight.X;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal += localNormal * weight.Y;
v[idx[i+1]].Tangent += localTangent * weight.Y;
v[idx[i+1]].Binormal += localBinormal * weight.Y;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal += localNormal * weight.Z;
v[idx[i+2]].Tangent += localTangent * weight.Z;
v[idx[i+2]].Binormal += localBinormal * weight.Z;
}
// Normalize the tangents and binormals
if (recalculateNormals)
{
for ( i = 0; i!= vtxCnt; ++i )
v[i].Normal.normalize();
}
for ( i = 0; i!= vtxCnt; ++i )
{
v[i].Tangent.normalize();
v[i].Binormal.normalize();
}
}
else
{
core::vector3df localNormal;
for (u32 i=0; i<idxCnt; i+=3)
{
calculateTangents(
localNormal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal=localNormal;
}
}
}
clone->recalculateBoundingBox();
if (calculateTangents)
recalculateTangents(clone, recalculateNormals, smooth, angleWeighted);
return clone;
}
@ -803,70 +822,76 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
SMesh* clone = new SMesh();
const u32 meshBufferCount = mesh->getMeshBufferCount();
u32 b;
for (b=0; b<meshBufferCount; ++b)
for (u32 b=0; b<meshBufferCount; ++b)
{
const u32 idxCnt = mesh->getMeshBuffer(b)->getIndexCount();
const u16* idx = mesh->getMeshBuffer(b)->getIndices();
const IMeshBuffer* original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount();
const u16* idx = original->getIndices();
SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->Material = mesh->getMeshBuffer(b)->getMaterial();
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt);
core::map<video::S3DVertex2TCoords, int> vertMap;
int vertLocation;
// copy vertices
buffer->Vertices.reallocate(idxCnt);
switch(mesh->getMeshBuffer(b)->getVertexType())
{
case video::EVT_STANDARD:
{
video::S3DVertex* v =
(video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<idxCnt; ++i)
buffer->Vertices.push_back(
video::S3DVertex2TCoords(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords));
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* v =
(video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<idxCnt; ++i)
buffer->Vertices.push_back(v[idx[i]]);
}
break;
case video::EVT_TANGENTS:
{
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<idxCnt; ++i)
buffer->Vertices.push_back(video::S3DVertex2TCoords(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords));
}
break;
}
// create new indices
buffer->Indices.set_used(idxCnt);
const video::E_VERTEX_TYPE vType = original->getVertexType();
video::S3DVertex2TCoords vNew;
for (u32 i=0; i<idxCnt; ++i)
buffer->Indices[i] = i;
{
switch(vType)
{
case video::EVT_STANDARD:
{
const video::S3DVertex* v =
(const video::S3DVertex*)original->getVertices();
vNew = video::S3DVertex2TCoords(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
}
break;
case video::EVT_2TCOORDS:
{
const video::S3DVertex2TCoords* v =
(const video::S3DVertex2TCoords*)original->getVertices();
vNew = v[idx[i]];
}
break;
case video::EVT_TANGENTS:
{
const video::S3DVertexTangents* v =
(const video::S3DVertexTangents*)original->getVertices();
vNew = video::S3DVertex2TCoords(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
}
break;
}
core::map<video::S3DVertex2TCoords, int>::Node* n = vertMap.find(vNew);
if (n)
{
vertLocation = n->getValue();
}
else
{
vertLocation = buffer->Vertices.size();
buffer->Vertices.push_back(vNew);
vertMap.insert(vNew, vertLocation);
}
//buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox());
buffer->recalculateBoundingBox ();
// create new indices
buffer->Indices[i] = vertLocation;
}
buffer->recalculateBoundingBox();
// add new buffer
clone->addMeshBuffer(buffer);
buffer->drop();
}
clone->recalculateBoundingBox ();
//clone->BoundingBox = mesh->getBoundingBox();
clone->recalculateBoundingBox();
return clone;
}
@ -879,9 +904,8 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
// copy mesh and fill data into SMeshBuffer
SMesh* clone = new SMesh();
const u32 meshBufferCount = mesh->getMeshBufferCount();
u32 b;
for (b=0; b<meshBufferCount; ++b)
for (u32 b=0; b<meshBufferCount; ++b)
{
const IMeshBuffer* original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount();
@ -941,9 +965,7 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
// create new indices
buffer->Indices[i] = vertLocation;
}
//buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox());
buffer->recalculateBoundingBox ();
buffer->recalculateBoundingBox();
// add new buffer
clone->addMeshBuffer(buffer);

View File

@ -51,8 +51,11 @@ public:
//! Creates a planar texture mapping on the meshbuffer
void makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const;
//! Recalculates tangents, requires a tangent mesh
virtual void recalculateTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false, bool recalculateTangents=true) const;
//! Creates a copy of the mesh, which will only consist of S3D2TCoords vertices.
virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const;

View File

@ -372,7 +372,8 @@ ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManag
nb->ReadOnlyMaterials = ReadOnlyMaterials;
nb->Materials = Materials;
nb->drop();
if ( newParent )
nb->drop();
return nb;
}

Some files were not shown because too many files have changed in this diff Show More