Merged revisions 2781:2892 from trunk.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@2893 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2009-11-20 10:08:00 +00:00
parent 9167c11177
commit 329f550b17
137 changed files with 4923 additions and 1861 deletions

View File

@ -1,3 +1,87 @@
Changes in 1.7
- Separate TextureWrap mode into U and V fields
- Add mirror texture wrap modes
- windows show now active/inactive state
- remove unneed drop/grab calls found by manik_sheeri
- fix rounding problem in IGUIElements which have EGUIA_SCALE alignments.
- MessageBox supports now automatic resizing and images.
Deprecated EGDS_MESSAGE_BOX_WIDTH and EGDS_MESSAGE_BOX_HEIGHT
- Let maya-cam animator react on a setTarget call to the camera which happened outside it's own control
- New contextmenue features:
automatic checking for checked flag.
close handling now customizable
serialization can handle incomplete xml's
setEventParent now in public interface
New function findItemWithCommandId
New function insertItem
- irrArray: Fixed issues with push_front and reallocation
Changed behavior for set_pointer and clear, when free_when_destroyed is false
- NPK (Nebula device archive) reader added, it's an uncompressed PAK-like format
- SSkinMeshBuffer::MoveTo* methods renamed to convertTo*
- Multiple Render Target (MRT) support added, including some enhanced blend features where supported
- Directory changing fixed for virtual file systems (Archives etc)
- Fix texture matrix init in scene manager and driver
- More draw2dimage support in software drivers
- Sphere node now properly chooses a good tesselation based on the parameters
- Active camera not registered twice anymore
- Parallax/normal map shader rotation bug under OpenGL fixed
- bump map handling for obj files fixed
- Fog serialization added
- New context menu features added
- Bounding Box updates for skinned meshes fixed
- The current FPS for an animated scene node cn be queried now, added some variables to serialization
- Scrollbars fixed
- Fixed 2d vertex primitive method to correctly handle transparency
- Fullscreen handling has been ehanced for Windows, now proper resolution is restored on Alt-Tab etc.
- Cameras can now be added to the scene node without automatically activating them
Clone method added
- New video driver method getMaxTextureSize
- PAK archive reader fixed
- TRANSPARENT_ALPHA_CHANNEL_REF uses modulate to enable lighting
- LIGHTMAP_ADD now always uses add operator
- Some Unicode file system fixes
- destructor of irrString not virtual anymore, please don't derive from irrString
Some new methods added, for searching and splitting
Assignment operator optimized
- new lightness method for SColor
- draw3DTriangle now renders filled polygons, old behavior can be achieved by setting EMT_WIREFRAME
----------------
Changes in 1.6.1
- Fix another (OldValue == NewValue) before drop()/grap(), this time in CTextureAttribute::setTexture.
@ -6,6 +90,7 @@ Changes in 1.6.1
- Fix ninja animation range which got messed up a little when b3d animations got fixed (thx gbox for finding)
---------------------------
Changes in 1.6 (23.09.2009)
- Added IFileSystem::createEmptyFileList, exposed IFileList::sort, addItem and added getID

View File

@ -146,7 +146,7 @@ int main()
/*
The last scene node we add to show possibilities of scene node animators is
a md2 model, which uses a 'fly straight' animator to run between to points.
a b3d model, which uses a 'fly straight' animator to run between to points.
*/
scene::IAnimatedMeshSceneNode* anms =
smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"));

View File

@ -29,7 +29,7 @@ Copyright 2006-2009 Burningwater, Thomas Alten
struct GameData
{
GameData ( const path &startupDir) :
retVal(0), createExDevice(0), Device(0), StartupDir(startupDir)
retVal(0), StartupDir(startupDir), createExDevice(0), Device(0)
{
setDefault ();
}

View File

@ -755,7 +755,11 @@ vector3df getGravity ( const c8 * surface )
Dynamically load the Irrlicht Library
*/
#if defined(_IRR_WINDOWS_API_) && 1
#if defined(_IRR_WINDOWS_API_)
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <windows.h>
funcptr_createDevice load_createDevice ( const c8 * filename)
@ -771,9 +775,6 @@ funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename)
#else
// TODO: Dynamic Loading for other os
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
funcptr_createDevice load_createDevice ( const c8 * filename)
{

View File

@ -148,11 +148,11 @@ bool CDemo::OnEvent(const SEvent& event)
device->closeDevice();
}
else
if ((event.EventType == EET_KEY_INPUT_EVENT &&
if (((event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.Key == KEY_SPACE &&
event.KeyInput.PressedDown == false) ||
(event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) &&
event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)) &&
currentScene == 3)
{
// shoot

View File

@ -90,7 +90,7 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
// add about text
wchar_t* text2 = L"This is the tech demo of the Irrlicht engine. To start, "\
const wchar_t* text2 = L"This is the tech demo of the Irrlicht engine. To start, "\
L"select a video driver which works best with your hardware and press 'Start Demo'.\n"\
L"What you currently see is displayed using the Burning Software Renderer (Thomas Alten).\n"\
L"The Irrlicht Engine was written by me, Nikolaus Gebhardt. The models, "\
@ -141,7 +141,7 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
};
const SLightParticle lightParticle[] =
{
//{LIGHT_GLOBAL,0,
//LIGHT_GLOBAL,0,
{LIGHT_RED,0},
{LIGHT_BLUE,0},
{LIGHT_RED,1},

View File

@ -91,6 +91,21 @@ namespace video
//! Supports Color masks (disabling color planes in output)
EVDF_COLOR_MASK,
//! Supports multiple render targets at once
EVDF_MULTIPLE_RENDER_TARGETS,
//! Supports separate blend settings for multiple render targets
EVDF_MRT_BLEND,
//! Supports separate color masks for multiple render targets
EVDF_MRT_COLOR_MASK,
//! Supports separate blend functions for multiple render targets
EVDF_MRT_BLEND_FUNC,
//! Supports geometry shaders
EVDF_GEOMETRY_SHADER,
//! Only used for counting the elements of this enum
EVDF_COUNT
};

View File

@ -112,7 +112,7 @@ namespace scene
virtual f32 getAspectRatio() const =0;
//! Gets the field of view of the camera.
/** \return The field of view of the camera in radiants. */
/** \return The field of view of the camera in radians. */
virtual f32 getFOV() const =0;
//! Sets the value of the near clipping plane. (default: 1.0f)
@ -128,7 +128,7 @@ namespace scene
virtual void setAspectRatio(f32 aspect) =0;
//! Sets the field of view (Default: PI / 2.5f)
/** \param fovy: New field of view in radiants. */
/** \param fovy: New field of view in radians. */
virtual void setFOV(f32 fovy) =0;
//! Get the view frustum.

View File

@ -57,7 +57,7 @@ namespace gui
//! Returns the current position of the mouse cursor.
/** \return Returns the current position of the cursor. The returned position
is the position of the mouse cursor in pixel units. */
virtual core::position2d<s32> getPosition() = 0;
virtual const core::position2d<s32>& getPosition() = 0;
//! Returns the current position of the mouse cursor.
/** \return Returns the current position of the cursor. The returned position

View File

@ -18,7 +18,7 @@ namespace io
enum EFileSystemType
{
FILESYSTEM_NATIVE = 0, // Native OS FileSystem
FILESYSTEM_VIRTUAL, // Virtual FileSystem
FILESYSTEM_VIRTUAL // Virtual FileSystem
};
//! Contains the different types of archives
@ -36,6 +36,9 @@ enum E_FILE_ARCHIVE_TYPE
//! An ID Software PAK archive
EFAT_PAK = MAKE_IRR_ID('P','A','K', 0),
//! A Nebula Device archive
EFAT_NPK = MAKE_IRR_ID('N','P','K', 0),
//! A Tape ARchive
EFAT_TAR = MAKE_IRR_ID('T','A','R', 0),

View File

@ -22,7 +22,7 @@ namespace gui
ECMC_REMOVE = 1,
//! call setVisible(false)
ECMC_HIDE = 2,
ECMC_HIDE = 2
// note to implementors - this is planned as bitset, so continue with 4 if you need to add further flags.
};

View File

@ -37,11 +37,14 @@ namespace gui
EGST_BURNING_SKIN,
//! An unknown skin, not serializable at present
EGST_UNKNOWN
EGST_UNKNOWN,
//! this value is not used, it only specifies the number of skin types
EGST_COUNT
};
//! Names for gui element types
const c8* const GUISkinTypeNames[] =
const c8* const GUISkinTypeNames[EGST_COUNT+1] =
{
"windowsClassic",
"windowsMetallic",
@ -102,7 +105,7 @@ namespace gui
};
//! Names for default skin colors
const c8* const GUISkinColorNames[] =
const c8* const GUISkinColorNames[EGDC_COUNT+1] =
{
"3DDarkShadow",
"3DShadow",
@ -173,7 +176,7 @@ namespace gui
//! Names for default skin sizes
const c8* const GUISkinSizeNames[] =
const c8* const GUISkinSizeNames[EGDS_COUNT+1] =
{
"ScrollBarSize",
"MenuHeight",
@ -220,7 +223,7 @@ namespace gui
};
//! Names for default skin sizes
const c8* const GUISkinTextNames[] =
const c8* const GUISkinTextNames[EGDT_COUNT+1] =
{
"MessageBoxOkay",
"MessageBoxCancel",
@ -287,7 +290,7 @@ namespace gui
EGDI_COUNT
};
const c8* const GUISkinIconNames[] =
const c8* const GUISkinIconNames[EGDI_COUNT+1] =
{
"windowMaximize",
"windowRestore",
@ -333,7 +336,7 @@ namespace gui
EGDF_COUNT
};
const c8* const GUISkinFontNames[] =
const c8* const GUISkinFontNames[EGDF_COUNT+1] =
{
"defaultFont",
"buttonFont",

View File

@ -176,7 +176,6 @@ namespace scene
//! flags the meshbuffer as changed, reloads hardware buffers
virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) = 0;
//to be spit into vertex and index buffers:
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
virtual u32 getChangedID_Vertex() const = 0;

View File

@ -10,15 +10,14 @@
#include "aabbox3d.h"
#include "matrix4.h"
#include "IAnimatedMesh.h"
#include "SColor.h"
#include "IMeshBuffer.h"
#include "SVertexManipulator.h"
namespace irr
{
namespace scene
{
class IMesh;
class IMeshBuffer;
struct SMesh;
//! An interface for easy manipulation of meshes.
@ -40,12 +39,18 @@ namespace scene
//! Sets the alpha vertex color value of the whole mesh to a new value.
/** \param mesh Mesh on which the operation is performed.
\param alpha New alpha value. Must be a value between 0 and 255. */
virtual void setVertexColorAlpha(IMesh* mesh, s32 alpha) const = 0;
void setVertexColorAlpha(IMesh* mesh, s32 alpha) const
{
apply(scene::SVertexColorSetAlphaManipulator(alpha), mesh);
}
//! Sets the colors of all vertices to one color
/** \param mesh Mesh on which the operation is performed.
\param color New color. */
virtual void setVertexColors(IMesh* mesh, video::SColor color) const = 0;
void setVertexColors(IMesh* mesh, video::SColor color) const
{
apply(scene::SVertexColorSetManipulator(color), mesh);
}
//! Recalculates all normals of the mesh.
/** \param mesh: Mesh on which the operation is performed.
@ -62,40 +67,58 @@ namespace scene
//! Scales the actual mesh, not a scene node.
/** \param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */
virtual void scale(IMesh* mesh, const core::vector3df& factor) const = 0;
void scale(IMesh* mesh, const core::vector3df& factor) const
{
apply(SVertexPositionScaleManipulator(factor), mesh, true);
}
//! Scales the actual meshbuffer, not a scene node.
/** \param buffer Meshbuffer on which the operation is performed.
\param factor Scale factor for each axis. */
virtual void scale(IMeshBuffer* buffer, const core::vector3df& factor) const = 0;
void scale(IMeshBuffer* buffer, const core::vector3df& factor) const
{
apply(SVertexPositionScaleManipulator(factor), buffer, true);
}
//! Scales the actual mesh, not a scene node.
/** \deprecated Use scale() instead
\param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */
virtual void scaleMesh(IMesh* mesh, const core::vector3df& factor) const {return scale(mesh,factor);}
void scaleMesh(IMesh* mesh, const core::vector3df& factor) const {return scale(mesh,factor);}
//! Scale the texture coords of a mesh.
/** \param mesh Mesh on which the operation is performed.
\param factor Vector which defines the scale for each axis.
\param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */
virtual void scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 level=1) const =0;
void scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 level=1) const
{
apply(SVertexTCoordsScaleManipulator(factor, level), mesh);
}
//! Scale the texture coords of a meshbuffer.
/** \param buffer Meshbuffer on which the operation is performed.
\param factor Vector which defines the scale for each axis.
\param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */
virtual void scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level=1) const =0;
void scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level=1) const
{
apply(SVertexTCoordsScaleManipulator(factor, level), buffer);
}
//! Applies a transformation to a mesh
/** \param mesh Mesh on which the operation is performed.
\param m transformation matrix. */
virtual void transform(IMesh* mesh, const core::matrix4& m) const = 0;
void transform(IMesh* mesh, const core::matrix4& m) const
{
apply(SVertexPositionTransformManipulator(m), mesh, true);
}
//! Applies a transformation to a meshbuffer
/** \param buffer Meshbuffer on which the operation is performed.
\param m transformation matrix. */
virtual void transform(IMeshBuffer* buffer, const core::matrix4& m) const = 0;
void transform(IMeshBuffer* buffer, const core::matrix4& m) const
{
apply(SVertexPositionTransformManipulator(m), buffer, true);
}
//! Applies a transformation to a mesh
/** \deprecated Use transform() instead
@ -205,11 +228,100 @@ namespace scene
IReferenceCounted::drop() for more information. */
virtual IAnimatedMesh * createAnimatedMesh(IMesh* mesh,
scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) const = 0;
};
//! Apply a manipulator on the Meshbuffer
/** \param func A functor defining the mesh manipulation.
\param buffer The Meshbuffer to apply the manipulator to.
\param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
\return True if the functor was successfully applied, else false. */
template <typename Functor>
bool apply(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate=false) const
{
return apply_(func, buffer, boundingBoxUpdate, func);
}
//! Apply a manipulator on the Mesh
/** \param func A functor defining the mesh manipulation.
\param mesh The Mesh to apply the manipulator to.
\param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
\return True if the functor was successfully applied, else false. */
template <typename Functor>
bool apply(const Functor& func, IMesh* mesh, bool boundingBoxUpdate=false) const
{
if (!mesh)
return true;
bool result = true;
core::aabbox3df bufferbox;
for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
{
result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate);
if (boundingBoxUpdate)
{
if (0==i)
bufferbox.reset(mesh->getBoundingBox());
else
bufferbox.addInternalBox(mesh->getBoundingBox());
}
}
if (boundingBoxUpdate)
mesh->setBoundingBox(bufferbox);
return result;
}
protected:
//! Apply a manipulator based on the type of the functor
/** \param func A functor defining the mesh manipulation.
\param buffer The Meshbuffer to apply the manipulator to.
\param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
\param typeTest Unused parameter, which handles the proper call selection based on the type of the Functor which is passed in two times.
\return True if the functor was successfully applied, else false. */
template <typename Functor>
bool apply_(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate, const IVertexManipulator& typeTest) const
{
if (!buffer)
return true;
core::aabbox3df bufferbox;
for (u32 i=0; i<buffer->getVertexCount(); ++i)
{
switch (buffer->getVertexType())
{
case video::EVT_STANDARD:
{
video::S3DVertex* verts = (video::S3DVertex*)buffer->getVertices();
func(verts[i]);
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* verts = (video::S3DVertex2TCoords*)buffer->getVertices();
func(verts[i]);
}
break;
case video::EVT_TANGENTS:
{
video::S3DVertexTangents* verts = (video::S3DVertexTangents*)buffer->getVertices();
func(verts[i]);
}
break;
}
if (boundingBoxUpdate)
{
if (0==i)
bufferbox.reset(buffer->getPosition(0));
else
bufferbox.addInternalPoint(buffer->getPosition(i));
}
}
if (boundingBoxUpdate)
buffer->setBoundingBox(bufferbox);
return true;
}
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -416,8 +416,10 @@ namespace scene
//! Adds a sphere scene node of the given radius and detail
/** \param radius: Radius of the sphere.
\param polyCount: Polycount of the sphere, i.e. subdivision in
horizontal and vertical direction.
\param polyCount: The number of vertices in horizontal and
vertical direction. The total polyCount of the sphere is
polyCount*polyCount. This parameter must be less than 256 to
stay within the 16-bit limit of the indices of a meshbuffer.
\param parent: Parent of the scene node. Can be 0 if no parent.
\param id: Id of the node. This id can be used to identify the scene node.
\param position: Position of the space relative to its parent

View File

@ -24,6 +24,11 @@ namespace scene
{
class ISceneManager;
//! Typedef for list of scene nodes
typedef core::list<ISceneNode*> ISceneNodeList;
//! Typedef for list of scene node animators
typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList;
//! Scene node interface.
/** A scene node is a node in the hierarchical scene graph. Every scene
node may have children, which are also scene nodes. Children move
@ -60,7 +65,7 @@ namespace scene
removeAll();
// delete all animators
core::list<ISceneNodeAnimator*>::Iterator ait = Animators.begin();
ISceneNodeAnimatorList::Iterator ait = Animators.begin();
for (; ait != Animators.end(); ++ait)
(*ait)->drop();
@ -87,7 +92,7 @@ namespace scene
{
if (IsVisible)
{
core::list<ISceneNode*>::Iterator it = Children.begin();
ISceneNodeList::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnRegisterSceneNode();
}
@ -106,7 +111,7 @@ namespace scene
{
// animate this node with all animators
core::list<ISceneNodeAnimator*>::Iterator ait = Animators.begin();
ISceneNodeAnimatorList::Iterator ait = Animators.begin();
while (ait != Animators.end())
{
// continue to the next node before calling animateNode()
@ -122,7 +127,7 @@ namespace scene
// perform the post render process on all children
core::list<ISceneNode*>::Iterator it = Children.begin();
ISceneNodeList::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnAnimate(timeMs);
}
@ -289,7 +294,7 @@ namespace scene
e.g. because it couldn't be found in the children list. */
virtual bool removeChild(ISceneNode* child)
{
core::list<ISceneNode*>::Iterator it = Children.begin();
ISceneNodeList::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
if ((*it) == child)
{
@ -307,7 +312,7 @@ namespace scene
//! Removes all children of this scene node
virtual void removeAll()
{
core::list<ISceneNode*>::Iterator it = Children.begin();
ISceneNodeList::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
{
(*it)->Parent = 0;
@ -350,7 +355,7 @@ namespace scene
/** \param animator A pointer to the animator to be deleted. */
virtual void removeAnimator(ISceneNodeAnimator* animator)
{
core::list<ISceneNodeAnimator*>::Iterator it = Animators.begin();
ISceneNodeAnimatorList::Iterator it = Animators.begin();
for (; it != Animators.end(); ++it)
if ((*it) == animator)
{
@ -364,7 +369,7 @@ namespace scene
//! Removes all animators from this scene node.
virtual void removeAnimators()
{
core::list<ISceneNodeAnimator*>::Iterator it = Animators.begin();
ISceneNodeAnimatorList::Iterator it = Animators.begin();
for (; it != Animators.end(); ++it)
(*it)->drop();
@ -744,13 +749,13 @@ namespace scene
// clone children
core::list<ISceneNode*>::Iterator it = toCopyFrom->Children.begin();
ISceneNodeList::Iterator it = toCopyFrom->Children.begin();
for (; it != toCopyFrom->Children.end(); ++it)
(*it)->clone(this, newManager);
// clone animators
core::list<ISceneNodeAnimator*>::Iterator ait = toCopyFrom->Animators.begin();
ISceneNodeAnimatorList::Iterator ait = toCopyFrom->Animators.begin();
for (; ait != toCopyFrom->Animators.end(); ++ait)
{
ISceneNodeAnimator* anim = (*ait)->createClone(this, SceneManager);
@ -768,7 +773,7 @@ namespace scene
{
SceneManager = newManager;
core::list<ISceneNode*>::Iterator it = Children.begin();
ISceneNodeList::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->setSceneManager(newManager);
}
@ -819,6 +824,7 @@ namespace scene
bool IsDebugObject;
};
} // end namespace scene
} // end namespace irr

View File

@ -62,7 +62,7 @@ enum E_TEXTURE_CREATION_FLAG
ETCF_NO_ALPHA_CHANNEL = 0x00000020,
//! Allow the Driver to use Non-Power-2-Textures
/** BurningVideo can handle Non-Power-2 Textures in 2D (GUI), but not it 3D. */
/** BurningVideo can handle Non-Power-2 Textures in 2D (GUI), but not in 3D. */
ETCF_ALLOW_NON_POWER_2 = 0x00000040,
/** This flag is never used, it only forces the compiler to compile
@ -71,23 +71,6 @@ enum E_TEXTURE_CREATION_FLAG
};
//! Helper function, helps to get the desired texture creation format from the flags.
/** \return Either ETCF_ALWAYS_32_BIT, ETCF_ALWAYS_16_BIT,
ETCF_OPTIMIZED_FOR_QUALITY, or ETCF_OPTIMIZED_FOR_SPEED. */
inline E_TEXTURE_CREATION_FLAG getTextureFormatFromFlags(u32 flags)
{
if (flags & ETCF_OPTIMIZED_FOR_SPEED)
return ETCF_OPTIMIZED_FOR_SPEED;
if (flags & ETCF_ALWAYS_16_BIT)
return ETCF_ALWAYS_16_BIT;
if (flags & ETCF_ALWAYS_32_BIT)
return ETCF_ALWAYS_32_BIT;
if (flags & ETCF_OPTIMIZED_FOR_QUALITY)
return ETCF_OPTIMIZED_FOR_QUALITY;
return ETCF_OPTIMIZED_FOR_SPEED;
}
//! Interface of a Video Driver dependent Texture.
/** An ITexture is created by an IVideoDriver by using IVideoDriver::addTexture
or IVideoDriver::getTexture. After that, the texture may only be used by this
@ -126,12 +109,11 @@ public:
//! Get original size of the texture.
/** The texture is usually scaled, if it was created with an unoptimal
size. For example if the size of the texture file it was loaded from
was not a power of two. This returns the size of the texture, it had
before it was scaled. Can be useful when drawing 2d images on the
screen, which should have the exact size of the original texture. Use
ITexture::getSize() if you want to know the real size it has now stored
in the system.
size. For example if the size was not a power of two. This method
returns the size of the texture it had before it was scaled. Can be
useful when drawing 2d images on the screen, which should have the
exact size of the original texture. Use ITexture::getSize() if you want
to know the real size it has now stored in the system.
\return The original size of the texture. */
virtual const core::dimension2d<u32>& getOriginalSize() const = 0;
@ -178,6 +160,22 @@ public:
protected:
//! Helper function, helps to get the desired texture creation format from the flags.
/** \return Either ETCF_ALWAYS_32_BIT, ETCF_ALWAYS_16_BIT,
ETCF_OPTIMIZED_FOR_QUALITY, or ETCF_OPTIMIZED_FOR_SPEED. */
inline E_TEXTURE_CREATION_FLAG getTextureFormatFromFlags(u32 flags)
{
if (flags & ETCF_OPTIMIZED_FOR_SPEED)
return ETCF_OPTIMIZED_FOR_SPEED;
if (flags & ETCF_ALWAYS_16_BIT)
return ETCF_ALWAYS_16_BIT;
if (flags & ETCF_ALWAYS_32_BIT)
return ETCF_ALWAYS_32_BIT;
if (flags & ETCF_OPTIMIZED_FOR_QUALITY)
return ETCF_OPTIMIZED_FOR_QUALITY;
return ETCF_OPTIMIZED_FOR_SPEED;
}
io::path Name;
};

View File

@ -60,8 +60,8 @@ public:
an IMetaTriangleSelector) this this function may be called multiple
times to retrieve all triangles.
Please note that unoptimized triangle selectors also may return
triangles which are not in the specified box at all.
This method will return at least the triangles that intersect the box,
but may return other triangles as well.
\param triangles: Array where the resulting triangles will be written
to.
\param arraySize: Size of the target array.

View File

@ -104,10 +104,10 @@ namespace video
{
//! Render target is the main color frame buffer
ERT_FRAME_BUFFER=0,
//! Render target is the main color frame buffer
ERT_STEREO_LEFT_BUFFER=0,
//! Render target is a render texture
ERT_RENDER_TEXTURE,
//! Render target is the main color frame buffer
ERT_STEREO_LEFT_BUFFER,
//! Render target is the right color buffer (left is the main buffer)
ERT_STEREO_RIGHT_BUFFER,
//! Render to both stereo buffers at once
@ -185,7 +185,10 @@ namespace video
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;
case EMF_TEXTURE_WRAP: material.TextureLayer[0].TextureWrap = Material.TextureLayer[0].TextureWrap; break;
case EMF_TEXTURE_WRAP:
material.TextureLayer[0].TextureWrapU = Material.TextureLayer[0].TextureWrapU;
material.TextureLayer[0].TextureWrapV = Material.TextureLayer[0].TextureWrapV;
break;
}
}
}
@ -194,6 +197,34 @@ namespace video
};
struct IRenderTarget
{
IRenderTarget(ITexture* texture,
E_COLOR_PLANE colorMask=ECP_ALL,
E_BLEND_FACTOR blendFuncSrc=EBF_ONE,
E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA,
bool blendEnable=false) :
RenderTexture(texture),
TargetType(ERT_RENDER_TEXTURE), ColorMask(colorMask),
BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst),
BlendEnable(blendEnable) {}
IRenderTarget(E_RENDER_TARGET target,
E_COLOR_PLANE colorMask=ECP_ALL,
E_BLEND_FACTOR blendFuncSrc=EBF_ONE,
E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA,
bool blendEnable=false) :
RenderTexture(0),
TargetType(target), ColorMask(colorMask),
BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst),
BlendEnable(blendEnable) {}
ITexture* RenderTexture;
E_RENDER_TARGET TargetType:8;
E_COLOR_PLANE ColorMask:8;
E_BLEND_FACTOR BlendFuncSrc:4;
E_BLEND_FACTOR BlendFuncDst:4;
bool BlendEnable;
};
//! Interface to driver which is able to perform 2d and 3d graphics functions.
/** This interface is one of the most important interfaces of
the Irrlicht Engine: All rendering and texture manipulation is done with
@ -490,6 +521,11 @@ namespace video
bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0)) =0;
//! Sets new multiple render targets.
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0)) =0;
//! Sets a new viewport.
/** Every rendering operation is done into this new area.
\param area: Rectangle defining the new area of rendering

View File

@ -7,12 +7,12 @@
//! Irrlicht SDK Version
#define IRRLICHT_VERSION_MAJOR 1
#define IRRLICHT_VERSION_MINOR 6
#define IRRLICHT_VERSION_REVISION 0
#define IRRLICHT_VERSION_MINOR 7
#define IRRLICHT_VERSION_REVISION 0-alpha
// This flag will be defined only in SVN, the official release code will have
// it undefined
//#define IRRLICHT_VERSION_SVN
#define IRRLICHT_SDK_VERSION "1.6"
#define IRRLICHT_VERSION_SVN
#define IRRLICHT_SDK_VERSION "1.7.0-alpha"
#include <stdio.h> // TODO: Although included elsewhere this is required at least for mingw
@ -126,7 +126,7 @@ headers, e.g. Summer 2004. This is a Microsoft issue, not an Irrlicht one.
#if defined(_IRR_WINDOWS_API_) && (!defined(__GNUC__) || defined(IRR_COMPILE_WITH_DX9_DEV_PACK))
//! Only define _IRR_COMPILE_WITH_DIRECT3D_8_ if you have an appropriate DXSDK, e.g. Summer 2004
#define _IRR_COMPILE_WITH_DIRECT3D_8_
//#define _IRR_COMPILE_WITH_DIRECT3D_8_
#define _IRR_COMPILE_WITH_DIRECT3D_9_
#endif
@ -295,6 +295,8 @@ B3D, MS3D or X meshes */
#define _IRR_COMPILE_WITH_MS3D_LOADER_
//! Define _IRR_COMPILE_WITH_X_LOADER_ if you want to use Microsoft X files
#define _IRR_COMPILE_WITH_X_LOADER_
//! Define _IRR_COMPILE_WITH_OGRE_LOADER_ if you want to load Ogre 3D files
#define _IRR_COMPILE_WITH_OGRE_LOADER_
#endif
//! Define _IRR_COMPILE_WITH_IRR_MESH_LOADER_ if you want to load Irrlicht Engine .irrmesh files
@ -323,8 +325,6 @@ B3D, MS3D or X meshes */
#define _IRR_COMPILE_WITH_OBJ_LOADER_
//! Define _IRR_COMPILE_WITH_OCT_LOADER_ if you want to load FSRad OCT files
#define _IRR_COMPILE_WITH_OCT_LOADER_
//! Define _IRR_COMPILE_WITH_OGRE_LOADER_ if you want to load Ogre 3D files
#define _IRR_COMPILE_WITH_OGRE_LOADER_
//! Define _IRR_COMPILE_WITH_LWO_LOADER_ if you want to load Lightwave3D files
#define _IRR_COMPILE_WITH_LWO_LOADER_
//! Define _IRR_COMPILE_WITH_STL_LOADER_ if you want to load stereolithography files
@ -384,6 +384,8 @@ B3D, MS3D or X meshes */
#define __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_
//! Define __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ if you want to open ID software PAK archives
#define __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_
//! Define __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ if you want to open Nebula Device NPK archives
#define __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
//! Define __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ if you want to open TAR archives
#define __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_

View File

@ -477,7 +477,10 @@ namespace video
case EMF_TEXTURE_WRAP:
{
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
TextureLayer[i].TextureWrap = (E_TEXTURE_CLAMP)value;
{
TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)value;
TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)value;
}
}
break;
case EMF_ANTI_ALIASING:
@ -528,10 +531,14 @@ namespace video
case EMF_NORMALIZE_NORMALS:
return NormalizeNormals;
case EMF_TEXTURE_WRAP:
return !(TextureLayer[0].TextureWrap ||
TextureLayer[1].TextureWrap ||
TextureLayer[2].TextureWrap ||
TextureLayer[3].TextureWrap);
return !(TextureLayer[0].TextureWrapU ||
TextureLayer[0].TextureWrapV ||
TextureLayer[1].TextureWrapU ||
TextureLayer[1].TextureWrapV ||
TextureLayer[2].TextureWrapU ||
TextureLayer[2].TextureWrapV ||
TextureLayer[3].TextureWrapU ||
TextureLayer[3].TextureWrapV);
case EMF_ANTI_ALIASING:
return (AntiAliasing==1);
case EMF_COLOR_MASK:

View File

@ -26,14 +26,23 @@ namespace video
//! Texture is clamped to the border pixel (if exists)
ETC_CLAMP_TO_BORDER,
//! Texture is alternatingly mirrored (0..1..0..1..0..)
ETC_MIRROR
ETC_MIRROR,
//! Texture is mirrored once and then clamped (0..1..0)
ETC_MIRROR_CLAMP,
//! Texture is mirrored once and then clamped to edge
ETC_MIRROR_CLAMP_TO_EDGE,
//! Texture is mirrored once and then clamped to border
ETC_MIRROR_CLAMP_TO_BORDER
};
static const char* const aTextureClampNames[] = {
"texture_clamp_repeat",
"texture_clamp_clamp",
"texture_clamp_clamp_to_edge",
"texture_clamp_clamp_to_border",
"texture_clamp_mirror", 0};
"texture_clamp_mirror",
"texture_clamp_mirror_clamp",
"texture_clamp_mirror_clamp_to_edge",
"texture_clamp_mirror_clamp_to_border", 0};
//! Struct for holding material parameters which exist per texture layer
class SMaterialLayer
@ -42,7 +51,8 @@ namespace video
//! Default constructor
SMaterialLayer()
: Texture(0),
TextureWrap(ETC_REPEAT),
TextureWrapU(ETC_REPEAT),
TextureWrapV(ETC_REPEAT),
BilinearFilter(true),
TrilinearFilter(false),
AnisotropicFilter(0),
@ -97,7 +107,8 @@ namespace video
else
TextureMatrix = 0;
}
TextureWrap = other.TextureWrap;
TextureWrapU = other.TextureWrapU;
TextureWrapV = other.TextureWrapV;
BilinearFilter = other.BilinearFilter;
TrilinearFilter = other.TrilinearFilter;
AnisotropicFilter = other.AnisotropicFilter;
@ -106,36 +117,6 @@ namespace video
return *this;
}
//! Texture
ITexture* Texture;
//! Texture Clamp Mode
u8 TextureWrap;
//! Is bilinear filtering enabled? Default: true
bool BilinearFilter:1;
//! Is trilinear filtering enabled? Default: false
/** If the trilinear filter flag is enabled,
the bilinear filtering flag is ignored. */
bool TrilinearFilter:1;
//! Is anisotropic filtering enabled? Default: 0, disabled
/** In Irrlicht you can use anisotropic texture filtering
in conjunction with bilinear or trilinear texture
filtering to improve rendering results. Primitives
will look less blurry with this flag switched on. The number gives
the maximal anisotropy degree, and is often in the range 2-16.
Value 1 is equivalent to 0, but should be avoided. */
u8 AnisotropicFilter;
//! Bias for the mipmap choosing decision.
/** This value can make the textures more or less blurry than with the
default value of 0. The value (divided by 8.f) is added to the mipmap level
chosen initially, and thus takes a smaller mipmap for a region
if the value is positive. */
s8 LODBias;
//! Gets the texture transformation matrix
/** \return Texture matrix of this layer. */
core::matrix4& getTextureMatrix()
@ -178,7 +159,8 @@ namespace video
{
bool different =
Texture != b.Texture ||
TextureWrap != b.TextureWrap ||
TextureWrapU != b.TextureWrapU ||
TextureWrapV != b.TextureWrapV ||
BilinearFilter != b.BilinearFilter ||
TrilinearFilter != b.TrilinearFilter ||
AnisotropicFilter != b.AnisotropicFilter ||
@ -198,6 +180,38 @@ namespace video
inline bool operator==(const SMaterialLayer& b) const
{ return !(b!=*this); }
//! Texture
ITexture* Texture;
//! Texture Clamp Mode
/** Values are tkane from E_TEXTURE_CLAMP. */
u8 TextureWrapU:4;
u8 TextureWrapV:4;
//! Is bilinear filtering enabled? Default: true
bool BilinearFilter:1;
//! Is trilinear filtering enabled? Default: false
/** If the trilinear filter flag is enabled,
the bilinear filtering flag is ignored. */
bool TrilinearFilter:1;
//! Is anisotropic filtering enabled? Default: 0, disabled
/** In Irrlicht you can use anisotropic texture filtering
in conjunction with bilinear or trilinear texture
filtering to improve rendering results. Primitives
will look less blurry with this flag switched on. The number gives
the maximal anisotropy degree, and is often in the range 2-16.
Value 1 is equivalent to 0, but should be avoided. */
u8 AnisotropicFilter;
//! Bias for the mipmap choosing decision.
/** This value can make the textures more or less blurry than with the
default value of 0. The value (divided by 8.f) is added to the mipmap level
chosen initially, and thus takes a smaller mipmap for a region
if the value is positive. */
s8 LODBias;
private:
friend class SMaterial;
irr::core::irrAllocator<irr::core::matrix4> MatrixAllocator;

View File

@ -187,7 +187,7 @@ struct SSkinMeshBuffer : public IMeshBuffer
}
//! Convert to 2tcoords vertex type
virtual void MoveTo_2TCoords()
virtual void convertTo2TCoords()
{
if (VertexType==video::EVT_STANDARD)
{
@ -206,7 +206,7 @@ struct SSkinMeshBuffer : public IMeshBuffer
}
//! Convert to tangents vertex type
virtual void MoveTo_Tangents()
virtual void convertToTangents()
{
if (VertexType==video::EVT_STANDARD)
{

View File

@ -0,0 +1,292 @@
// Copyright (C) 2009 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __S_VERTEX_MANIPULATOR_H_INCLUDED__
#define __S_VERTEX_MANIPULATOR_H_INCLUDED__
#include "S3DVertex.h"
#include "SColor.h"
namespace irr
{
namespace scene
{
class IMesh;
class IMeshBuffer;
struct SMesh;
//! Interface for vertex manipulators.
/** You should derive your manipulator from this class if it shall be called for every vertex, getting as parameter just the vertex.
*/
struct IVertexManipulator
{
};
//! Vertex manipulator to set color to a fixed color for all vertices
class SVertexColorSetManipulator : public IVertexManipulator
{
public:
SVertexColorSetManipulator(video::SColor color) : Color(color) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color=Color;
}
private:
video::SColor Color;
};
//! Vertex manipulator to set the alpha value of the vertex color to a fixed value
class SVertexColorSetAlphaManipulator : public IVertexManipulator
{
public:
SVertexColorSetAlphaManipulator(u32 alpha) : Alpha(alpha) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color.setAlpha(Alpha);
}
private:
u32 Alpha;
};
//! Vertex manipulator which invertes the RGB values
class SVertexColorInvertManipulator : public IVertexManipulator
{
public:
void operator()(video::S3DVertex& vertex) const
{
vertex.Color.setRed(255-vertex.Color.getRed());
vertex.Color.setGreen(255-vertex.Color.getGreen());
vertex.Color.setBlue(255-vertex.Color.getBlue());
}
};
//! Vertex manipulator to set vertex color to one of two values depending on a given threshold
/** If average of the color value is >Threshold the High color is chosen, else Low. */
class SVertexColorThresholdManipulator : public IVertexManipulator
{
public:
SVertexColorThresholdManipulator(u8 threshold, video::SColor low,
video::SColor high) : Threshold(threshold), Low(low), High(high) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color = (vertex.Color.getAverage()>Threshold)?High:Low;
}
private:
u8 Threshold;
video::SColor Low;
video::SColor High;
};
//! Vertex manipulator which adjusts the brightness by the given amount
/** A positive value increases brightness, a negative value darkens the colors. */
class SVertexColorBrightnessManipulator : public IVertexManipulator
{
public:
SVertexColorBrightnessManipulator(s32 amount) : Amount(amount) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color.setRed(core::clamp(vertex.Color.getRed()+Amount, 0u, 255u));
vertex.Color.setGreen(core::clamp(vertex.Color.getGreen()+Amount, 0u, 255u));
vertex.Color.setBlue(core::clamp(vertex.Color.getBlue()+Amount, 0u, 255u));
}
private:
s32 Amount;
};
//! Vertex manipulator which adjusts the contrast by the given factor
/** Factors over 1 increase contrast, below 1 reduce it. */
class SVertexColorContrastManipulator : public IVertexManipulator
{
public:
SVertexColorContrastManipulator(f32 factor) : Factor(factor) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color.setRed(core::clamp(core::round32((vertex.Color.getRed()-128)*Factor)+128, 0, 255));
vertex.Color.setGreen(core::clamp(core::round32((vertex.Color.getGreen()-128)*Factor)+128, 0, 255));
vertex.Color.setBlue(core::clamp(core::round32((vertex.Color.getBlue()-128)*Factor)+128, 0, 255));
}
private:
f32 Factor;
};
//! Vertex manipulator which adjusts the contrast by the given factor and brightness by a signed amount.
/** Factors over 1 increase contrast, below 1 reduce it.
A positive amount increases brightness, a negative one darkens the colors. */
class SVertexColorContrastBrightnessManipulator : public IVertexManipulator
{
public:
SVertexColorContrastBrightnessManipulator(f32 factor, s32 amount) : Factor(factor), Amount(amount+128) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color.setRed(core::clamp(core::round32((vertex.Color.getRed()-128)*Factor)+Amount, 0, 255));
vertex.Color.setGreen(core::clamp(core::round32((vertex.Color.getGreen()-128)*Factor)+Amount, 0, 255));
vertex.Color.setBlue(core::clamp(core::round32((vertex.Color.getBlue()-128)*Factor)+Amount, 0, 255));
}
private:
f32 Factor;
s32 Amount;
};
//! Vertex manipulator which adjusts the brightness by a gamma operation
/** A value over one increases brightness, one below darkens the colors. */
class SVertexColorGammaManipulator : public IVertexManipulator
{
public:
SVertexColorGammaManipulator(f32 gamma) : Gamma(1.f)
{
if (gamma != 0.f)
Gamma = 1.f/gamma;
}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color.setRed(core::clamp(core::round32(powf((f32)(vertex.Color.getRed()),Gamma)), 0, 255));
vertex.Color.setGreen(core::clamp(core::round32(powf((f32)(vertex.Color.getGreen()),Gamma)), 0, 255));
vertex.Color.setBlue(core::clamp(core::round32(powf((f32)(vertex.Color.getBlue()),Gamma)), 0, 255));
}
private:
f32 Gamma;
};
//! Vertex manipulator which scales the color values
/** Can e.g be used for white balance, factor would be 255.f/brightest color. */
class SVertexColorScaleManipulator : public IVertexManipulator
{
public:
SVertexColorScaleManipulator(f32 factor) : Factor(factor) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color.setRed(core::clamp(core::round32(vertex.Color.getRed()*Factor), 0, 255));
vertex.Color.setGreen(core::clamp(core::round32(vertex.Color.getGreen()*Factor), 0, 255));
vertex.Color.setBlue(core::clamp(core::round32(vertex.Color.getBlue()*Factor), 0, 255));
}
private:
f32 Factor;
};
//! Vertex manipulator which desaturates the color values
/** Uses the lightness value of the color. */
class SVertexColorDesaturateToLightnessManipulator : public IVertexManipulator
{
public:
void operator()(video::S3DVertex& vertex) const
{
vertex.Color=core::round32(vertex.Color.getLightness());
}
};
//! Vertex manipulator which desaturates the color values
/** Uses the average value of the color. */
class SVertexColorDesaturateToAverageManipulator : public IVertexManipulator
{
public:
void operator()(video::S3DVertex& vertex) const
{
vertex.Color=vertex.Color.getAverage();
}
};
//! Vertex manipulator which desaturates the color values
/** Uses the luminance value of the color. */
class SVertexColorDesaturateToLuminanceManipulator : public IVertexManipulator
{
public:
void operator()(video::S3DVertex& vertex) const
{
vertex.Color=core::round32(vertex.Color.getLuminance());
}
};
//! Vertex manipulator which interpolates the color values
/** Uses linear interpolation. */
class SVertexColorInterpolateLinearManipulator : public IVertexManipulator
{
public:
SVertexColorInterpolateLinearManipulator(video::SColor color, f32 factor) :
Color(color), Factor(factor) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color=vertex.Color.getInterpolated(Color, Factor);
}
private:
video::SColor Color;
f32 Factor;
};
//! Vertex manipulator which interpolates the color values
/** Uses linear interpolation. */
class SVertexColorInterpolateQuadraticManipulator : public IVertexManipulator
{
public:
SVertexColorInterpolateQuadraticManipulator(video::SColor color1, video::SColor color2, f32 factor) :
Color1(color1), Color2(color2), Factor(factor) {}
void operator()(video::S3DVertex& vertex) const
{
vertex.Color=vertex.Color.getInterpolated_quadratic(Color1, Color2, Factor);
}
private:
video::SColor Color1;
video::SColor Color2;
f32 Factor;
};
//! Vertex manipulator which scales the position of the vertex
class SVertexPositionScaleManipulator : public IVertexManipulator
{
public:
SVertexPositionScaleManipulator(const core::vector3df& factor) : Factor(factor) {}
template <typename VType>
void operator()(VType& vertex) const
{
vertex.Pos *= Factor;
}
private:
core::vector3df Factor;
};
//! Vertex manipulator which scales the position of the vertex along the normals
/** This can look more pleasing than the usual Scale operator, but
depends on the mesh geometry.
*/
class SVertexPositionScaleAlongNormalsManipulator : public IVertexManipulator
{
public:
SVertexPositionScaleAlongNormalsManipulator(const core::vector3df& factor) : Factor(factor) {}
template <typename VType>
void operator()(VType& vertex) const
{
vertex.Pos += vertex.Normal*Factor;
}
private:
core::vector3df Factor;
};
//! Vertex manipulator which transforms the position of the vertex
class SVertexPositionTransformManipulator : public IVertexManipulator
{
public:
SVertexPositionTransformManipulator(const core::matrix4& m) : Transformation(m) {}
template <typename VType>
void operator()(VType& vertex) const
{
Transformation.transformVect(vertex.Pos);
}
private:
core::matrix4 Transformation;
};
//! Vertex manipulator which scales the TCoords of the vertex
class SVertexTCoordsScaleManipulator : public IVertexManipulator
{
public:
SVertexTCoordsScaleManipulator(const core::vector2df& factor, u32 uvSet=1) : Factor(factor), UVSet(uvSet) {}
void operator()(video::S3DVertex2TCoords& vertex) const
{
if (1==UVSet)
vertex.TCoords *= Factor;
else if (2==UVSet)
vertex.TCoords2 *= Factor;
}
template <typename VType>
void operator()(VType& vertex) const
{
if (1==UVSet)
vertex.TCoords *= Factor;
}
private:
core::vector2df Factor;
u32 UVSet;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -113,7 +113,7 @@ enum eAllocStrategy
{
ALLOC_STRATEGY_SAFE = 0,
ALLOC_STRATEGY_DOUBLE = 1,
ALLOC_STRATEGY_SQRT = 2,
ALLOC_STRATEGY_SQRT = 2
};

View File

@ -30,6 +30,7 @@ public:
{
}
//! Constructs an array and allocates an initial chunk of memory.
/** \param start_count Amount of elements to pre-allocate. */
array(u32 start_count)
@ -41,26 +42,18 @@ public:
//! Copy constructor
array(const array<T>& other)
: data(0)
array(const array<T>& other) : data(0)
{
*this = other;
}
//! Destructor.
/** Frees allocated memory, if set_free_when_destroyed was not set to
false by the user before. */
~array()
{
if (free_when_destroyed)
{
for (u32 i=0; i<used; ++i)
allocator.destruct(&data[i]);
allocator.deallocate(data);
}
clear();
}
@ -102,48 +95,13 @@ public:
strategy = newStrategy;
}
//! Adds an element at back of array.
/** If the array is too small to add this new element it is made bigger.
\param element: Element to add at the back of the array. */
void push_back(const T& element)
{
if (used + 1 > allocated)
{
// this doesn't work if the element is in the same array. So
// we'll copy the element first to be sure we'll get no data
// corruption
T e(element);
//reallocate(used * 2 +1); // increase data block
// TA: okt, 2008. it's only allowed to alloc one element, if
// default constructor has to be called
// increase data block
u32 newAlloc;
switch ( strategy )
{
case ALLOC_STRATEGY_DOUBLE:
newAlloc = used + 1 + (allocated < 500 ?
(allocated < 5 ? 5 : used) : used >> 2);
break;
default:
case ALLOC_STRATEGY_SAFE:
newAlloc = used + 1;
break;
}
reallocate( newAlloc);
// construct new element
// Attention!. in missing default constructors for faster alloc methods
allocator.construct(&data[used++], e); // data[used++] = e; // push_back
}
else
{
//data[used++] = element;
// instead of using this here, we copy it the safe way:
allocator.construct(&data[used++], element);
}
is_sorted = false;
insert(element, used);
}
@ -169,18 +127,56 @@ public:
_IRR_DEBUG_BREAK_IF(index>used) // access violation
if (used + 1 > allocated)
reallocate(used +1);
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
// this doesn't work if the element is in the same
// array. So we'll copy the element first to be sure
// we'll get no data corruption
const T e(element);
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], element); // data[index] = element;
// increase data block
u32 newAlloc;
switch ( strategy )
{
case ALLOC_STRATEGY_DOUBLE:
newAlloc = used + 1 + (allocated < 500 ?
(allocated < 5 ? 5 : used) : used >> 2);
break;
default:
case ALLOC_STRATEGY_SAFE:
newAlloc = used + 1;
break;
}
reallocate( newAlloc);
// move array content and construct new element
// first move end one up
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
// then add new element
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], e); // data[index] = e;
}
else
{
// move array content and construct new element
// first move end one up
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
// then add new element
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], element); // data[index] = element;
}
// set to false as we don't know if we have the comparison operators
is_sorted = false;
++used;
}
@ -189,10 +185,13 @@ public:
//! Clears the array and deletes all allocated memory.
void clear()
{
for (u32 i=0; i<used; ++i)
allocator.destruct(&data[i]);
if (free_when_destroyed)
{
for (u32 i=0; i<used; ++i)
allocator.destruct(&data[i]);
allocator.deallocate(data); // delete [] data;
allocator.deallocate(data); // delete [] data;
}
data = 0;
used = 0;
allocated = 0;
@ -201,23 +200,32 @@ public:
//! Sets pointer to new array, using this as new workspace.
/** \param newPointer: Pointer to new array of elements.
\param size: Size of the new array. */
void set_pointer(T* newPointer, u32 size)
/** Make sure that set_free_when_destroyed is used properly.
\param newPointer: Pointer to new array of elements.
\param size: Size of the new array.
\param _is_sorted Flag which tells whether the new array is already
sorted.
\param _free_when_destroyed Sets whether the new memory area shall be
freed by the array upon destruction, or if this will be up to the user
application. */
void set_pointer(T* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
{
for (u32 i=0; i<used; ++i)
allocator.destruct(&data[i]);
allocator.deallocate(data); // delete [] data;
clear();
data = newPointer;
allocated = size;
used = size;
is_sorted = false;
is_sorted = _is_sorted;
free_when_destroyed=_free_when_destroyed;
}
//! Sets if the array should delete the memory it uses upon destruction.
/** \param f If true, the array frees the allocated memory in its
/** Also clear and set_pointer will only delete the (original) memory
area if this flag is set to true, which is also the default. The
methods reallocate, set_used, push_back, push_front, insert, and erase
will still try to deallocate the original memory, which might cause
troubles depending on the intended use of the memory area.
\param f If true, the array frees the allocated memory in its
destructor, otherwise not. The default is true. */
void set_free_when_destroyed(bool f)
{
@ -244,12 +252,7 @@ public:
strategy = other.strategy;
if (data)
{
for (u32 i=0; i<used; ++i)
allocator.destruct(&data[i]);
allocator.deallocate(data); // delete [] data;
}
clear();
//if (allocated < other.allocated)
if (other.allocated == 0)
@ -258,7 +261,7 @@ public:
data = allocator.allocate(other.allocated); // new T[other.allocated];
used = other.used;
free_when_destroyed = other.free_when_destroyed;
free_when_destroyed = true;
is_sorted = other.is_sorted;
allocated = other.allocated;
@ -279,6 +282,7 @@ public:
return true;
}
//! Inequality operator
bool operator != (const array<T>& other) const
{
@ -368,10 +372,8 @@ public:
O(n*log n) in worst case. */
void sort()
{
if (is_sorted || used<2)
return;
heapsort(data, used);
if (!is_sorted || used>1)
heapsort(data, used);
is_sorted = true;
}
@ -473,6 +475,7 @@ public:
return index;
}
//! Finds an element in linear time, which is very slow.
/** Use binary_search for faster finding. Only works if ==operator is
implemented.
@ -559,21 +562,20 @@ public:
is_sorted = _is_sorted;
}
private:
T* data;
TAlloc allocator;
u32 allocated;
u32 used;
eAllocStrategy strategy;
bool free_when_destroyed:1;
bool is_sorted:1;
private:
T* data;
u32 allocated;
u32 used;
TAlloc allocator;
eAllocStrategy strategy:4;
bool free_when_destroyed:1;
bool is_sorted:1;
};
} // end namespace core
} // end namespace irr
#endif

View File

@ -169,6 +169,10 @@ public:
//! Returns amount of elements in list.
/** \return Amount of elements in the list. */
u32 size() const
{
return Size;
}
u32 getSize() const
{
return Size;
@ -380,10 +384,10 @@ public:
private:
irrAllocator<SKListNode> allocator;
SKListNode* First;
SKListNode* Last;
u32 Size;
irrAllocator<SKListNode> allocator;
};

View File

@ -232,9 +232,13 @@ public:
if (this == &other)
return *this;
allocator.deallocate(array); // delete [] array;
allocated = used = other.size()+1;
array = allocator.allocate(used); //new T[used];
used = other.size()+1;
if (used>allocated)
{
allocator.deallocate(array); // delete [] array;
allocated = used;
array = allocator.allocate(used); //new T[used];
}
const T* p = other.c_str();
for (u32 i=0; i<used; ++i, ++p)
@ -273,24 +277,28 @@ public:
u32 len = 0;
const B* p = c;
while(*p)
do
{
++len;
++p;
}
} while(*p++);
// we'll take the old string for a while, because the new
// we'll keep the old string for a while, because the new
// string could be a part of the current string.
T* oldArray = array;
++len;
allocated = used = len;
array = allocator.allocate(used); //new T[used];
used = len;
if (used>allocated)
{
allocated = used;
array = allocator.allocate(used); //new T[used];
}
for (u32 l = 0; l<len; ++l)
array[l] = (T)c[l];
allocator.deallocate(oldArray); // delete [] oldArray;
if (oldArray != array)
allocator.deallocate(oldArray); // delete [] oldArray;
return *this;
}
@ -366,10 +374,6 @@ public:
s32 diff = array[i] - other.array[i];
if ( diff )
return diff < 0;
/*
if (array[i] != other.array[i])
return (array[i] < other.array[i]);
*/
}
return used < other.used;
@ -390,8 +394,9 @@ public:
}
//! Returns length of string
/** \return Length of the string in characters. */
//! Returns length of the string's content
/** \return Length of the string's content in characters, excluding
the trailing NUL. */
u32 size() const
{
return used-1;
@ -399,7 +404,7 @@ public:
//! Returns character string
/** \return pointer to C-style zero terminated string. */
/** \return pointer to C-style NUL terminated string. */
const T* c_str() const
{
return array;
@ -1027,6 +1032,55 @@ public:
return used > 1 ? array[used-2] : 0;
}
//! split string into parts.
/** This method will split a string at certain delimiter characters
into the container passed in as reference. The type of the container
has to be given as template parameter. It must provide a push_back and
a size method.
\param ret The result container
\param c C-style string of delimiter characters
\param count Number of delimiter characters
\param ignoreEmptyTokens Flag to avoid empty substrings in the result
container. If two delimiters occur without a character in between, an
empty substring would be placed in the result. If this flag is set,
only non-empty strings are stored.
\param keepSeparators Flag which allows to add the separator to the
result string. If this flag is true, the concatenation of the
substrings results in the original string. Otherwise, only the
characters between the delimiters are returned.
\return The number of resulting substrings
*/
template<class container>
u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
{
if (!c)
return 0;
const u32 oldSize=ret.size();
u32 lastpos = 0;
bool lastWasSeparator = false;
for (u32 i=0; i<used; ++i)
{
bool foundSeparator = false;
for (u32 j=0; j<count; ++j)
{
if (array[i] == c[j])
{
if ((!ignoreEmptyTokens || i - lastpos != 0) &&
!lastWasSeparator)
ret.push_back(string<T>(&array[lastpos], i - lastpos));
foundSeparator = true;
lastpos = (keepSeparators ? i : i + 1);
break;
}
}
lastWasSeparator = foundSeparator;
}
if ((used - 1) > lastpos)
ret.push_back(string<T>(&array[lastpos], (used - 1) - lastpos));
return ret.size()-oldSize;
}
private:
//! Reallocate the array, make it bigger or smaller
@ -1050,9 +1104,9 @@ private:
//--- member variables
T* array;
TAlloc allocator;
u32 allocated;
u32 used;
TAlloc allocator;
};

View File

@ -5,7 +5,7 @@
#ifndef __IRR_MATRIX_H_INCLUDED__
#define __IRR_MATRIX_H_INCLUDED__
#include "irrTypes.h"
#include "irrMath.h"
#include "vector3d.h"
#include "vector2d.h"
#include "plane3d.h"
@ -323,12 +323,11 @@ namespace core
\param axis: axis to rotate about
\param from: source vector to rotate from
*/
void buildAxisAlignedBillboard( const core::vector3df& camPos,
const core::vector3df& center,
const core::vector3df& translation,
const core::vector3df& axis,
const core::vector3df& from
);
void buildAxisAlignedBillboard(const core::vector3df& camPos,
const core::vector3df& center,
const core::vector3df& translation,
const core::vector3df& axis,
const core::vector3df& from);
/*
construct 2D Texture transformations
@ -384,6 +383,9 @@ namespace core
//! Gets if the matrix is definitely identity matrix
bool getDefinitelyIdentityMatrix() const;
//! Compare two matrices using the equal method
bool equals(const core::CMatrix4<T>& other, const T tolerance=(T)ROUNDING_ERROR_f64) const;
private:
//! Matrix data, stored in row-major order
T M[16];
@ -846,34 +848,36 @@ namespace core
inline core::vector3d<T> CMatrix4<T>::getRotationDegrees() const
{
const CMatrix4<T> &mat = *this;
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(0,2));
f64 Y = -asin(mat[2]*invScale.X);
const f64 C = cos(Y);
Y *= RADTODEG64;
f64 rotx, roty, X, Z;
if (fabs(C)>ROUNDING_ERROR_f64)
if (!core::iszero(C))
{
const T invC = (T)(1.0/C);
rotx = mat(2,2) * invC;
roty = mat(1,2) * invC;
const f64 invC = core::reciprocal(C);
rotx = mat[10] * invC * invScale.Z;
roty = mat[6] * invC * invScale.Y;
X = atan2( roty, rotx ) * RADTODEG64;
rotx = mat(0,0) * invC;
roty = mat(0,1) * invC;
rotx = mat[0] * invC * invScale.X;
roty = mat[1] * invC * invScale.X;
Z = atan2( roty, rotx ) * RADTODEG64;
}
else
{
X = 0.0;
rotx = mat(1,1);
roty = -mat(1,0);
rotx = mat[5] * invScale.Y;
roty = -mat[4] * invScale.Y;
Z = atan2( roty, rotx ) * RADTODEG64;
}
// fix values that get below zero
// before it would set (!) values to 360
// that where above 360:
// that were above 360:
if (X < 0.0) X += 360.0;
if (Y < 0.0) Y += 360.0;
if (Z < 0.0) Z += 360.0;
@ -938,10 +942,10 @@ namespace core
if (definitelyIdentityMatrix)
return true;
#endif
if (!equals( M[ 0], (T)1 ) ||
!equals( M[ 5], (T)1 ) ||
!equals( M[10], (T)1 ) ||
!equals( M[15], (T)1 ))
if (!core::equals( M[ 0], (T)1 ) ||
!core::equals( M[ 5], (T)1 ) ||
!core::equals( M[10], (T)1 ) ||
!core::equals( M[15], (T)1 ))
return false;
for (s32 i=0; i<4; ++i)
@ -2090,6 +2094,22 @@ namespace core
}
//! Compare two matrices using the equal method
template <class T>
inline bool CMatrix4<T>::equals(const core::CMatrix4<T>& other, const T tolerance) const
{
#if defined ( USE_MATRIX_TEST )
if (definitelyIdentityMatrix && other.definitelyIdentityMatrix)
return true;
#endif
for (s32 i = 0; i < 16; ++i)
if (!core::equals(M[i],other.M[i], tolerance))
return false;
return true;
}
// Multiply by scalar.
template <class T>
inline CMatrix4<T> operator*(const T scalar, const CMatrix4<T>& mat)

View File

@ -48,6 +48,20 @@ namespace core
box.isPointInside(pointC));
}
//! Determines if the triangle is totally outside a bounding box.
/** \param box Box to check.
\return True if triangle is outside the box, otherwise false. */
bool isTotalOutsideBox(const aabbox3d<T>& box) const
{
return ((pointA.X > box.MaxEdge.X && pointB.X > box.MaxEdge.X && pointC.X > box.MaxEdge.X) ||
(pointA.Y > box.MaxEdge.Y && pointB.Y > box.MaxEdge.Y && pointC.Y > box.MaxEdge.Y) ||
(pointA.Z > box.MaxEdge.Z && pointB.Z > box.MaxEdge.Z && pointC.Z > box.MaxEdge.Z) ||
(pointA.X < box.MinEdge.X && pointB.X < box.MinEdge.X && pointC.X < box.MinEdge.X) ||
(pointA.Y < box.MinEdge.Y && pointB.Y < box.MinEdge.Y && pointC.Y < box.MinEdge.Y) ||
(pointA.Z < box.MinEdge.Z && pointB.Z < box.MinEdge.Z && pointC.Z < box.MinEdge.Z));
}
//! Get the closest point on a triangle to a point on the same plane.
/** \param p Point which must be on the same plane as the triangle.
\return The closest point of the triangle */

View File

@ -140,10 +140,10 @@ namespace core
\return Reference to this vector after normalization. */
vector3d<T>& normalize()
{
f64 length = (f32)(X*X + Y*Y + Z*Z);
f64 length = X*X + Y*Y + Z*Z;
if (core::equals(length, 0.0)) // this check isn't an optimization but prevents getting NAN in the sqrt.
return *this;
length = core::reciprocal_squareroot ( (f64) (X*X + Y*Y + Z*Z) );
length = core::reciprocal_squareroot(length);
X = (T)(X * length);
Y = (T)(Y * length);
@ -161,9 +161,9 @@ namespace core
//! Inverts the vector.
vector3d<T>& invert()
{
X *= -1.0f;
Y *= -1.0f;
Z *= -1.0f;
X *= -1;
Y *= -1;
Z *= -1;
return *this;
}
@ -275,25 +275,50 @@ namespace core
{
vector3d<T> angle;
angle.Y = (T)(atan2(X, Z) * (T) RADTODEG64);
const f64 tmp = (atan2(X, Z) * RADTODEG64);
angle.Y = (T)tmp;
if (angle.Y < 0.0f)
angle.Y += 360.0f;
if (angle.Y >= 360.0f)
angle.Y -= 360.0f;
if (angle.Y < 0)
angle.Y += 360;
if (angle.Y >= 360)
angle.Y -= 360;
const T z1 = core::squareroot(X*X + Z*Z);
const f64 z1 = core::squareroot(X*X + Z*Z);
angle.X = (T)(atan2(z1, (T)Y) * (T) RADTODEG64 - (T) 90.0);
angle.X = (T)(atan2((f64)z1, (f64)Y) * RADTODEG64 - 90.0);
if (angle.X < (T) 0.0)
angle.X += (T) 360.0;
if (angle.X >= (T) 360.0)
angle.X -= (T) 360.0;
if (angle.X < 0)
angle.X += 360;
if (angle.X >= 360)
angle.X -= 360;
return angle;
}
//! Get the spherical coordinate angles
/** This returns Euler degrees for the point represented by
this vector. The calculation assumes the pole at (0,1,0) and
returns the angles in X and Y.
*/
vector3d<T> getSphericalCoordinateAngles()
{
vector3d<T> angle;
const f64 length = X*X + Y*Y + Z*Z;
if (length)
{
if (X!=0)
{
angle.Y = (T)(atan2(Z,X) * RADTODEG64);
}
else if (Z<0)
angle.Y=180;
angle.X = (T)(acos(Y * core::reciprocal_squareroot(length)) * RADTODEG64);
}
return angle;
}
//! Builds a direction vector from (this) rotation vector.
/** This vector is assumed to be a rotation vector composed of 3 Euler angle rotations, in degrees.
The implementation performs the same calculations as using a matrix to do the rotation.

View File

@ -1927,7 +1927,7 @@ public:
virtual s32 getInt()
{
return *(s32*)(&Value);
return *static_cast<s32*>(Value);
}
virtual bool getBool()
@ -1938,7 +1938,7 @@ public:
virtual core::stringw getStringW()
{
wchar_t buf[32];
swprintf(buf, 32, L"0x%x", *(int*)(&Value));
swprintf(buf, 32, L"%p", Value);
return core::stringw(buf);
}

View File

@ -493,7 +493,7 @@ bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 m
{
//Check for lightmapping:
if (BaseVertices[ vertex_id[i] ].TCoords2 != core::vector2df(0.f,0.f))
meshBuffer->MoveTo_2TCoords(); //Will only affect the meshbuffer the first time this is called
meshBuffer->convertTo2TCoords(); //Will only affect the meshbuffer the first time this is called
//Add the vertex to the meshbuffer:
if (meshBuffer->VertexType == video::EVT_STANDARD)
@ -922,9 +922,9 @@ void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const
material.Material.setTexture(i, tex);
}
if (material.Textures[i]->Flags & 0x10) // Clamp U
material.Material.TextureLayer[i].TextureWrap=video::ETC_CLAMP;
material.Material.TextureLayer[i].TextureWrapU=video::ETC_CLAMP;
if (material.Textures[i]->Flags & 0x20) // Clamp V
material.Material.TextureLayer[i].TextureWrap=video::ETC_CLAMP;
material.Material.TextureLayer[i].TextureWrapV=video::ETC_CLAMP;
}
}

View File

@ -69,7 +69,7 @@ void CBoneSceneNode::OnAnimate(u32 timeMs)
{
// animate this node with all animators
core::list<ISceneNodeAnimator*>::Iterator ait = Animators.begin();
ISceneNodeAnimatorList::Iterator ait = Animators.begin();
for (; ait != Animators.end(); ++ait)
(*ait)->animateNode(this, timeMs);
@ -77,7 +77,7 @@ void CBoneSceneNode::OnAnimate(u32 timeMs)
//updateAbsolutePosition();
// perform the post render process on all children
core::list<ISceneNode*>::Iterator it = Children.begin();
ISceneNodeList::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnAnimate(timeMs);
}
@ -88,7 +88,7 @@ void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node
{
Node->updateAbsolutePosition();
core::list<ISceneNode*>::ConstIterator it = Node->getChildren().begin();
ISceneNodeList::ConstIterator it = Node->getChildren().begin();
for (; it != Node->getChildren().end(); ++it)
{
helper_updateAbsolutePositionOfAllChildren( (*it) );

View File

@ -110,7 +110,7 @@ bool CCameraSceneNode::OnEvent(const SEvent& event)
// send events to event receiving animators
core::list<ISceneNodeAnimator*>::Iterator ait = Animators.begin();
ISceneNodeAnimatorList::Iterator ait = Animators.begin();
for (; ait != Animators.end(); ++ait)
if ((*ait)->isEventReceiverEnabled() && (*ait)->OnEvent(event))

View File

@ -779,7 +779,7 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
if (node && newnode)
{
// move children from dummy to new node
core::list<ISceneNode*>::ConstIterator it = node->getChildren().begin();
ISceneNodeList::ConstIterator it = node->getChildren().begin();
for (; it != node->getChildren().end(); it = node->getChildren().begin())
(*it)->setParent(newnode);

View File

@ -912,7 +912,7 @@ void CD3D8Driver::draw2D3DVertexPrimitiveList(const void* vertices,
E_MODULATE_FUNC modulo;
u32 alphaSource;
unpack_texureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam);
setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), alphaSource&video::EAS_TEXTURE);
setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0);
}
else
setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL);
@ -1354,6 +1354,39 @@ bool CD3D8Driver::setRenderStates3DMode()
}
//! Map Irrlicht texture wrap mode to native values
D3DTEXTUREADDRESS CD3D8Driver::getTextureWrapMode(const u8 clamp)
{
switch (clamp)
{
case ETC_REPEAT:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP)
return D3DTADDRESS_WRAP;
case ETC_CLAMP:
case ETC_CLAMP_TO_EDGE:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP)
return D3DTADDRESS_CLAMP;
case ETC_MIRROR:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR)
return D3DTADDRESS_MIRROR;
case ETC_CLAMP_TO_BORDER:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
return D3DTADDRESS_BORDER;
else
return D3DTADDRESS_CLAMP;
case ETC_MIRROR_CLAMP:
case ETC_MIRROR_CLAMP_TO_EDGE:
case ETC_MIRROR_CLAMP_TO_BORDER:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE)
return D3DTADDRESS_MIRRORONCE;
else
return D3DTADDRESS_CLAMP;
default:
return D3DTADDRESS_WRAP;
}
}
//! Can be called by an IMaterialRenderer to make its work easier.
void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates)
@ -1530,29 +1563,13 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetTextureStageState(st, D3DTSS_MIPMAPLODBIAS, *(DWORD*)(&tmp));
}
if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrap != material.TextureLayer[st].TextureWrap)
{
u32 mode = D3DTADDRESS_WRAP;
switch (material.TextureLayer[st].TextureWrap)
{
case ETC_REPEAT:
mode=D3DTADDRESS_WRAP;
break;
case ETC_CLAMP:
case ETC_CLAMP_TO_EDGE:
mode=D3DTADDRESS_CLAMP;
break;
case ETC_MIRROR:
mode=D3DTADDRESS_MIRROR;
break;
case ETC_CLAMP_TO_BORDER:
mode=D3DTADDRESS_BORDER;
break;
}
pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSU, mode );
pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, mode );
}
if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU)
pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
// If separate UV not supported reuse U for V
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV))
pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV)
pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV));
// Bilinear and/or trilinear
if (resetAllRenderstates ||

View File

@ -57,7 +57,7 @@ namespace video
//! sets a render target
virtual bool setRenderTarget(video::ITexture* texture,
bool clearBackBuffer=false, bool clearZBuffer=false,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0));
//! sets a viewport
@ -275,6 +275,8 @@ namespace video
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType, bool is3D);
D3DTEXTUREADDRESS getTextureWrapMode(const u8 clamp);
inline D3DCOLORVALUE colorToD3D(const SColor& col)
{
const f32 f = 1.0f / 255.0f;

View File

@ -627,6 +627,12 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0;
case EVDF_COLOR_MASK:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
case EVDF_MULTIPLE_RENDER_TARGETS:
return Caps.NumSimultaneousRTs > 1;
case EVDF_MRT_COLOR_MASK:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_INDEPENDENTWRITEMASKS) != 0;
case EVDF_MRT_BLEND:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0;
default:
return false;
};
@ -823,6 +829,120 @@ bool CD3D9Driver::setRenderTarget(video::ITexture* texture,
}
//! Sets multiple render targets
bool CD3D9Driver::setRenderTarget(const core::array<video::IRenderTarget>& targets,
bool clearBackBuffer, bool clearZBuffer, SColor color)
{
if (targets.size()==0)
return setRenderTarget(0, clearBackBuffer, clearZBuffer, color);
u32 maxMultipleRTTs = core::min_(4u, targets.size());
for (u32 i = 0; i < maxMultipleRTTs; ++i)
{
if (targets[i].TargetType != ERT_RENDER_TEXTURE || !targets[i].RenderTexture)
{
maxMultipleRTTs = i;
os::Printer::log("Missing texture for MRT.", ELL_WARNING);
break;
}
// check for right driver type
if (targets[i].RenderTexture->getDriverType() != EDT_DIRECT3D9)
{
maxMultipleRTTs = i;
os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING);
break;
}
// check for valid render target
if (!targets[i].RenderTexture->isRenderTarget())
{
maxMultipleRTTs = i;
os::Printer::log("Tried to set a non render target texture as render target.", ELL_WARNING);
break;
}
// check for valid size
if (targets[0].RenderTexture->getSize() != targets[i].RenderTexture->getSize())
{
maxMultipleRTTs = i;
os::Printer::log("Render target texture has wrong size.", ELL_WARNING);
break;
}
}
if (maxMultipleRTTs==0)
{
os::Printer::log("Fatal Error: No valid MRT found.", ELL_ERROR);
return false;
}
CD3D9Texture* tex = static_cast<CD3D9Texture*>(targets[0].RenderTexture);
// check if we should set the previous RT back
bool ret = true;
// we want to set a new target. so do this.
// store previous target
if (!PrevRenderTarget)
{
if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget)))
{
os::Printer::log("Could not get previous render target.", ELL_ERROR);
return false;
}
}
// set new render target
D3DRENDERSTATETYPE colorWrite[4]={D3DRS_COLORWRITEENABLE, D3DRS_COLORWRITEENABLE1, D3DRS_COLORWRITEENABLE2, D3DRS_COLORWRITEENABLE3};
for (u32 i = 0; i < maxMultipleRTTs; ++i)
{
if (FAILED(pID3DDevice->SetRenderTarget(i, static_cast<CD3D9Texture*>(targets[i].RenderTexture)->getRenderTargetSurface())))
{
os::Printer::log("Error: Could not set render target.", ELL_ERROR);
return false;
}
if (i<4 && (i==0 || queryFeature(EVDF_MRT_COLOR_MASK)))
{
const DWORD flag =
((targets[i].ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) |
((targets[i].ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) |
((targets[i].ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) |
((targets[i].ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0);
pID3DDevice->SetRenderState(colorWrite[i], flag);
}
}
CurrentRendertargetSize = tex->getSize();
if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface)))
{
os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR);
}
if (clearBackBuffer || clearZBuffer)
{
DWORD flags = 0;
if (clearBackBuffer)
flags |= D3DCLEAR_TARGET;
if (clearZBuffer)
flags |= D3DCLEAR_ZBUFFER;
pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0);
}
return ret;
}
//! sets a viewport
void CD3D9Driver::setViewPort(const core::rect<s32>& area)
{
@ -1799,6 +1919,39 @@ bool CD3D9Driver::setRenderStates3DMode()
}
//! Map Irrlicht texture wrap mode to native values
D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp)
{
switch (clamp)
{
case ETC_REPEAT:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP)
return D3DTADDRESS_WRAP;
case ETC_CLAMP:
case ETC_CLAMP_TO_EDGE:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP)
return D3DTADDRESS_CLAMP;
case ETC_MIRROR:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR)
return D3DTADDRESS_MIRROR;
case ETC_CLAMP_TO_BORDER:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
return D3DTADDRESS_BORDER;
else
return D3DTADDRESS_CLAMP;
case ETC_MIRROR_CLAMP:
case ETC_MIRROR_CLAMP_TO_EDGE:
case ETC_MIRROR_CLAMP_TO_BORDER:
if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE)
return D3DTADDRESS_MIRRORONCE;
else
return D3DTADDRESS_CLAMP;
default:
return D3DTADDRESS_WRAP;
}
}
//! Can be called by an IMaterialRenderer to make its work easier.
void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates)
@ -2011,29 +2164,13 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetSamplerState(st, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)(&tmp));
}
if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrap != material.TextureLayer[st].TextureWrap)
{
u32 mode = D3DTADDRESS_WRAP;
switch (material.TextureLayer[st].TextureWrap)
{
case ETC_REPEAT:
mode=D3DTADDRESS_WRAP;
break;
case ETC_CLAMP:
case ETC_CLAMP_TO_EDGE:
mode=D3DTADDRESS_CLAMP;
break;
case ETC_MIRROR:
mode=D3DTADDRESS_MIRROR;
break;
case ETC_CLAMP_TO_BORDER:
mode=D3DTADDRESS_BORDER;
break;
}
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSU, mode );
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, mode );
}
if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU)
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
// If separate UV not supported reuse U for V
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV))
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV)
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV));
// Bilinear, trilinear, and anisotropic filter
if (resetAllRenderstates ||

View File

@ -73,7 +73,12 @@ namespace video
//! sets a render target
virtual bool setRenderTarget(video::ITexture* texture,
bool clearBackBuffer=false, bool clearZBuffer=false,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0));
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0));
//! sets a viewport
@ -355,6 +360,8 @@ namespace video
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType, bool is3D);
D3DTEXTUREADDRESS getTextureWrapMode(const u8 clamp);
inline D3DCOLORVALUE colorToD3D(const SColor& col)
{
const f32 f = 1.0f / 255.0f;

View File

@ -46,6 +46,32 @@ CDMFLoader::CDMFLoader(ISceneManager* smgr, io::IFileSystem* filesys)
}
void CDMFLoader::findFile(bool use_mat_dirs, const core::stringc& path, const core::stringc& matPath, core::stringc& filename)
{
// path + texpath + full name
if (use_mat_dirs && FileSystem->existFile(path+matPath+filename))
filename = path+matPath+filename;
// path + full name
else if (FileSystem->existFile(path+filename))
filename = path+filename;
// path + texpath + base name
else if (use_mat_dirs && FileSystem->existFile(path+matPath+FileSystem->getFileBasename(filename)))
filename = path+matPath+FileSystem->getFileBasename(filename);
// path + base name
else if (FileSystem->existFile(path+FileSystem->getFileBasename(filename)))
filename = path+FileSystem->getFileBasename(filename);
// texpath + full name
else if (use_mat_dirs && FileSystem->existFile(matPath+filename))
filename = matPath+filename;
// texpath + base name
else if (use_mat_dirs && FileSystem->existFile(matPath+FileSystem->getFileBasename(filename)))
filename = matPath+FileSystem->getFileBasename(filename);
// base name
else if (FileSystem->existFile(FileSystem->getFileBasename(filename)))
filename = FileSystem->getFileBasename(filename);
}
/**Creates/loads an animated mesh from the file.
\return Pointer to the created mesh. Returns 0 if loading failed.
If you no longer need the mesh, you should call IAnimatedMesh::drop().
@ -57,7 +83,8 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
video::IVideoDriver* driver = SceneMgr->getVideoDriver();
//Load stringlist
StringList dmfRawFile(file);
StringList dmfRawFile;
LoadFromFile(file, dmfRawFile);
if (dmfRawFile.size()==0)
return 0;
@ -69,13 +96,13 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
dmfHeader header;
//load header
core::array<dmfMaterial> materiali;
if (GetDMFHeader(dmfRawFile, header))
{
//let's set ambient light
SceneMgr->setAmbientLight(header.dmfAmbient);
//let's create the correct number of materials, vertices and faces
core::array<dmfMaterial> materiali;
dmfVert *verts=new dmfVert[header.numVertices];
dmfFace *faces=new dmfFace[header.numFaces];
@ -113,7 +140,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
for (i = 0; i < header.numFaces; i++)
{
#ifdef _IRR_DMF_DEBUG_
// os::Printer::log("Polygon with #vertices", core::stringc(faces[i].numVerts).c_str());
os::Printer::log("Polygon with #vertices", core::stringc(faces[i].numVerts).c_str());
#endif
if (faces[i].numVerts < 3)
continue;
@ -129,12 +156,14 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
const bool use2TCoords = meshBuffer->Vertices_2TCoords.size() ||
materiali[faces[i].materialID].lightmapName.size();
if (use2TCoords && meshBuffer->Vertices_Standard.size())
meshBuffer->MoveTo_2TCoords();
meshBuffer->convertTo2TCoords();
const u32 base = meshBuffer->Vertices_2TCoords.size()?meshBuffer->Vertices_2TCoords.size():meshBuffer->Vertices_Standard.size();
// Add this face's verts
if (use2TCoords)
{
// make sure we have the proper type set
meshBuffer->VertexType=video::EVT_2TCOORDS;
for (u32 v = 0; v < faces[i].numVerts; v++)
{
const dmfVert& vv = verts[faces[i].firstVert + v];
@ -187,6 +216,33 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
}
}
delete verts;
delete faces;
}
// delete all buffers without geometry in it.
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Cleaning meshbuffers.");
#endif
i = 0;
while(i < mesh->MeshBuffers.size())
{
if (mesh->MeshBuffers[i]->getVertexCount() == 0 ||
mesh->MeshBuffers[i]->getIndexCount() == 0)
{
// Meshbuffer is empty -- drop it
mesh->MeshBuffers[i]->drop();
mesh->MeshBuffers.erase(i);
materiali.erase(i);
}
else
{
i++;
}
}
{
//load textures and lightmaps in materials.
//don't worry if you receive a could not load texture, cause if you don't need
//a particular material in your scene it will be loaded and then destroyed.
@ -202,7 +258,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
path = FileSystem->getFileDir(file->getFileName());
path += ('/');
for (i=0; i<header.numMaterials; i++)
for (i=0; i<mesh->getMeshBufferCount(); i++)
{
//texture and lightmap
video::ITexture *tex = 0;
@ -216,34 +272,8 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
{
if (materiali[i].textureBlend==4)
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true);
// path + texpath + full name
if (use_mat_dirs && FileSystem->existFile(path+materiali[i].pathName+materiali[i].textureName))
tex = driver->getTexture((path+materiali[i].pathName+materiali[i].textureName));
// path + full name
else if (FileSystem->existFile(path+materiali[i].textureName))
tex = driver->getTexture((path+materiali[i].textureName));
// path + texpath + base name
else if (use_mat_dirs && FileSystem->existFile(path+materiali[i].pathName+FileSystem->getFileBasename(materiali[i].textureName)))
tex = driver->getTexture((path+materiali[i].pathName+FileSystem->getFileBasename(materiali[i].textureName)));
// path + base name
else if (FileSystem->existFile(path+FileSystem->getFileBasename(materiali[i].textureName)))
tex = driver->getTexture((path+FileSystem->getFileBasename(materiali[i].textureName)));
// texpath + full name
else if (use_mat_dirs && FileSystem->existFile(materiali[i].pathName+materiali[i].textureName))
tex = driver->getTexture(materiali[i].pathName+materiali[i].textureName.c_str());
// full name
else if (FileSystem->existFile(materiali[i].textureName))
tex = driver->getTexture(materiali[i].textureName.c_str());
// texpath + base name
else if (use_mat_dirs && FileSystem->existFile(materiali[i].pathName+FileSystem->getFileBasename(materiali[i].textureName)))
tex = driver->getTexture(materiali[i].pathName+FileSystem->getFileBasename(materiali[i].textureName));
// base name
else if (FileSystem->existFile(FileSystem->getFileBasename(materiali[i].textureName)))
tex = driver->getTexture(FileSystem->getFileBasename(materiali[i].textureName));
#ifdef _IRR_DMF_DEBUG_
else
os::Printer::log("Could not load texture", materiali[i].textureName);
#endif // _IRR_DMF_DEBUG_
findFile(use_mat_dirs, path, materiali[i].pathName, materiali[i].textureName);
tex = driver->getTexture(materiali[i].textureName);
}
//Primary texture is just a colour
else if(materiali[i].textureFlag==1)
@ -271,7 +301,10 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//Lightmap is present
if (materiali[i].lightmapFlag == 0)
lig = driver->getTexture((path+materiali[i].lightmapName));
{
findFile(use_mat_dirs, path, materiali[i].pathName, materiali[i].lightmapName);
lig = driver->getTexture(materiali[i].lightmapName);
}
else //no lightmap
{
mat.MaterialType = video::EMT_SOLID;
@ -368,29 +401,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
mat.setTexture(0, tex);
mat.setTexture(1, lig);
}
delete verts;
delete faces;
}
// delete all buffers without geometry in it.
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Cleaning meshbuffers.");
#endif
i = 0;
while(i < mesh->MeshBuffers.size())
{
if (mesh->MeshBuffers[i]->getVertexCount() == 0 ||
mesh->MeshBuffers[i]->getIndexCount() == 0)
{
// Meshbuffer is empty -- drop it
mesh->MeshBuffers[i]->drop();
mesh->MeshBuffers.erase(i);
}
else
{
i++;
}
}
// create bounding box

View File

@ -78,6 +78,8 @@ namespace scene
bool mode = true);
private:
void findFile(bool use_mat_dirs, const core::stringc& path, const core::stringc& matPath, core::stringc& filename);
ISceneManager* SceneMgr;
io::IFileSystem* FileSystem;
};

View File

@ -47,7 +47,7 @@ void CDepthBuffer::clear()
#endif
u32 zMaxValue;
zMaxValue = *(u32*) &zMax;
zMaxValue = IR(zMax);
memset32 ( Buffer, zMaxValue, TotalSize );
}

View File

@ -10,6 +10,7 @@
#include "CZipReader.h"
#include "CMountPointReader.h"
#include "CPakReader.h"
#include "CNPKReader.h"
#include "CTarReader.h"
#include "CFileList.h"
#include "CXMLReader.h"
@ -67,6 +68,10 @@ CFileSystem::CFileSystem()
ArchiveLoader.push_back(new CArchiveLoaderPAK(this));
#endif
#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
ArchiveLoader.push_back(new CArchiveLoaderNPK(this));
#endif
#ifdef __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_
ArchiveLoader.push_back(new CArchiveLoaderTAR(this));
#endif
@ -185,7 +190,7 @@ bool CFileSystem::moveFileArchive(u32 sourceIndex, s32 relative)
//! Adds an archive to the file system.
bool CFileSystem::addFileArchive(const io::path& filename, bool ignoreCase,
bool ignorePaths, E_FILE_ARCHIVE_TYPE archiveType)
bool ignorePaths, E_FILE_ARCHIVE_TYPE archiveType)
{
IFileArchive* archive = 0;
bool ret = false;
@ -194,7 +199,7 @@ bool CFileSystem::addFileArchive(const io::path& filename, bool ignoreCase,
// check if the archive was already loaded
for (i = 0; i < FileArchives.size(); ++i)
{
if (filename == FileArchives[i]->getFileList()->getPath())
if (getAbsolutePath(filename) == FileArchives[i]->getFileList()->getPath())
return true;
}
@ -404,7 +409,7 @@ bool CFileSystem::changeWorkingDirectoryTo(const io::path& newDirectory)
if (FileSystemType != FILESYSTEM_NATIVE)
{
WorkingDirectory[FILESYSTEM_VIRTUAL].append(newDirectory);
WorkingDirectory[FILESYSTEM_VIRTUAL] = newDirectory;
flattenFilename(WorkingDirectory[FILESYSTEM_VIRTUAL], "");
success = 1;
}
@ -707,7 +712,7 @@ bool CFileSystem::existFile(const io::path& filename) const
#if defined(_IRR_WCHAR_FILESYSTEM)
HANDLE hFile = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
#else
HANDLE hFile = CreateFileA(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
HANDLE hFile = CreateFileW(core::stringw(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
#endif
if (hFile == INVALID_HANDLE_VALUE)
return false;

View File

@ -154,7 +154,7 @@ void CGUICheckBox::draw()
IGUIFont* font = skin->getFont();
if (font)
font->draw(Text.c_str(), checkRect,
skin->getColor(EGDC_BUTTON_TEXT), false, true, &AbsoluteClippingRect);
skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), false, true, &AbsoluteClippingRect);
}
IGUIElement::draw();

View File

@ -651,9 +651,21 @@ void CGUIContextMenu::recalculateSize()
const s32 w = Items[i].SubMenu->getAbsolutePosition().getWidth();
const s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight();
Items[i].SubMenu->setRelativePosition(
core::rect<s32>(width-5, Items[i].PosY,
width+w-5, Items[i].PosY+h));
core::rect<s32> subRect(width-5, Items[i].PosY, width+w-5, Items[i].PosY+h);
// if it would be drawn beyond the right border, then add it to the left side
gui::IGUIElement * root = Environment->getRootGUIElement();
if ( root )
{
core::rect<s32> rectRoot( root->getAbsolutePosition() );
if ( getAbsolutePosition().UpperLeftCorner.X+subRect.LowerRightCorner.X > rectRoot.LowerRightCorner.X )
{
subRect.UpperLeftCorner.X = -w;
subRect.LowerRightCorner.X = 0;
}
}
Items[i].SubMenu->setRelativePosition(subRect);
}
}
}

View File

@ -43,10 +43,7 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
ScrollBar->setTabStop(false);
ScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
ScrollBar->setVisible(false);
ScrollBar->drop();
ScrollBar->setPos(0);
ScrollBar->grab();
setNotClipped(!clip);
@ -166,8 +163,9 @@ void CGUIListBox::recalculateItemHeight()
TotalItemHeight = ItemHeight * Items.size();
ScrollBar->setMax(TotalItemHeight - AbsoluteRect.getHeight());
ScrollBar->setSmallStep ( 1 );
ScrollBar->setLargeStep ( ItemHeight );
s32 minItemHeight = ItemHeight > 0 ? ItemHeight : 1;
ScrollBar->setSmallStep ( minItemHeight );
ScrollBar->setLargeStep ( 2*minItemHeight );
if ( TotalItemHeight <= AbsoluteRect.getHeight() )
ScrollBar->setVisible(false);
@ -390,7 +388,7 @@ bool CGUIListBox::OnEvent(const SEvent& event)
switch(event.MouseInput.Event)
{
case EMIE_MOUSE_WHEEL:
ScrollBar->setPos(ScrollBar->getPos() + (s32)event.MouseInput.Wheel*-10);
ScrollBar->setPos(ScrollBar->getPos() + (s32)event.MouseInput.Wheel*-ItemHeight/2);
return true;
case EMIE_LMOUSE_PRESSED_DOWN:

View File

@ -31,14 +31,14 @@ CGUISkin::CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver)
Colors[EGDC_3D_HIGH_LIGHT] = video::SColor(101,255,255,255);
Colors[EGDC_3D_LIGHT] = video::SColor(101,210,210,210);
Colors[EGDC_ACTIVE_BORDER] = video::SColor(101,16,14,115);
Colors[EGDC_ACTIVE_CAPTION] = video::SColor(200,255,255,255);
Colors[EGDC_ACTIVE_CAPTION] = video::SColor(255,255,255,255);
Colors[EGDC_APP_WORKSPACE] = video::SColor(101,100,100,100);
Colors[EGDC_BUTTON_TEXT] = video::SColor(240,10,10,10);
Colors[EGDC_GRAY_TEXT] = video::SColor(240,130,130,130);
Colors[EGDC_HIGH_LIGHT] = video::SColor(101,8,36,107);
Colors[EGDC_HIGH_LIGHT_TEXT] = video::SColor(240,255,255,255);
Colors[EGDC_INACTIVE_BORDER] = video::SColor(101,165,165,165);
Colors[EGDC_INACTIVE_CAPTION] = video::SColor(101,210,210,210);
Colors[EGDC_INACTIVE_CAPTION] = video::SColor(255,30,30,30);
Colors[EGDC_TOOLTIP] = video::SColor(200,0,0,0);
Colors[EGDC_TOOLTIP_BACKGROUND]= video::SColor(200,255,255,225);
Colors[EGDC_SCROLLBAR] = video::SColor(101,230,230,230);
@ -72,14 +72,14 @@ CGUISkin::CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver)
Colors[EGDC_3D_HIGH_LIGHT] = 0x40c7ccdc;
Colors[EGDC_3D_LIGHT] = 0x802e313a;
Colors[EGDC_ACTIVE_BORDER] = 0x80404040; // window title
Colors[EGDC_ACTIVE_CAPTION] = 0xf0d0d0d0;
Colors[EGDC_ACTIVE_CAPTION] = 0xffd0d0d0;
Colors[EGDC_APP_WORKSPACE] = 0xc0646464; // unused
Colors[EGDC_BUTTON_TEXT] = 0xd0161616;
Colors[EGDC_GRAY_TEXT] = 0x3c141414;
Colors[EGDC_HIGH_LIGHT] = 0x6c606060;
Colors[EGDC_HIGH_LIGHT_TEXT]= 0xd0e0e0e0;
Colors[EGDC_INACTIVE_BORDER]= 0xf0a5a5a5;
Colors[EGDC_INACTIVE_CAPTION]= 0xf0d2d2d2;
Colors[EGDC_INACTIVE_CAPTION]= 0xffd2d2d2;
Colors[EGDC_TOOLTIP] = 0xf00f2033;
Colors[EGDC_TOOLTIP_BACKGROUND]=0xc0cbd2d9;
Colors[EGDC_SCROLLBAR] = 0xf0e0e0e0;
@ -204,7 +204,7 @@ void CGUISkin::setSize(EGUI_DEFAULT_SIZE which, s32 size)
//! returns the default font
IGUIFont* CGUISkin::getFont(EGUI_DEFAULT_FONT which) const
{
if (((u32)which < EGDS_COUNT) && Fonts[which])
if (((u32)which < EGDF_COUNT) && Fonts[which])
return Fonts[which];
else
return Fonts[EGDF_DEFAULT];
@ -214,7 +214,7 @@ IGUIFont* CGUISkin::getFont(EGUI_DEFAULT_FONT which) const
//! sets a default font
void CGUISkin::setFont(IGUIFont* font, EGUI_DEFAULT_FONT which)
{
if ((u32)which >= EGDS_COUNT)
if ((u32)which >= EGDF_COUNT)
return;
if (font)

View File

@ -19,7 +19,7 @@ namespace gui
//! constructor
CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUIWindow(environment, parent, id, rectangle), Dragging(false), IsDraggable(true), DrawBackground(true), DrawTitlebar(true)
: IGUIWindow(environment, parent, id, rectangle), Dragging(false), IsDraggable(true), DrawBackground(true), DrawTitlebar(true), IsActive(false)
{
#ifdef _DEBUG
setDebugName("CGUIWindow");
@ -118,12 +118,20 @@ bool CGUIWindow::OnEvent(const SEvent& event)
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
Dragging = false;
IsActive = false;
}
else
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
{
if (Parent && ((event.GUIEvent.Caller == this) || isMyChild(event.GUIEvent.Caller)))
{
Parent->bringToFront(this);
IsActive = true;
}
else
{
IsActive = false;
}
}
else
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
@ -218,8 +226,9 @@ void CGUIWindow::draw()
// draw body fast
if ( DrawBackground )
{
rect = skin->draw3DWindowBackground(this, DrawTitlebar, skin->getColor(EGDC_ACTIVE_BORDER),
AbsoluteRect, &AbsoluteClippingRect);
rect = skin->draw3DWindowBackground(this, DrawTitlebar,
skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
AbsoluteRect, &AbsoluteClippingRect);
if (DrawTitlebar && Text.size())
{
@ -231,7 +240,8 @@ void CGUIWindow::draw()
if (font)
{
font->draw(Text.c_str(), rect,
skin->getColor(EGDC_ACTIVE_CAPTION), false, true, &AbsoluteClippingRect);
skin->getColor(IsActive ? EGDC_ACTIVE_CAPTION:EGDC_INACTIVE_CAPTION),
false, true, &AbsoluteClippingRect);
}
}
}
@ -327,6 +337,7 @@ void CGUIWindow::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWr
IGUIWindow::deserializeAttributes(in,options);
Dragging = false;
IsActive = false;
IsDraggable = in->getAttributeAsBool("IsDraggable");
DrawBackground = in->getAttributeAsBool("DrawBackground");
DrawTitlebar = in->getAttributeAsBool("DrawTitlebar");

View File

@ -79,6 +79,7 @@ namespace gui
bool Dragging, IsDraggable;
bool DrawBackground;
bool DrawTitlebar;
bool IsActive;
};
} // end namespace gui

View File

@ -337,8 +337,6 @@ IMesh* CGeometryCreator::createArrowMesh(const u32 tesselationCylinder,
/* A sphere with proper normals and texture coords */
IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY) const
{
SMeshBuffer* buffer = new SMeshBuffer();
// thanks to Alfaz93 who made his code available for Irrlicht on which
// this one is based!
@ -348,21 +346,20 @@ IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCo
polyCountX = 2;
if (polyCountY < 2)
polyCountY = 2;
if (polyCountX * polyCountY > 32767) // prevent u16 overflow
while (polyCountX * polyCountY > 32767) // prevent u16 overflow
{
if (polyCountX > polyCountY) // prevent u16 overflow
polyCountX = 32767/polyCountY-1;
else
polyCountY = 32767/(polyCountX+1);
polyCountX /= 2;
polyCountY /= 2;
}
u32 polyCountXPitch = polyCountX+1; // get to same vertex on next level
buffer->Vertices.set_used((polyCountXPitch * polyCountY) + 2);
buffer->Indices.set_used((polyCountX * polyCountY) * 6);
const u32 polyCountXPitch = polyCountX+1; // get to same vertex on next level
SMeshBuffer* buffer = new SMeshBuffer();
buffer->Indices.reallocate((polyCountX * polyCountY) * 6);
const video::SColor clr(100, 255,255,255);
u32 i=0;
u32 level = 0;
for (u32 p1 = 0; p1 < polyCountY-1; ++p1)
@ -371,25 +368,22 @@ IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCo
for (u32 p2 = 0; p2 < polyCountX - 1; ++p2)
{
const u32 curr = level + p2;
buffer->Indices[i] = curr + polyCountXPitch;
buffer->Indices[++i] = curr;
buffer->Indices[++i] = curr + 1;
buffer->Indices[++i] = curr + polyCountXPitch;
buffer->Indices[++i] = curr+1;
buffer->Indices[++i] = curr + 1 + polyCountXPitch;
++i;
buffer->Indices.push_back(curr + polyCountXPitch);
buffer->Indices.push_back(curr);
buffer->Indices.push_back(curr + 1);
buffer->Indices.push_back(curr + polyCountXPitch);
buffer->Indices.push_back(curr+1);
buffer->Indices.push_back(curr + 1 + polyCountXPitch);
}
// the connectors from front to end
buffer->Indices[i] = level + polyCountX - 1 + polyCountXPitch;
buffer->Indices[++i] = level + polyCountX - 1;
buffer->Indices[++i] = level + polyCountX;
++i;
buffer->Indices.push_back(level + polyCountX - 1 + polyCountXPitch);
buffer->Indices.push_back(level + polyCountX - 1);
buffer->Indices.push_back(level + polyCountX);
buffer->Indices[i] = level + polyCountX - 1 + polyCountXPitch;
buffer->Indices[++i] = level + polyCountX;
buffer->Indices[++i] = level + polyCountX + polyCountXPitch;
++i;
buffer->Indices.push_back(level + polyCountX - 1 + polyCountXPitch);
buffer->Indices.push_back(level + polyCountX);
buffer->Indices.push_back(level + polyCountX + polyCountXPitch);
level += polyCountXPitch;
}
@ -401,43 +395,41 @@ IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCo
{
// create triangles which are at the top of the sphere
buffer->Indices[i] = polyCountSq;
buffer->Indices[++i] = p2 + 1;
buffer->Indices[++i] = p2;
++i;
buffer->Indices.push_back(polyCountSq);
buffer->Indices.push_back(p2 + 1);
buffer->Indices.push_back(p2);
// create triangles which are at the bottom of the sphere
buffer->Indices[i] = polyCountSqM1 + p2;
buffer->Indices[++i] = polyCountSqM1 + p2 + 1;
buffer->Indices[++i] = polyCountSq1;
++i;
buffer->Indices.push_back(polyCountSqM1 + p2);
buffer->Indices.push_back(polyCountSqM1 + p2 + 1);
buffer->Indices.push_back(polyCountSq1);
}
// create final triangle which is at the top of the sphere
buffer->Indices[i] = polyCountSq;
buffer->Indices[++i] = polyCountX;
buffer->Indices[++i] = polyCountX-1;
++i;
buffer->Indices.push_back(polyCountSq);
buffer->Indices.push_back(polyCountX);
buffer->Indices.push_back(polyCountX-1);
// create final triangle which is at the bottom of the sphere
buffer->Indices[i] = polyCountSqM1 + polyCountX - 1;
buffer->Indices[++i] = polyCountSqM1;
buffer->Indices[++i] = polyCountSq1;
buffer->Indices.push_back(polyCountSqM1 + polyCountX - 1);
buffer->Indices.push_back(polyCountSqM1);
buffer->Indices.push_back(polyCountSq1);
// calculate the angle which separates all points in a circle
const f64 AngleX = 2 * core::PI / polyCountX;
const f64 AngleY = core::PI / polyCountY;
i = 0;
u32 i=0;
f64 axz;
// we don't start at 0.
f64 ay = 0;//AngleY / 2;
buffer->Vertices.set_used((polyCountXPitch * polyCountY) + 2);
for (u32 y = 0; y < polyCountY; ++y)
{
ay += AngleY;
@ -508,8 +500,8 @@ IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCo
/* A cylinder with proper normals and texture coords */
IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length,
u32 tesselation, const video::SColor& color,
bool closeTop, f32 oblique) const
u32 tesselation, const video::SColor& color,
bool closeTop, f32 oblique) const
{
SMeshBuffer* buffer = new SMeshBuffer();

View File

@ -16,9 +16,6 @@ namespace video
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size)
:Data(0), Size(size), Format(format), DeleteMemory(true)
{
#ifdef _DEBUG
setDebugName("CImage");
#endif
initData();
}
@ -79,6 +76,9 @@ CImage::CImage(IImage* imageToCopy, const core::position2d<s32>& pos,
//! assumes format and size has been set and creates the rest
void CImage::initData()
{
#ifdef _DEBUG
setDebugName("CImage");
#endif
BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8;
// Pitch should be aligned...

View File

@ -153,7 +153,7 @@ namespace irr
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<s32> getPosition()
virtual const core::position2d<s32>& getPosition()
{
return CursorPos;
}

View File

@ -974,7 +974,7 @@ bool CIrrDeviceLinux::run()
else
{
irrevent.KeyInput.Key = (EKEY_CODE)0;
os::Printer::log("Could not find win32 key for x11 key.", ELL_WARNING);
os::Printer::log("Could not find win32 key for x11 key.", core::stringc((int)mp.X11Key).c_str(), ELL_WARNING);
}
irrevent.EventType = irr::EET_KEY_INPUT_EVENT;
irrevent.KeyInput.PressedDown = (event.type == KeyPress);
@ -1367,6 +1367,7 @@ void CIrrDeviceLinux::createKeyMap()
KeyMap.push_back(SKeyMap(XK_Page_Down, KEY_NEXT));
KeyMap.push_back(SKeyMap(XK_End, KEY_END));
KeyMap.push_back(SKeyMap(XK_Begin, KEY_HOME));
KeyMap.push_back(SKeyMap(XK_Num_Lock, KEY_NUMLOCK));
KeyMap.push_back(SKeyMap(XK_KP_Space, KEY_SPACE));
KeyMap.push_back(SKeyMap(XK_KP_Tab, KEY_TAB));
KeyMap.push_back(SKeyMap(XK_KP_Enter, KEY_RETURN));
@ -1374,10 +1375,12 @@ void CIrrDeviceLinux::createKeyMap()
KeyMap.push_back(SKeyMap(XK_KP_F2, KEY_F2));
KeyMap.push_back(SKeyMap(XK_KP_F3, KEY_F3));
KeyMap.push_back(SKeyMap(XK_KP_F4, KEY_F4));
KeyMap.push_back(SKeyMap(XK_KP_Home, KEY_HOME));
KeyMap.push_back(SKeyMap(XK_KP_Left, KEY_LEFT));
KeyMap.push_back(SKeyMap(XK_KP_Up, KEY_UP));
KeyMap.push_back(SKeyMap(XK_KP_Right, KEY_RIGHT));
KeyMap.push_back(SKeyMap(XK_KP_Down, KEY_DOWN));
KeyMap.push_back(SKeyMap(XK_Print, KEY_PRINT));
KeyMap.push_back(SKeyMap(XK_KP_Prior, KEY_PRIOR));
KeyMap.push_back(SKeyMap(XK_KP_Page_Up, KEY_PRIOR));
KeyMap.push_back(SKeyMap(XK_KP_Next, KEY_NEXT));
@ -1698,9 +1701,9 @@ bool CIrrDeviceLinux::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness
XRRCrtcGamma *gamma = XRRGetCrtcGamma(display, screennr);
if (gamma)
{
*gamma->red=red;
*gamma->green=green;
*gamma->blue=blue;
*gamma->red=(u16)red;
*gamma->green=(u16)green;
*gamma->blue=(u16)blue;
XRRSetCrtcGamma(display, screennr, gamma);
XRRFreeGamma(gamma);
return true;

View File

@ -252,7 +252,7 @@ namespace irr
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<s32> getPosition()
virtual const core::position2d<s32>& getPosition()
{
updateCursorPos();
return CursorPos;

View File

@ -143,7 +143,7 @@ namespace irr
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<s32> getPosition()
virtual const core::position2d<s32>& getPosition()
{
updateCursorPos();
return CursorPos;

View File

@ -213,17 +213,30 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
event.KeyInput.Key = (irr::EKEY_CODE)wParam;
event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN);
const UINT MY_MAPVK_VSC_TO_VK_EX = 3; // MAPVK_VSC_TO_VK_EX should be in SDK according to MSDN, but isn't in mine.
if ( event.KeyInput.Key == irr::KEY_SHIFT )
{
// this will fail on systems before windows NT/2000/XP, not sure _what_ will return there instead.
event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX );
}
if ( event.KeyInput.Key == irr::KEY_CONTROL )
{
event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX );
// some keyboards will just return LEFT for both - left and right keys. So also check extend bit.
if (lParam & 0x1000000)
event.KeyInput.Key = irr::KEY_RCONTROL;
}
if ( event.KeyInput.Key == irr::KEY_MENU )
{
event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX );
if (lParam & 0x1000000)
event.KeyInput.Key = irr::KEY_RMENU;
}
WORD KeyAsc=0;
GetKeyboardState(allKeys);
ToAscii((UINT)wParam,(UINT)lParam,allKeys,&KeyAsc,0);
if (event.KeyInput.Key==irr::KEY_SHIFT)
{
if ((allKeys[VK_LSHIFT] & 0x80)!=0)
event.KeyInput.Key=irr::KEY_LSHIFT;
else if ((allKeys[VK_RSHIFT] & 0x80)!=0)
event.KeyInput.Key=irr::KEY_RSHIFT;
}
event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0);
event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0);
event.KeyInput.Char = (KeyAsc & 0x00ff); //KeyAsc >= 0 ? KeyAsc : 0;

View File

@ -207,7 +207,7 @@ namespace irr
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<s32> getPosition()
virtual const core::position2d<s32>& getPosition()
{
updateInternalCursorPosition();
return CursorPos;

View File

@ -162,7 +162,7 @@ namespace irr
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<s32> getPosition()
virtual const core::position2d<s32>& getPosition()
{
updateInternalCursorPosition();
return CursorPos;

View File

@ -31,6 +31,7 @@ namespace scene
# error compiler not supported
#endif
namespace {
// File header
struct MS3DHeader
{
@ -99,6 +100,8 @@ struct MS3DVertexWeights
u8 weights[3];
} PACK_STRUCT;
} // end namespace
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )

View File

@ -7,6 +7,7 @@
#include "CMeshBuffer.h"
#include "SAnimatedMesh.h"
#include "os.h"
#include "irrMap.h"
namespace irr
{
@ -60,86 +61,6 @@ void CMeshManipulator::flipSurfaces(scene::IMesh* mesh) const
}
//! Sets the alpha vertex color value of the whole mesh to a new value
//! \param mesh: Mesh on which the operation is performed.
void CMeshManipulator::setVertexColorAlpha(scene::IMesh* mesh, s32 alpha) const
{
if (!mesh)
return;
u32 i;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
IMeshBuffer* buffer = mesh->getMeshBuffer(b);
void* v = buffer->getVertices();
u32 vtxcnt = buffer->getVertexCount();
switch(buffer->getVertexType())
{
case video::EVT_STANDARD:
{
for ( i=0; i<vtxcnt; ++i)
((video::S3DVertex*)v)[i].Color.setAlpha(alpha);
}
break;
case video::EVT_2TCOORDS:
{
for ( i=0; i<vtxcnt; ++i)
((video::S3DVertex2TCoords*)v)[i].Color.setAlpha(alpha);
}
break;
case video::EVT_TANGENTS:
{
for ( i=0; i<vtxcnt; ++i)
((video::S3DVertexTangents*)v)[i].Color.setAlpha(alpha);
}
break;
}
}
}
//! Sets the colors of all vertices to one color
void CMeshManipulator::setVertexColors(IMesh* mesh, video::SColor color) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for (u32 b=0; b<bcount; ++b)
{
IMeshBuffer* buffer = mesh->getMeshBuffer(b);
void* v = buffer->getVertices();
const u32 vtxcnt = buffer->getVertexCount();
u32 i;
switch(buffer->getVertexType())
{
case video::EVT_STANDARD:
{
for ( i=0; i<vtxcnt; ++i)
((video::S3DVertex*)v)[i].Color = color;
}
break;
case video::EVT_2TCOORDS:
{
for ( i=0; i<vtxcnt; ++i)
((video::S3DVertex2TCoords*)v)[i].Color = color;
}
break;
case video::EVT_TANGENTS:
{
for ( i=0; i<vtxcnt; ++i)
((video::S3DVertexTangents*)v)[i].Color = color;
}
break;
}
}
}
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. */
void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool angleWeighted) const
@ -205,143 +126,6 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool
}
//! Applies a transformation
/** \param buffer: Meshbuffer on which the operation is performed.
\param m: matrix. */
void CMeshManipulator::transform(scene::IMeshBuffer* buffer, const core::matrix4& m) const
{
const u32 vtxcnt = buffer->getVertexCount();
if (!vtxcnt)
return;
core::aabbox3df bufferbox;
// first transform
{
m.transformVect(buffer->getPosition(0));
m.rotateVect(buffer->getNormal(0));
buffer->getNormal(0).normalize();
bufferbox.reset(buffer->getPosition(0));
}
for ( u32 i=1 ;i < vtxcnt; ++i)
{
m.transformVect(buffer->getPosition(i));
m.rotateVect(buffer->getNormal(i));
buffer->getNormal(i).normalize();
bufferbox.addInternalPoint(buffer->getPosition(i));
}
buffer->setBoundingBox(bufferbox);
}
//! Applies a transformation
/** \param mesh: Mesh on which the operation is performed.
\param m: matrix. */
void CMeshManipulator::transform(scene::IMesh* mesh, const core::matrix4& m) const
{
if (!mesh)
return;
core::aabbox3df meshbox;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
IMeshBuffer* buffer = mesh->getMeshBuffer(b);
transform(buffer, m);
if (b == 0)
meshbox.reset(buffer->getBoundingBox());
else
meshbox.addInternalBox(buffer->getBoundingBox());
}
mesh->setBoundingBox( meshbox );
}
//! Scales the actual mesh, not a scene node.
void CMeshManipulator::scale(scene::IMesh* mesh, const core::vector3df& factor) const
{
if (!mesh)
return;
core::aabbox3df meshbox;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
IMeshBuffer* buffer = mesh->getMeshBuffer(b);
scale(buffer, factor);
if (b == 0)
meshbox.reset(buffer->getBoundingBox());
else
meshbox.addInternalBox(buffer->getBoundingBox());
}
mesh->setBoundingBox( meshbox );
}
//! Scales the actual meshbuffer, not a scene node.
void CMeshManipulator::scale(scene::IMeshBuffer* buffer, const core::vector3df& factor) const
{
if (!buffer)
return;
const u32 vtxcnt = buffer->getVertexCount();
core::aabbox3df bufferbox;
if (vtxcnt != 0)
bufferbox.reset(buffer->getPosition(0) * factor);
for (u32 i=0; i<vtxcnt; ++i)
{
buffer->getPosition(i) *= factor;
bufferbox.addInternalPoint(buffer->getPosition(i));
}
buffer->setBoundingBox(bufferbox);
}
//! Scale the texture coords of a mesh.
void CMeshManipulator::scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 layer) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for (u32 b=0; b<bcount; ++b)
scaleTCoords(mesh->getMeshBuffer(b), factor, layer);
}
//! Scale the level-th texture coords of a meshbuffer.
void CMeshManipulator::scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level) const
{
if (!buffer || ((level>1) && (buffer->getVertexType() != video::EVT_2TCOORDS)))
return;
const u32 vtxcnt = buffer->getVertexCount();
if (level==1)
{
for (u32 i=0; i<vtxcnt; ++i)
buffer->getTCoords(i) *= factor;
}
else
{
for (u32 i=0; i<vtxcnt; ++i)
((SMeshBufferLightMap*)buffer)->Vertices[i].TCoords2 *= factor;
}
}
//! Clones a static IMesh into a modifyable SMesh.
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
{
@ -1099,57 +883,64 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
for (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();
SMeshBuffer* buffer = new SMeshBuffer();
buffer->Material = mesh->getMeshBuffer(b)->getMaterial();
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt);
core::map<video::S3DVertex, 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(v[idx[i]]);
}
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::S3DVertex(
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(
video::S3DVertex(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords));
}
break;
}
// create new indices
buffer->Indices.set_used(idxCnt);
const video::E_VERTEX_TYPE vType = original->getVertexType();
video::S3DVertex vNew;
for (u32 i=0; i<idxCnt; ++i)
buffer->Indices[i] = i;
{
switch(vType)
{
case video::EVT_STANDARD:
{
video::S3DVertex* v =
(video::S3DVertex*)original->getVertices();
vNew = v[idx[i]];
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* v =
(video::S3DVertex2TCoords*)original->getVertices();
vNew = video::S3DVertex(
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*)original->getVertices();
vNew = video::S3DVertex(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
}
break;
}
core::map<video::S3DVertex, 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);
}
// create new indices
buffer->Indices[i] = vertLocation;
}
//buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox());
buffer->recalculateBoundingBox ();
@ -1159,9 +950,7 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
buffer->drop();
}
clone->recalculateBoundingBox ();
//clone->BoundingBox = mesh->getBoundingBox();
clone->recalculateBoundingBox();
return clone;
}

View File

@ -25,14 +25,6 @@ public:
\param mesh: Mesh on which the operation is performed. */
virtual void flipSurfaces(scene::IMesh* mesh) const;
//! Sets the alpha vertex color value of the whole mesh to a new value
/** \param mesh: Mesh on which the operation is performed.
\param alpha: New alpha for the vertex color. */
virtual void setVertexColorAlpha(scene::IMesh* mesh, s32 alpha) const;
//! Sets the colors of all vertices to one color
virtual void setVertexColors(IMesh* mesh, video::SColor color) const;
//! Recalculates all normals of the mesh.
/** \param mesh: Mesh on which the operation is performed.
\param smooth: Whether to use smoothed normals. */
@ -43,38 +35,6 @@ public:
\param smooth: Whether to use smoothed normals. */
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false, bool angleWeighted = false) const;
//! Scales the actual mesh, not the scene node.
/** \param mesh Mesh on which the operation is performed.
\param factor Vector which defines the scale for each axis. */
virtual void scale(scene::IMesh* mesh, const core::vector3df& factor) const;
//! Scales the actual meshbuffer, not the scene node.
/** \param buffer MeshBuffer on which the operation is performed.
\param factor Vector which defines the scale for each axis. */
virtual void scale(scene::IMeshBuffer* buffer, const core::vector3df& factor) const;
//! Scale the texture coords of a mesh.
/** \param mesh Mesh on which the operation is performed.
\param factor Vector which defines the scale for each axis.
\param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */
virtual void scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 layer=1) const;
//! Scale the texture coords of a meshbuffer.
/** \param mesh Mesh on which the operation is performed.
\param factor Vector which defines the scale for each axis.
\param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */
virtual void scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level=1) const;
//! Applies a transformation to a meshbuffer
/** \param buffer: Meshbuffer on which the operation is performed.
\param m: matrix. */
void transform(scene::IMeshBuffer* buffer, const core::matrix4& m) const;
//! Applies a transformation to a mesh
/** \param mesh: Mesh on which the operation is performed.
\param m: transformation matrix. */
virtual void transform(scene::IMesh* mesh, const core::matrix4& m) const;
//! Clones a static IMesh into a modifiable SMesh.
virtual SMesh* createMeshCopy(scene::IMesh* mesh) const;
@ -129,4 +89,3 @@ private:
#endif

View File

@ -45,9 +45,10 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
{
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
transform);
arraySize - outWritten, t, transform);
outWritten += t;
if (outWritten==arraySize)
break;
}
outTriangleCount = outWritten;
@ -64,9 +65,10 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
{
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
box, transform);
arraySize - outWritten, t, box, transform);
outWritten += t;
if (outWritten==arraySize)
break;
}
outTriangleCount = outWritten;
@ -82,10 +84,11 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
for (u32 i=0; i<TriangleSelectors.size(); ++i)
{
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
line, transform);
TriangleSelectors[i]->getTriangles(triangles + outWritten,
arraySize - outWritten, t, line, transform);
outWritten += t;
if (outWritten==arraySize)
break;
}
outTriangleCount = outWritten;
@ -130,6 +133,7 @@ void CMetaTriangleSelector::removeAllTriangleSelectors()
TriangleSelectors.clear();
}
//! Return the scene node associated with a given triangle.
const ISceneNode* CMetaTriangleSelector::getSceneNodeForTriangle(u32 triangleIndex) const
{
@ -142,13 +146,12 @@ const ISceneNode* CMetaTriangleSelector::getSceneNodeForTriangle(u32 triangleInd
if(totalTriangles > triangleIndex)
return TriangleSelectors[i]->getSceneNodeForTriangle(0);
}
// For lack of anything more sensible, return the first selector.
return TriangleSelectors[0]->getSceneNodeForTriangle(0);
}
} // end namespace scene
} // end namespace irr

View File

@ -0,0 +1,279 @@
// Copyright (C) 2002-2009 Nikolaus Gebhardt
// Copyright (C) 2009 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// Based on the NPK reader from Irrlicht
#include "CNPKReader.h"
#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
#include "os.h"
#include "coreutil.h"
#ifdef _DEBUG
#define IRR_DEBUG_NPK_READER
#endif
namespace irr
{
namespace io
{
namespace
{
bool isHeaderValid(const SNPKHeader& header)
{
const c8* const tag = header.Tag;
return tag[0] == '0' &&
tag[1] == 'K' &&
tag[2] == 'P' &&
tag[3] == 'N';
}
} // end namespace
//! Constructor
CArchiveLoaderNPK::CArchiveLoaderNPK( io::IFileSystem* fs)
: FileSystem(fs)
{
#ifdef _DEBUG
setDebugName("CArchiveLoaderNPK");
#endif
}
//! returns true if the file maybe is able to be loaded by this class
bool CArchiveLoaderNPK::isALoadableFileFormat(const io::path& filename) const
{
return core::hasFileExtension(filename, "npk");
}
//! Check to see if the loader can create archives of this type.
bool CArchiveLoaderNPK::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
{
return fileType == EFAT_NPK;
}
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
IFileArchive* CArchiveLoaderNPK::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const
{
IFileArchive *archive = 0;
io::IReadFile* file = FileSystem->createAndOpenFile(filename);
if (file)
{
archive = createArchive(file, ignoreCase, ignorePaths);
file->drop ();
}
return archive;
}
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
IFileArchive* CArchiveLoaderNPK::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
{
IFileArchive *archive = 0;
if ( file )
{
file->seek ( 0 );
archive = new CNPKReader(file, ignoreCase, ignorePaths);
}
return archive;
}
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
bool CArchiveLoaderNPK::isALoadableFileFormat(io::IReadFile* file) const
{
SNPKHeader header;
file->read(&header, sizeof(header));
return isHeaderValid(header);
}
/*!
NPK Reader
*/
CNPKReader::CNPKReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
: CFileList(file ? file->getFileName() : "", ignoreCase, ignorePaths), File(file)
{
#ifdef _DEBUG
setDebugName("CNPKReader");
#endif
if (File)
{
File->grab();
if (scanLocalHeader())
sort();
else
os::Printer::log("Failed to load NPK archive.");
}
}
CNPKReader::~CNPKReader()
{
if (File)
File->drop();
}
const IFileList* CNPKReader::getFileList() const
{
return this;
}
bool CNPKReader::scanLocalHeader()
{
SNPKHeader header;
// Read and validate the header
File->read(&header, sizeof(header));
if (!isHeaderValid(header))
return false;
// Seek to the table of contents
#ifdef __BIG_ENDIAN__
header.Offset = os::Byteswap::byteswap(header.Offset);
header.Length = os::Byteswap::byteswap(header.Length);
#endif
header.Offset += 8;
core::stringc dirName;
bool inTOC=true;
// Loop through each entry in the table of contents
while (inTOC && (File->getPos() < File->getSize()))
{
// read an entry
char tag[4]={0};
SNPKFileEntry entry;
File->read(tag, 4);
const int numTag = MAKE_IRR_ID(tag[3],tag[2],tag[1],tag[0]);
int size;
bool isDir=true;
switch (numTag)
{
case MAKE_IRR_ID('D','I','R','_'):
{
File->read(&size, 4);
readString(entry.Name);
entry.Length=0;
entry.Offset=0;
#ifdef IRR_DEBUG_NPK_READER
os::Printer::log("Dir", entry.Name);
#endif
}
break;
case MAKE_IRR_ID('F','I','L','E'):
{
File->read(&size, 4);
File->read(&entry.Offset, 4);
File->read(&entry.Length, 4);
readString(entry.Name);
isDir=false;
#ifdef IRR_DEBUG_NPK_READER
os::Printer::log("File", entry.Name);
#endif
#ifdef __BIG_ENDIAN__
entry.Offset = os::Byteswap::byteswap(entry.Offset);
entry.Length = os::Byteswap::byteswap(entry.Length);
#endif
}
break;
case MAKE_IRR_ID('D','E','N','D'):
{
File->read(&size, 4);
entry.Name="";
entry.Length=0;
entry.Offset=0;
const s32 pos = dirName.findLast('/', dirName.size()-2);
if (pos==-1)
dirName="";
else
dirName=dirName.subString(0, pos);
#ifdef IRR_DEBUG_NPK_READER
os::Printer::log("Dirend", dirName);
#endif
}
break;
default:
inTOC=false;
}
// skip root dir
if (isDir)
{
if (!entry.Name.size() || (entry.Name==".") || (entry.Name=="<noname>"))
continue;
dirName += entry.Name;
dirName += "/";
}
#ifdef IRR_DEBUG_NPK_READER
os::Printer::log("Name", entry.Name);
#endif
addItem(isDir?dirName:dirName+entry.Name, entry.Length, isDir, Offsets.size());
Offsets.push_back(entry.Offset+header.Offset);
}
return true;
}
//! opens a file by file name
IReadFile* CNPKReader::createAndOpenFile(const io::path& filename)
{
s32 index = findFile(filename, false);
if (index != -1)
return createAndOpenFile(index);
return 0;
}
//! opens a file by index
IReadFile* CNPKReader::createAndOpenFile(u32 index)
{
if (index < Files.size())
{
return createLimitReadFile(Files[index].FullName, File, Offsets[Files[index].ID], Files[index].Size);
}
else
return 0;
}
void CNPKReader::readString(core::stringc& name)
{
short stringSize;
char buf[256];
File->read(&stringSize, 2);
#ifdef __BIG_ENDIAN__
stringSize = os::Byteswap::byteswap(stringSize);
#endif
name.reserve(stringSize);
while(stringSize)
{
const short next = core::min_(stringSize, (short)255);
File->read(buf,next);
buf[next]=0;
name.append(buf);
stringSize -= next;
}
}
} // end namespace io
} // end namespace irr
#endif // __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_

View File

@ -0,0 +1,131 @@
// Copyright (C) 2002-2009 Nikolaus Gebhardt
// Copyright (C) 2009 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_NPK_READER_H_INCLUDED__
#define __C_NPK_READER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
#include "IReferenceCounted.h"
#include "IReadFile.h"
#include "irrArray.h"
#include "irrString.h"
#include "IFileSystem.h"
#include "CFileList.h"
namespace irr
{
namespace io
{
namespace
{
//! File header containing location and size of the table of contents
struct SNPKHeader
{
// Don't change the order of these fields! They must match the order stored on disk.
c8 Tag[4];
u32 Length;
u32 Offset;
};
//! An entry in the NPK file's table of contents.
struct SNPKFileEntry
{
core::stringc Name;
u32 Offset;
u32 Length;
};
} // end namespace
//! Archiveloader capable of loading Nebula Device 2 NPK Archives
class CArchiveLoaderNPK : public IArchiveLoader
{
public:
//! Constructor
CArchiveLoaderNPK(io::IFileSystem* fs);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".zip")
virtual bool isALoadableFileFormat(const io::path& filename) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
//! Returns the type of archive created by this loader
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_NPK; }
private:
io::IFileSystem* FileSystem;
};
//! reads from NPK
class CNPKReader : public virtual IFileArchive, virtual CFileList
{
public:
CNPKReader(IReadFile* file, bool ignoreCase, bool ignorePaths);
virtual ~CNPKReader();
// file archive methods
//! return the id of the file Archive
virtual const io::path& getArchiveName() const
{
return File->getFileName();
}
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const io::path& filename);
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the class Type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_NPK; }
private:
//! scans for a local header, returns false if the header is invalid
bool scanLocalHeader();
void readString(core::stringc& name);
IReadFile* File;
//! Contains offsets of the files from the start of the archive file
core::array<u32> Offsets;
};
} // end namespace io
} // end namespace irr
#endif // __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
#endif // __C_NPK_READER_H_INCLUDED__

View File

@ -554,6 +554,14 @@ bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer
}
//! Sets multiple render targets
bool CNullDriver::setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer, bool clearZBuffer, SColor color)
{
return false;
}
//! sets a viewport
void CNullDriver::setViewPort(const core::rect<s32>& area)
{
@ -697,6 +705,9 @@ void CNullDriver::draw2DImage(const video::ITexture* texture, const core::rect<s
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture)
{
draw2DImage(texture, core::position2d<s32>(destRect.UpperLeftCorner),
sourceRect, clipRect, colors?colors[0]:0xffffffff,
useAlphaChannelOfTexture);
}
@ -1606,9 +1617,12 @@ io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMateria
prefix = "AnisotropicFilter";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].AnisotropicFilter);
prefix="TextureWrap";
prefix="TextureWrapU";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrap, aTextureClampNames);
attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapU, aTextureClampNames);
prefix="TextureWrapV";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapV, aTextureClampNames);
prefix="LODBias";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].LODBias);
@ -1681,8 +1695,22 @@ void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMater
outMaterial.TextureLayer[i].AnisotropicFilter = attr->getAttributeAsInt((prefix+core::stringc(i+1)).c_str());
prefix = "TextureWrap";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
outMaterial.TextureLayer[i].TextureWrap = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+core::stringc(i+1)).c_str(), aTextureClampNames);
if (attr->existsAttribute(prefix.c_str())) // legacy
{
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{
outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+core::stringc(i+1)).c_str(), aTextureClampNames);
outMaterial.TextureLayer[i].TextureWrapV = outMaterial.TextureLayer[i].TextureWrapU;
}
}
else
{
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{
outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"U"+core::stringc(i+1)).c_str(), aTextureClampNames);
outMaterial.TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"V"+core::stringc(i+1)).c_str(), aTextureClampNames);
}
}
// default 0 is ok
prefix="LODBias";

View File

@ -98,6 +98,10 @@ namespace video
virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color);
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=SColor(0,0,0,0));
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area);

View File

@ -23,10 +23,13 @@ namespace irr
namespace scene
{
namespace
{
enum OGRE_CHUNKS
{
// Main Chunks
COGRE_HEADER= 0x1000,
COGRE_SKELETON= 0x2000,
COGRE_MESH= 0x3000,
// sub chunks of COGRE_MESH
@ -39,6 +42,13 @@ namespace scene
COGRE_MESH_SUBMESH_NAME_TABLE= 0xA000,
COGRE_MESH_EDGE_LISTS= 0xB000,
// sub chunks of COGRE_SKELETON
COGRE_BONE_PARENT= 0x3000,
COGRE_ANIMATION= 0x4000,
COGRE_ANIMATION_TRACK= 0x4100,
COGRE_ANIMATION_KEYFRAME= 0x4110,
COGRE_ANIMATION_LINK= 0x5000,
// sub chunks of COGRE_SUBMESH
COGRE_SUBMESH_OPERATION= 0x4010,
COGRE_SUBMESH_BONE_ASSIGNMENT= 0x4100,
@ -50,6 +60,7 @@ namespace scene
COGRE_GEOMETRY_VERTEX_BUFFER= 0x5200,
COGRE_GEOMETRY_VERTEX_BUFFER_DATA= 0x5210
};
}
//! Constructor
COgreMeshFileLoader::COgreMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver)
@ -120,23 +131,34 @@ IAnimatedMesh* COgreMeshFileLoader::createMesh(io::IReadFile* file)
CurrentlyLoadingFromPath = FileSystem->getFileDir(file->getFileName());
loadMaterials(file);
Mesh = new SMesh();
if (readChunk(file))
{
// success
SAnimatedMesh* am = new SAnimatedMesh();
am->Type = EAMT_3DS;
// delete data loaded from file
clearMeshes();
for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox();
if (Skeleton.Bones.size())
{
ISkinnedMesh* tmp = static_cast<CSkinnedMesh*>(Mesh);
static_cast<CSkinnedMesh*>(Mesh)->updateBoundingBox();
Skeleton.Animations.clear();
Skeleton.Bones.clear();
Mesh=0;
return tmp;
}
else
{
for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox();
Mesh->recalculateBoundingBox();
am->addMesh(Mesh);
am->recalculateBoundingBox();
Mesh->drop();
Mesh = 0;
((SMesh*)Mesh)->recalculateBoundingBox();
SAnimatedMesh* am = new SAnimatedMesh();
am->Type = EAMT_3DS;
am->addMesh(Mesh);
am->recalculateBoundingBox();
Mesh->drop();
Mesh = 0;
return am;
}
}
Mesh->drop();
@ -159,6 +181,10 @@ bool COgreMeshFileLoader::readChunk(io::IReadFile* file)
{
Meshes.push_back(OgreMesh());
readObjectChunk(file, data, Meshes.getLast());
if (Skeleton.Bones.size())
Mesh = new CSkinnedMesh();
else
Mesh = new SMesh();
composeObject();
}
break;
@ -177,6 +203,7 @@ bool COgreMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData& parent
os::Printer::log("Read Object Chunk");
#endif
readBool(file, parent, mesh.SkeletalAnimation);
bool skeleton_loaded=false;
while ((parent.read < parent.header.length)&&(file->getPos() < file->getSize()))
{
ChunkData data;
@ -195,27 +222,46 @@ bool COgreMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData& parent
break;
case COGRE_MESH_BOUNDS:
{
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Read Mesh Bounds");
#endif
readVector(file, data, mesh.BBoxMinEdge);
readVector(file, data, mesh.BBoxMaxEdge);
readFloat(file, data, &mesh.BBoxRadius);
}
break;
case COGRE_SKELETON_LINK:
{
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Read Skeleton link");
#endif
core::stringc name;
readString(file, data, name);
loadSkeleton(file, name);
skeleton_loaded=true;
}
break;
case COGRE_BONE_ASSIGNMENT:
{
mesh.BoneAssignments.push_back(OgreBoneAssignment());
readInt(file, data, &mesh.BoneAssignments.getLast().VertexID);
readShort(file, data, &mesh.BoneAssignments.getLast().BoneID);
readFloat(file, data, &mesh.BoneAssignments.getLast().Weight);
}
break;
case COGRE_MESH_LOD:
case COGRE_MESH_SUBMESH_NAME_TABLE:
case COGRE_MESH_EDGE_LISTS:
default:
// ignore chunk
file->seek(data.header.length-data.read, true);
data.read += data.header.length-data.read;
break;
default:
parent.read=parent.header.length;
file->seek(-(long)sizeof(ChunkHeader), true);
return true;
}
parent.read += data.read;
}
if (!skeleton_loaded)
loadSkeleton(file, FileSystem->getFileBasename(file->getFileName(), false));
return true;
}
@ -359,9 +405,17 @@ bool COgreMeshFileLoader::readSubMesh(io::IReadFile* file, ChunkData& parent, Og
{
case COGRE_SUBMESH_OPERATION:
readShort(file, data, &subMesh.Operation);
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Read Submesh Operation",core::stringc(subMesh.Operation));
#endif
if (subMesh.Operation != 4)
os::Printer::log("Primitive type != trilist not yet implemented", ELL_WARNING);
break;
case COGRE_SUBMESH_TEXTURE_ALIAS:
{
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Read Submesh Texture Alias");
#endif
core::stringc texture, alias;
readString(file, data, texture);
readString(file, data, alias);
@ -369,9 +423,12 @@ bool COgreMeshFileLoader::readSubMesh(io::IReadFile* file, ChunkData& parent, Og
}
break;
case COGRE_SUBMESH_BONE_ASSIGNMENT:
// currently ignore chunk
file->seek(data.header.length-data.read, true);
data.read += data.header.length-data.read;
{
subMesh.BoneAssignments.push_back(OgreBoneAssignment());
readInt(file, data, &subMesh.BoneAssignments.getLast().VertexID);
readShort(file, data, &subMesh.BoneAssignments.getLast().BoneID);
readFloat(file, data, &subMesh.BoneAssignments.getLast().Weight);
}
break;
default:
parent.read=parent.header.length;
@ -394,19 +451,10 @@ void COgreMeshFileLoader::composeMeshBufferMaterial(scene::IMeshBuffer* mb, cons
material=Materials[k].Techniques[0].Passes[0].Material;
if (Materials[k].Techniques[0].Passes[0].Texture.Filename.size())
{
material.setTexture(0, Driver->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename));
if (!material.getTexture(0))
{
// retry with relative path
core::stringc relative = Materials[k].Techniques[0].Passes[0].Texture.Filename;
s32 idx = relative.findLast('\\');
if (idx != -1)
relative = relative.subString(idx+1, relative.size()-idx-1);
idx = relative.findLast('/');
if (idx != -1)
relative = relative.subString(idx+1, relative.size()-idx-1);
material.setTexture(0, Driver->getTexture((CurrentlyLoadingFromPath+"/"+relative)));
}
if (FileSystem->existFile(Materials[k].Techniques[0].Passes[0].Texture.Filename))
material.setTexture(0, Driver->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename));
else
material.setTexture(0, Driver->getTexture((CurrentlyLoadingFromPath+"/"+FileSystem->getFileBasename(Materials[k].Techniques[0].Passes[0].Texture.Filename))));
}
break;
}
@ -554,6 +602,91 @@ scene::SMeshBufferLightMap* COgreMeshFileLoader::composeMeshBufferLightMap(const
}
scene::IMeshBuffer* COgreMeshFileLoader::composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array<s32>& indices, const OgreGeometry& geom)
{
scene::SSkinMeshBuffer *mb=mesh.addMeshBuffer();
if (NumUV>1)
{
mb->convertTo2TCoords();
mb->Vertices_2TCoords.set_used(geom.NumVertex);
}
else
mb->Vertices_Standard.set_used(geom.NumVertex);
u32 i;
mb->Indices.set_used(indices.size());
for (i=0; i<indices.size(); i+=3)
{
mb->Indices[i+0]=indices[i+2];
mb->Indices[i+1]=indices[i+1];
mb->Indices[i+2]=indices[i+0];
}
for (i=0; i<geom.Elements.size(); ++i)
{
if (geom.Elements[i].Semantic==1) //Pos
{
for (u32 j=0; j<geom.Buffers.size(); ++j)
{
if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
{
u32 eSize=geom.Buffers[j].VertexSize;
u32 ePos=geom.Elements[i].Offset;
for (s32 k=0; k<geom.NumVertex; ++k)
{
if (NumUV>1)
mb->Vertices_2TCoords[k].Color=mb->Material.DiffuseColor;
else
mb->Vertices_Standard[k].Color=mb->Material.DiffuseColor;
mb->getPosition(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
ePos += eSize;
}
}
}
}
if (geom.Elements[i].Semantic==4) //Normal
{
for (u32 j=0; j<geom.Buffers.size(); ++j)
{
if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
{
u32 eSize=geom.Buffers[j].VertexSize;
u32 ePos=geom.Elements[i].Offset;
for (s32 k=0; k<geom.NumVertex; ++k)
{
mb->getNormal(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
ePos += eSize;
}
}
}
}
if (geom.Elements[i].Semantic==7) //TexCoord
{
for (u32 j=0; j<geom.Buffers.size(); ++j)
{
if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
{
u32 eSize=geom.Buffers[j].VertexSize;
u32 ePos=geom.Elements[i].Offset;
for (s32 k=0; k<geom.NumVertex; ++k)
{
mb->getTCoords(k).set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
if (NumUV>1)
mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]);
ePos += eSize;
}
}
}
}
}
return mb;
}
void COgreMeshFileLoader::composeObject(void)
{
for (u32 i=0; i<Meshes.size(); ++i)
@ -563,7 +696,11 @@ void COgreMeshFileLoader::composeObject(void)
IMeshBuffer* mb;
if (Meshes[i].SubMeshes[j].SharedVertices)
{
if (NumUV < 2)
if (Skeleton.Bones.size())
{
mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
}
else if (NumUV < 2)
{
mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
}
@ -574,7 +711,11 @@ void COgreMeshFileLoader::composeObject(void)
}
else
{
if (NumUV < 2)
if (Skeleton.Bones.size())
{
mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
}
else if (NumUV < 2)
{
mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
}
@ -587,11 +728,79 @@ void COgreMeshFileLoader::composeObject(void)
if (mb != 0)
{
composeMeshBufferMaterial(mb, Meshes[i].SubMeshes[j].Material);
Mesh->addMeshBuffer(mb);
mb->drop();
if (!Skeleton.Bones.size())
{
((SMesh*)Mesh)->addMeshBuffer(mb);
mb->drop();
}
}
}
}
if (Skeleton.Bones.size())
{
CSkinnedMesh* m = (CSkinnedMesh*)Mesh;
// Create Joints
for (u32 i=0; i<Skeleton.Bones.size(); ++i)
{
ISkinnedMesh::SJoint* joint = m->addJoint();
joint->Name=Skeleton.Bones[i].Name;
joint->LocalMatrix = Skeleton.Bones[i].Orientation.getMatrix();
if (Skeleton.Bones[i].Scale != core::vector3df(1,1,1))
{
core::matrix4 scaleMatrix;
scaleMatrix.setScale( Skeleton.Bones[i].Scale );
joint->LocalMatrix *= scaleMatrix;
}
joint->LocalMatrix.setTranslation( Skeleton.Bones[i].Position );
}
// Joints hierarchy
for (u32 i=0; i<Skeleton.Bones.size(); ++i)
{
if (Skeleton.Bones[i].Parent<m->getJointCount())
{
m->getAllJoints()[Skeleton.Bones[i].Parent]->Children.push_back(m->getAllJoints()[Skeleton.Bones[i].Handle]);
}
}
// Weights
u32 bufCount=0;
for (u32 i=0; i<Meshes.size(); ++i)
{
for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j)
{
for (u32 k=0; k<Meshes[i].SubMeshes[j].BoneAssignments.size(); ++k)
{
OgreBoneAssignment& ba = Meshes[i].SubMeshes[j].BoneAssignments[k];
ISkinnedMesh::SWeight* w = m->addWeight(m->getAllJoints()[ba.BoneID]);
w->strength=ba.Weight;
w->vertex_id=ba.VertexID;
w->buffer_id=bufCount;
}
++bufCount;
}
}
#if 0
// currently not working correctly
for (u32 i=0; i<Skeleton.Animations.size(); ++i)
{
for (u32 j=0; j<Skeleton.Animations[i].Keyframes.size(); ++j)
{
ISkinnedMesh::SPositionKey* poskey = m->addPositionKey(m->getAllJoints()[Skeleton.Animations[i].Keyframes[j].BoneID]);
poskey->frame=Skeleton.Animations[i].Keyframes[j].Time;
poskey->position=Skeleton.Animations[i].Keyframes[j].Position;
ISkinnedMesh::SRotationKey* rotkey = m->addRotationKey(m->getAllJoints()[Skeleton.Animations[i].Keyframes[j].BoneID]);
rotkey->frame=Skeleton.Animations[i].Keyframes[j].Time;
rotkey->rotation=Skeleton.Animations[i].Keyframes[j].Orientation;
ISkinnedMesh::SScaleKey* scalekey = m->addScaleKey(m->getAllJoints()[Skeleton.Animations[i].Keyframes[j].BoneID]);
scalekey->frame=Skeleton.Animations[i].Keyframes[j].Time;
scalekey->scale=Skeleton.Animations[i].Keyframes[j].Scale;
}
}
#endif
m->finalize();
}
}
@ -1007,19 +1216,22 @@ void COgreMeshFileLoader::readTechnique(io::IReadFile* file, OgreMaterial& mat)
}
void COgreMeshFileLoader::loadMaterials(io::IReadFile* meshFile)
{
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Load Materials");
#endif
core::stringc token = meshFile->getFileName();
io::path filename = token.subString(0, token.size()-4) + L"material";
io::IReadFile* file = FileSystem->createAndOpenFile(filename.c_str());
core::stringc token;
io::IReadFile* file = 0;
io::path filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".material";
if (FileSystem->existFile(filename))
file = FileSystem->createAndOpenFile(filename);
else
file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename);
if (!file)
{
os::Printer::log("Could not load OGRE material", filename.c_str());
os::Printer::log("Could not load OGRE material", filename);
return;
}
@ -1095,6 +1307,143 @@ void COgreMeshFileLoader::loadMaterials(io::IReadFile* meshFile)
}
bool COgreMeshFileLoader::loadSkeleton(io::IReadFile* meshFile, const core::stringc& name)
{
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Load Skeleton", name);
#endif
io::IReadFile* file = 0;
io::path filename;
if (FileSystem->existFile(name))
file = FileSystem->createAndOpenFile(name);
else if (FileSystem->existFile(filename = FileSystem->getFileDir(meshFile->getFileName())+"/"+name))
file = FileSystem->createAndOpenFile(filename);
else if (FileSystem->existFile(filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".skeleton"))
file = FileSystem->createAndOpenFile(filename);
else
file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename);
if (!file)
{
os::Printer::log("Could not load matching skeleton", name);
return false;
}
s16 id;
file->read(&id, 2);
if (SwapEndian)
id = os::Byteswap::byteswap(id);
if (id != COGRE_HEADER)
{
file->drop();
return false;
}
core::stringc skeletonVersion;
ChunkData head;
readString(file, head, skeletonVersion);
if (skeletonVersion != "[Serializer_v1.10]")
{
file->drop();
return false;
}
u16 bone=0;
f32 animationTotal=0.f;
while(file->getPos() < file->getSize())
{
ChunkData data;
readChunkData(file, data);
switch(data.header.id)
{
case COGRE_SKELETON:
{
Skeleton.Bones.push_back(OgreBone());
OgreBone& bone = Skeleton.Bones.getLast();
readString(file, data, bone.Name);
readShort(file, data, &bone.Handle);
readVector(file, data, bone.Position);
readQuaternion(file, data, bone.Orientation);
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Bone", bone.Name+" ("+core::stringc(bone.Handle)+")");
// os::Printer::log("Position", core::stringc(bone.Position.X)+" "+core::stringc(bone.Position.Y)+" "+core::stringc(bone.Position.Z));
// os::Printer::log("Rotation quat", core::stringc(bone.Orientation.W)+" "+core::stringc(bone.Orientation.X)+" "+core::stringc(bone.Orientation.Y)+" "+core::stringc(bone.Orientation.Z));
// core::vector3df rot;
// bone.Orientation.toEuler(rot);
// rot *= core::RADTODEG;
// os::Printer::log("Rotation", core::stringc(rot.X)+" "+core::stringc(rot.Y)+" "+core::stringc(rot.Z));
#endif
if (data.read<(data.header.length-bone.Name.size()))
{
readVector(file, data, bone.Scale);
bone.Scale.X *= -1.f;
}
else
bone.Scale=core::vector3df(1,1,1);
bone.Parent=0xffff;
}
break;
case COGRE_BONE_PARENT:
{
u16 parent;
readShort(file, data, &bone);
readShort(file, data, &parent);
if (bone<Skeleton.Bones.size() && parent<Skeleton.Bones.size())
Skeleton.Bones[bone].Parent=parent;
}
break;
case COGRE_ANIMATION:
{
if (Skeleton.Animations.size())
animationTotal+=Skeleton.Animations.getLast().Length;
Skeleton.Animations.push_back(OgreAnimation());
OgreAnimation& anim = Skeleton.Animations.getLast();
readString(file, data, anim.Name);
readFloat(file, data, &anim.Length);
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Animation", anim.Name);
os::Printer::log("Length", core::stringc(anim.Length));
#endif
}
break;
case COGRE_ANIMATION_TRACK:
#ifdef IRR_OGRE_LOADER_DEBUG
// os::Printer::log("for Bone ", core::stringc(bone));
#endif
readShort(file, data, &bone); // store current bone
break;
case COGRE_ANIMATION_KEYFRAME:
{
Skeleton.Animations.getLast().Keyframes.push_back(OgreKeyframe());
OgreKeyframe& keyframe = Skeleton.Animations.getLast().Keyframes.getLast();
readFloat(file, data, &keyframe.Time);
keyframe.Time+=animationTotal;
readVector(file, data, keyframe.Position);
readQuaternion(file, data, keyframe.Orientation);
if (data.read<data.header.length)
{
readVector(file, data, keyframe.Scale);
keyframe.Scale.X *= -1.f;
}
else
keyframe.Scale=core::vector3df(1,1,1);
keyframe.BoneID=bone;
}
break;
case COGRE_ANIMATION_LINK:
#ifdef IRR_OGRE_LOADER_DEBUG
os::Printer::log("Animation link");
#endif
break;
default:
break;
}
}
file->drop();
return true;
}
void COgreMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data)
{
file->read(&data.header, sizeof(ChunkHeader));
@ -1177,6 +1526,14 @@ void COgreMeshFileLoader::readVector(io::IReadFile* file, ChunkData& data, core:
readFloat(file, data, &out.X);
readFloat(file, data, &out.Y);
readFloat(file, data, &out.Z);
out.X *= -1.f;
}
void COgreMeshFileLoader::readQuaternion(io::IReadFile* file, ChunkData& data, core::quaternion& out)
{
readVector(file, data, *((core::vector3df*)&out.X));
readFloat(file, data, &out.W);
}
@ -1202,3 +1559,4 @@ void COgreMeshFileLoader::clearMeshes()
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OGRE_LOADER_

View File

@ -15,6 +15,8 @@
#include "SMeshBufferLightMap.h"
#include "IMeshManipulator.h"
#include "matrix4.h"
#include "quaternion.h"
#include "CSkinnedMesh.h"
namespace irr
{
@ -168,6 +170,13 @@ private:
core::stringc Alias;
};
struct OgreBoneAssignment
{
s32 VertexID;
u16 BoneID;
f32 Weight;
};
struct OgreSubMesh
{
core::stringc Material;
@ -176,6 +185,7 @@ private:
OgreGeometry Geometry;
u16 Operation;
core::array<OgreTextureAlias> TextureAliases;
core::array<OgreBoneAssignment> BoneAssignments;
bool Indices32Bit;
};
@ -184,11 +194,44 @@ private:
bool SkeletalAnimation;
OgreGeometry Geometry;
core::array<OgreSubMesh> SubMeshes;
core::array<OgreBoneAssignment> BoneAssignments;
core::vector3df BBoxMinEdge;
core::vector3df BBoxMaxEdge;
f32 BBoxRadius;
};
struct OgreBone
{
core::stringc Name;
core::vector3df Position;
core::quaternion Orientation;
core::vector3df Scale;
u16 Handle;
u16 Parent;
};
struct OgreKeyframe
{
u16 BoneID;
f32 Time;
core::vector3df Position;
core::quaternion Orientation;
core::vector3df Scale;
};
struct OgreAnimation
{
core::stringc Name;
f32 Length;
core::array<OgreKeyframe> Keyframes;
};
struct OgreSkeleton
{
core::array<OgreBone> Bones;
core::array<OgreAnimation> Animations;
};
bool readChunk(io::IReadFile* file);
bool readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh);
bool readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry);
@ -203,16 +246,19 @@ private:
void readShort(io::IReadFile* file, ChunkData& data, u16* out, u32 num=1);
void readFloat(io::IReadFile* file, ChunkData& data, f32* out, u32 num=1);
void readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out);
void readQuaternion(io::IReadFile* file, ChunkData& data, core::quaternion& out);
void composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName);
scene::SMeshBuffer* composeMeshBuffer(const core::array<s32>& indices, const OgreGeometry& geom);
scene::SMeshBufferLightMap* composeMeshBufferLightMap(const core::array<s32>& indices, const OgreGeometry& geom);
scene::IMeshBuffer* composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array<s32>& indices, const OgreGeometry& geom);
void composeObject(void);
bool readColor(io::IReadFile* meshFile, video::SColor& col);
void getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine=false);
void readTechnique(io::IReadFile* meshFile, OgreMaterial& mat);
void readPass(io::IReadFile* file, OgreTechnique& technique);
void loadMaterials(io::IReadFile* file);
bool loadSkeleton(io::IReadFile* meshFile, const core::stringc& name);
core::stringc getTextureFileName(const core::stringc& texture, core::stringc& model);
void clearMeshes();
@ -225,8 +271,9 @@ private:
io::path CurrentlyLoadingFromPath;
core::array<OgreMaterial> Materials;
OgreSkeleton Skeleton;
SMesh* Mesh;
IMesh* Mesh;
u32 NumUV;
};

View File

@ -74,201 +74,213 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
GLuint PixelFormat;
if (AntiAlias > 1)
{
// Create a window to test antialiasing support
// Create a window to test antialiasing support
const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32");
HINSTANCE lhInstance = GetModuleHandle(0);
HINSTANCE lhInstance = GetModuleHandle(0);
// Register Class
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)DefWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = lhInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = ClassName;
wcex.hIconSm = 0;
wcex.hIcon = 0;
// Register Class
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)DefWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = lhInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = ClassName;
wcex.hIconSm = 0;
wcex.hIcon = 0;
RegisterClassEx(&wcex);
RECT clientSize;
clientSize.top = 0;
clientSize.left = 0;
clientSize.right = params.WindowSize.Width;
clientSize.bottom = params.WindowSize.Height;
RegisterClassEx(&wcex);
RECT clientSize;
clientSize.top = 0;
clientSize.left = 0;
clientSize.right = params.WindowSize.Width;
clientSize.bottom = params.WindowSize.Height;
DWORD style = WS_POPUP;
DWORD style = WS_POPUP;
if (!params.Fullscreen)
style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
if (!params.Fullscreen)
style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
AdjustWindowRect(&clientSize, style, FALSE);
AdjustWindowRect(&clientSize, style, FALSE);
const s32 realWidth = clientSize.right - clientSize.left;
const s32 realHeight = clientSize.bottom - clientSize.top;
const s32 realWidth = clientSize.right - clientSize.left;
const s32 realHeight = clientSize.bottom - clientSize.top;
const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;
const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;
HWND temporary_wnd=CreateWindow(ClassName, __TEXT(""), style, windowLeft, windowTop,
realWidth, realHeight, NULL, NULL, lhInstance, NULL);
if (!temporary_wnd)
{
os::Printer::log("Cannot create a temporary window.", ELL_ERROR);
return false;
}
if (!temporary_wnd)
{
os::Printer::log("Cannot create a temporary window.", ELL_ERROR);
return false;
}
HDc = GetDC(temporary_wnd);
for (u32 i=0; i<5; ++i)
HDc = GetDC(temporary_wnd);
for (u32 i=0; i<5; ++i)
{
if (i == 1)
{
if (i == 1)
if (params.Stencilbuffer)
{
if (params.Stencilbuffer)
{
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
continue;
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
if (i == 2)
{
pfd.cDepthBits = 24;
}
if (i == 3)
{
if (params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
}
else
if (i == 4)
{
// try single buffer
if (params.Doublebuffer)
pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
else
continue;
}
else
if (i == 5)
{
os::Printer::log("Cannot create a GL device context", "No suitable format for temporary window.", ELL_ERROR);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
// choose pixelformat
PixelFormat = ChoosePixelFormat(HDc, &pfd);
if (PixelFormat)
break;
}
SetPixelFormat(HDc, PixelFormat, &pfd);
HRc=wglCreateContext(HDc);
if (!HRc)
{
os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
if (!wglMakeCurrent(HDc, HRc))
{
os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR);
wglDeleteContext(HRc);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
#ifdef WGL_ARB_pixel_format
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
if (wglChoosePixelFormat_ARB)
{
// This value determines the number of samples used for antialiasing
// My experience is that 8 does not show a big
// improvement over 4, but 4 shows a big improvement
// over 2.
if(AntiAlias > 32)
AntiAlias = 32;
f32 fAttributes[] = {0.0, 0.0};
s32 iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB,(params.Bits==32) ? 24 : 15,
WGL_ALPHA_BITS_ARB,(params.Bits==32) ? 8 : 1,
WGL_DEPTH_BITS_ARB,params.ZBufferBits, // 10,11
WGL_STENCIL_BITS_ARB,(params.Stencilbuffer) ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,(params.Doublebuffer) ? GL_TRUE : GL_FALSE,
WGL_STEREO_ARB,(params.Stereobuffer) ? GL_TRUE : GL_FALSE,
#ifdef WGL_ARB_multisample
WGL_SAMPLE_BUFFERS_ARB, 1,
WGL_SAMPLES_ARB,AntiAlias, // 20,21
#elif defined(WGL_EXT_multisample)
WGL_SAMPLE_BUFFERS_EXT, 1,
WGL_SAMPLES_EXT,AntiAlias, // 20,21
#elif defined(WGL_3DFX_multisample)
WGL_SAMPLE_BUFFERS_3DFX, 1,
WGL_SAMPLES_3DFX,AntiAlias, // 20,21
#endif
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
// other possible values:
// WGL_ARB_pixel_format_float: WGL_TYPE_RGBA_FLOAT_ARB
// WGL_EXT_pixel_format_packed_float: WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT
#if 0
#ifdef WGL_EXT_framebuffer_sRGB
WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, GL_FALSE,
#endif
#endif
0,0
};
s32 rv=0;
// Try to get an acceptable pixel format
while(rv==0 && iAttributes[21]>1)
{
s32 pixelFormat=0;
u32 numFormats=0;
const s32 valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
if (valid && numFormats>0)
rv = pixelFormat;
else
iAttributes[21] -= 1;
}
if (rv)
{
PixelFormat=rv;
AntiAlias=iAttributes[21];
}
continue;
}
else
#endif
AntiAlias=0;
if (i == 2)
{
pfd.cDepthBits = 24;
}
if (i == 3)
{
if (params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
}
else
if (i == 4)
{
// try single buffer
if (params.Doublebuffer)
pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
else
continue;
}
else
if (i == 5)
{
os::Printer::log("Cannot create a GL device context", "No suitable format for temporary window.", ELL_ERROR);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
wglMakeCurrent(HDc, NULL);
// choose pixelformat
PixelFormat = ChoosePixelFormat(HDc, &pfd);
if (PixelFormat)
break;
}
SetPixelFormat(HDc, PixelFormat, &pfd);
HRc=wglCreateContext(HDc);
if (!HRc)
{
os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
if (!wglMakeCurrent(HDc, HRc))
{
os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR);
wglDeleteContext(HRc);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
#ifdef _DEBUG
core::stringc wglExtensions;
#ifdef WGL_ARB_extensions_string
PFNWGLGETEXTENSIONSSTRINGARBPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
if (irrGetExtensionsString)
wglExtensions = irrGetExtensionsString(HDc);
#elif defined(WGL_EXT_extensions_string)
PFNWGLGETEXTENSIONSSTRINGEXTPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
if (irrGetExtensionsString)
wglExtensions = irrGetExtensionsString(HDc);
#endif
os::Printer::log("WGL_extensions", wglExtensions);
#endif
#ifdef WGL_ARB_pixel_format
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
if (wglChoosePixelFormat_ARB)
{
// This value determines the number of samples used for antialiasing
// My experience is that 8 does not show a big
// improvement over 4, but 4 shows a big improvement
// over 2.
if(AntiAlias > 32)
AntiAlias = 32;
f32 fAttributes[] = {0.0, 0.0};
s32 iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB,(params.Bits==32) ? 24 : 15,
WGL_ALPHA_BITS_ARB,(params.Bits==32) ? 8 : 1,
WGL_DEPTH_BITS_ARB,params.ZBufferBits, // 10,11
WGL_STENCIL_BITS_ARB,(params.Stencilbuffer) ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,(params.Doublebuffer) ? GL_TRUE : GL_FALSE,
WGL_STEREO_ARB,(params.Stereobuffer) ? GL_TRUE : GL_FALSE,
#ifdef WGL_ARB_multisample
WGL_SAMPLE_BUFFERS_ARB, 1,
WGL_SAMPLES_ARB,AntiAlias, // 20,21
#elif defined(WGL_EXT_multisample)
WGL_SAMPLE_BUFFERS_EXT, 1,
WGL_SAMPLES_EXT,AntiAlias, // 20,21
#elif defined(WGL_3DFX_multisample)
WGL_SAMPLE_BUFFERS_3DFX, 1,
WGL_SAMPLES_3DFX,AntiAlias, // 20,21
#endif
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
// other possible values:
// WGL_ARB_pixel_format_float: WGL_TYPE_RGBA_FLOAT_ARB
// WGL_EXT_pixel_format_packed_float: WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT
#if 0
#ifdef WGL_EXT_framebuffer_sRGB
WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, GL_FALSE,
#endif
#endif
0,0
};
s32 rv=0;
// Try to get an acceptable pixel format
while(rv==0 && iAttributes[21]>1)
{
s32 pixelFormat=0;
u32 numFormats=0;
const s32 valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
if (valid && numFormats>0)
rv = pixelFormat;
else
iAttributes[21] -= 1;
}
if (rv)
{
PixelFormat=rv;
AntiAlias=iAttributes[21];
}
}
else
#endif
AntiAlias=0;
wglMakeCurrent(HDc, NULL);
wglDeleteContext(HRc);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
// get hdc
HDc=GetDC(Window);
if (!HDc)
@ -330,7 +342,15 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
#ifdef WGL_ARB_create_context
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
if (wglCreateContextAttribs_ARB)
HRc=wglCreateContextAttribs_ARB(HDc, 0, NULL);
{
int iAttribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
0
};
HRc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs);
}
else
#endif
HRc=wglCreateContext(HDc);
@ -440,6 +460,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
genericDriverInit(params.WindowSize, params.Stencilbuffer);
// set vsync
//TODO: Check GLX_EXT_swap_control and GLX_MESA_swap_control
#ifdef GLX_SGI_swap_control
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
if (params.Vsync && glxSwapIntervalSGI)
@ -529,7 +550,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
if (renderer && vendor)
{
os::Printer::log(reinterpret_cast<const c8*>(renderer), reinterpret_cast<const c8*>(vendor), ELL_INFORMATION);
vendorName = reinterpret_cast<const c8*>(vendor);
VendorName = reinterpret_cast<const c8*>(vendor);
}
u32 i;
@ -552,6 +573,13 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
// Reset The Current Viewport
glViewport(0, 0, screenSize.Width, screenSize.Height);
UserClipPlanes.reallocate(MaxUserClipPlanes);
for (i=0; i<MaxUserClipPlanes; ++i)
UserClipPlanes.push_back(SUserClipPlane());
for (i=0; i<ETS_COUNT; ++i)
setTransform(static_cast<E_TRANSFORMATION_STATE>(i), core::IdentityMatrix);
setAmbientLight(SColorf(0.0f,0.0f,0.0f,0.0f));
#ifdef GL_EXT_separate_specular_color
if (FeatureAvailable[IRR_EXT_separate_specular_color])
@ -574,14 +602,6 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
extGlProvokingVertex(GL_FIRST_VERTEX_CONVENTION_EXT);
#endif
UserClipPlane.reallocate(MaxUserClipPlanes);
UserClipPlaneEnabled.reallocate(MaxUserClipPlanes);
for (i=0; i<MaxUserClipPlanes; ++i)
{
UserClipPlane.push_back(core::plane3df());
UserClipPlaneEnabled.push_back(false);
}
// create material renderers
createMaterialRenderers();
@ -767,7 +787,7 @@ void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matri
glLoadMatrixf((Matrices[ETS_VIEW] * Matrices[ETS_WORLD]).pointer());
// we have to update the clip planes to the latest view matrix
for (u32 i=0; i<MaxUserClipPlanes; ++i)
if (UserClipPlaneEnabled[i])
if (UserClipPlanes[i].Enabled)
uploadClipPlane(i);
}
break;
@ -1442,7 +1462,7 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
E_MODULATE_FUNC modulo;
u32 alphaSource;
unpack_texureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam);
setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), alphaSource&video::EAS_TEXTURE);
setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0);
}
else
setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL);
@ -2093,6 +2113,108 @@ void COpenGLDriver::setRenderStates3DMode()
}
//! Get native wrap mode value
GLint COpenGLDriver::getTextureWrapMode(const u8 clamp)
{
GLint mode=GL_REPEAT;
switch (clamp)
{
case ETC_REPEAT:
mode=GL_REPEAT;
break;
case ETC_CLAMP:
mode=GL_CLAMP;
break;
case ETC_CLAMP_TO_EDGE:
#ifdef GL_VERSION_1_2
if (Version>101)
mode=GL_CLAMP_TO_EDGE;
else
#endif
#ifdef GL_SGIS_texture_edge_clamp
if (FeatureAvailable[IRR_SGIS_texture_edge_clamp])
mode=GL_CLAMP_TO_EDGE_SGIS;
else
#endif
// fallback
mode=GL_CLAMP;
break;
case ETC_CLAMP_TO_BORDER:
#ifdef GL_VERSION_1_3
if (Version>102)
mode=GL_CLAMP_TO_BORDER;
else
#endif
#ifdef GL_ARB_texture_border_clamp
if (FeatureAvailable[IRR_ARB_texture_border_clamp])
mode=GL_CLAMP_TO_BORDER_ARB;
else
#endif
#ifdef GL_SGIS_texture_border_clamp
if (FeatureAvailable[IRR_SGIS_texture_border_clamp])
mode=GL_CLAMP_TO_BORDER_SGIS;
else
#endif
// fallback
mode=GL_CLAMP;
break;
case ETC_MIRROR:
#ifdef GL_VERSION_1_4
if (Version>103)
mode=GL_MIRRORED_REPEAT;
else
#endif
#ifdef GL_ARB_texture_border_clamp
if (FeatureAvailable[IRR_ARB_texture_mirrored_repeat])
mode=GL_MIRRORED_REPEAT_ARB;
else
#endif
#ifdef GL_IBM_texture_mirrored_repeat
if (FeatureAvailable[IRR_IBM_texture_mirrored_repeat])
mode=GL_MIRRORED_REPEAT_IBM;
else
#endif
mode=GL_REPEAT;
break;
case ETC_MIRROR_CLAMP:
#ifdef GL_EXT_texture_mirror_clamp
if (FeatureAvailable[IRR_EXT_texture_mirror_clamp])
mode=GL_MIRROR_CLAMP_EXT;
else
#endif
#if defined(GL_ATI_texture_mirror_once)
if (FeatureAvailable[IRR_ATI_texture_mirror_once])
mode=GL_MIRROR_CLAMP_ATI;
else
#endif
mode=GL_CLAMP;
break;
case ETC_MIRROR_CLAMP_TO_EDGE:
#ifdef GL_EXT_texture_mirror_clamp
if (FeatureAvailable[IRR_EXT_texture_mirror_clamp])
mode=GL_MIRROR_CLAMP_TO_EDGE_EXT;
else
#endif
#if defined(GL_ATI_texture_mirror_once)
if (FeatureAvailable[IRR_ATI_texture_mirror_once])
mode=GL_MIRROR_CLAMP_TO_EDGE_ATI;
else
#endif
mode=GL_CLAMP;
break;
case ETC_MIRROR_CLAMP_TO_BORDER:
#ifdef GL_EXT_texture_mirror_clamp
if (FeatureAvailable[IRR_EXT_texture_mirror_clamp])
mode=GL_MIRROR_CLAMP_TO_BORDER_EXT;
else
#endif
mode=GL_CLAMP;
break;
}
return mode;
}
void COpenGLDriver::setWrapMode(const SMaterial& material)
{
// texture address mode
@ -2104,70 +2226,8 @@ void COpenGLDriver::setWrapMode(const SMaterial& material)
else if (u>0)
break; // stop loop
GLint mode=GL_REPEAT;
switch (material.TextureLayer[u].TextureWrap)
{
case ETC_REPEAT:
mode=GL_REPEAT;
break;
case ETC_CLAMP:
mode=GL_CLAMP;
break;
case ETC_CLAMP_TO_EDGE:
#ifdef GL_VERSION_1_2
if (Version>101)
mode=GL_CLAMP_TO_EDGE;
else
#endif
#ifdef GL_SGIS_texture_edge_clamp
if (FeatureAvailable[IRR_SGIS_texture_edge_clamp])
mode=GL_CLAMP_TO_EDGE_SGIS;
else
#endif
// fallback
mode=GL_CLAMP;
break;
case ETC_CLAMP_TO_BORDER:
#ifdef GL_VERSION_1_3
if (Version>102)
mode=GL_CLAMP_TO_BORDER;
else
#endif
#ifdef GL_ARB_texture_border_clamp
if (FeatureAvailable[IRR_ARB_texture_border_clamp])
mode=GL_CLAMP_TO_BORDER_ARB;
else
#endif
#ifdef GL_SGIS_texture_border_clamp
if (FeatureAvailable[IRR_SGIS_texture_border_clamp])
mode=GL_CLAMP_TO_BORDER_SGIS;
else
#endif
// fallback
mode=GL_CLAMP;
break;
case ETC_MIRROR:
#ifdef GL_VERSION_1_4
if (Version>103)
mode=GL_MIRRORED_REPEAT;
else
#endif
#ifdef GL_ARB_texture_border_clamp
if (FeatureAvailable[IRR_ARB_texture_mirrored_repeat])
mode=GL_MIRRORED_REPEAT_ARB;
else
#endif
#ifdef GL_IBM_texture_mirrored_repeat
if (FeatureAvailable[IRR_IBM_texture_mirrored_repeat])
mode=GL_MIRRORED_REPEAT_IBM;
else
#endif
mode=GL_REPEAT;
break;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[u].TextureWrapU));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[u].TextureWrapV));
}
}
@ -2539,6 +2599,9 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
glLoadIdentity();
glTranslatef(0.375, 0.375, 0.0);
// Make sure we set first texture matrix
if (MultiTextureExtension)
extGlActiveTexture(GL_TEXTURE0_ARB);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
@ -3353,6 +3416,136 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff
}
//! Sets multiple render targets
bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& targets,
bool clearBackBuffer, bool clearZBuffer, SColor color)
{
if (targets.size()==0)
return setRenderTarget(0, clearBackBuffer, clearZBuffer, color);
u32 maxMultipleRTTs = core::min_(4u, targets.size());
// determine common size
core::dimension2du rttSize = CurrentRendertargetSize;
if (targets[0].TargetType==ERT_RENDER_TEXTURE)
{
if (!targets[0].RenderTexture)
{
os::Printer::log("Missing render texture for MRT.", ELL_ERROR);
return false;
}
rttSize=targets[0].RenderTexture->getSize();
}
for (u32 i = 0; i < maxMultipleRTTs; ++i)
{
// check for right driver type
if (targets[i].TargetType==ERT_RENDER_TEXTURE)
{
if (!targets[i].RenderTexture)
{
maxMultipleRTTs=i;
os::Printer::log("Missing render texture for MRT.", ELL_WARNING);
break;
}
if (targets[i].RenderTexture->getDriverType() != EDT_OPENGL)
{
maxMultipleRTTs=i;
os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING);
break;
}
// check for valid render target
if (!targets[i].RenderTexture->isRenderTarget() || !static_cast<COpenGLTexture*>(targets[i].RenderTexture)->isFrameBufferObject())
{
maxMultipleRTTs=i;
os::Printer::log("Tried to set a non FBO-RTT as render target.", ELL_WARNING);
break;
}
// check for valid size
if (rttSize != targets[i].RenderTexture->getSize())
{
maxMultipleRTTs=i;
os::Printer::log("Render target texture has wrong size.", ELL_WARNING);
break;
}
}
}
if (maxMultipleRTTs==0)
{
os::Printer::log("No valid MRTs.", ELL_ERROR);
return false;
}
if (targets[0].TargetType==ERT_RENDER_TEXTURE)
setRenderTarget(targets[0].RenderTexture, false, false, 0x0);
else
setRenderTarget(targets[0].TargetType, false, false, 0x0);
if (maxMultipleRTTs > 1)
{
core::array<GLenum> MRTs;
MRTs.set_used(maxMultipleRTTs);
for(u32 i = 0; i < maxMultipleRTTs; i++)
{
if (FeatureAvailable[IRR_EXT_draw_buffers2])
{
extGlColorMaskIndexed(i,
(targets[i].ColorMask & ECP_RED)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
if (targets[i].BlendEnable)
extGlEnableIndexed(GL_BLEND, i);
else
extGlDisableIndexed(GL_BLEND, i);
}
if (FeatureAvailable[IRR_AMD_draw_buffers_blend] || FeatureAvailable[IRR_ARB_draw_buffers_blend])
{
extGlBlendFuncIndexed(i, targets[i].BlendFuncSrc, targets[i].BlendFuncDst);
}
if (targets[0].TargetType==ERT_RENDER_TEXTURE)
{
GLenum attachment = GL_NONE;
#ifdef GL_EXT_framebuffer_object
// attach texture to FrameBuffer Object on Color [i]
attachment = GL_COLOR_ATTACHMENT0_EXT+i;
extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, static_cast<COpenGLTexture*>(targets[i].RenderTexture)->getOpenGLTextureName(), 0);
#endif
MRTs[i]=attachment;
}
else
{
switch(targets[i].TargetType)
{
case ERT_FRAME_BUFFER:
MRTs[i]=GL_BACK_LEFT;
break;
case ERT_STEREO_BOTH_BUFFERS:
MRTs[i]=GL_BACK;
break;
case ERT_STEREO_RIGHT_BUFFER:
MRTs[i]=GL_BACK_RIGHT;
break;
case ERT_STEREO_LEFT_BUFFER:
MRTs[i]=GL_BACK_LEFT;
break;
default:
MRTs[i]=GL_AUX0+(targets[i].TargetType-ERT_AUX_BUFFER0);
break;
}
}
}
extGlDrawBuffers(maxMultipleRTTs, MRTs.const_pointer());
}
clearBuffers(clearBackBuffer, clearZBuffer, false, color);
return true;
}
// returns the current size of the screen or rendertarget
const core::dimension2d<u32>& COpenGLDriver::getCurrentRenderTargetSize() const
{
@ -3472,7 +3665,7 @@ bool COpenGLDriver::setClipPlane(u32 index, const core::plane3df& plane, bool en
if (index >= MaxUserClipPlanes)
return false;
UserClipPlane[index]=plane;
UserClipPlanes[index].Plane=plane;
enableClipPlane(index, enable);
return true;
}
@ -3482,10 +3675,10 @@ void COpenGLDriver::uploadClipPlane(u32 index)
{
// opengl needs an array of doubles for the plane equation
double clip_plane[4];
clip_plane[0] = UserClipPlane[index].Normal.X;
clip_plane[1] = UserClipPlane[index].Normal.Y;
clip_plane[2] = UserClipPlane[index].Normal.Z;
clip_plane[3] = UserClipPlane[index].D;
clip_plane[0] = UserClipPlanes[index].Plane.Normal.X;
clip_plane[1] = UserClipPlanes[index].Plane.Normal.Y;
clip_plane[2] = UserClipPlanes[index].Plane.Normal.Z;
clip_plane[3] = UserClipPlanes[index].Plane.D;
glClipPlane(GL_CLIP_PLANE0 + index, clip_plane);
}
@ -3497,7 +3690,7 @@ void COpenGLDriver::enableClipPlane(u32 index, bool enable)
return;
if (enable)
{
if (!UserClipPlaneEnabled[index])
if (!UserClipPlanes[index].Enabled)
{
uploadClipPlane(index);
glEnable(GL_CLIP_PLANE0 + index);
@ -3506,7 +3699,7 @@ void COpenGLDriver::enableClipPlane(u32 index, bool enable)
else
glDisable(GL_CLIP_PLANE0 + index);
UserClipPlaneEnabled[index]=enable;
UserClipPlanes[index].Enabled=enable;
}

View File

@ -289,6 +289,10 @@ namespace video
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color);
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=SColor(0,0,0,0));
//! Clears the ZBuffer.
virtual void clearZBuffer();
@ -313,7 +317,7 @@ namespace video
virtual void enableClipPlane(u32 index, bool enable);
//! Returns the graphics card vendor name.
virtual core::stringc getVendorInfo() {return vendorName;}
virtual core::stringc getVendorInfo() {return VendorName;}
//! Returns the maximum texture size supported.
virtual core::dimension2du getMaxTextureSize() const;
@ -343,6 +347,9 @@ namespace video
//! Set GL pipeline to desired texture wrap modes of the material
void setWrapMode(const SMaterial& material);
//! get native wrap mode value
GLint getTextureWrapMode(const u8 clamp);
//! sets the needed renderstates
void setRenderStates3DMode();
@ -388,12 +395,17 @@ namespace video
COpenGLTexture* RenderTargetTexture;
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
core::array<ITexture*> DepthTextures;
core::array<core::plane3df> UserClipPlane;
core::array<bool> UserClipPlaneEnabled;
struct SUserClipPlane
{
SUserClipPlane() : Enabled(false) {}
core::plane3df Plane;
bool Enabled;
};
core::array<SUserClipPlane> UserClipPlanes;
core::dimension2d<u32> CurrentRendertargetSize;
core::stringc vendorName;
core::stringc VendorName;
core::matrix4 TextureFlipMatrix;
@ -414,7 +426,7 @@ namespace video
: LightData(lightData), HardwareLightIndex(-1), DesireToBeOn(true) { }
SLight LightData;
s32 HardwareLightIndex; // GL_LIGHT0 - GL_LIGHT7
s32 HardwareLightIndex; // GL_LIGHT0 - GL_LIGHT7
bool DesireToBeOn;
};
core::array<RequestedLight> RequestedLights;

View File

@ -46,9 +46,9 @@ COpenGLExtensionHandler::COpenGLExtensionHandler() :
pGlGenBuffersARB(0), pGlBindBufferARB(0), pGlBufferDataARB(0), pGlDeleteBuffersARB(0),
pGlBufferSubDataARB(0), pGlGetBufferSubDataARB(0), pGlMapBufferARB(0), pGlUnmapBufferARB(0),
pGlIsBufferARB(0), pGlGetBufferParameterivARB(0), pGlGetBufferPointervARB(0),
pGlProvokingVertexARB(0), pGlProvokingVertexEXT(0)
pGlProvokingVertexARB(0), pGlProvokingVertexEXT(0),
pGlColorMaskIndexedEXT(0), pGlEnableIndexedEXT(0), pGlDisableIndexedEXT(0),
pGlBlendFuncIndexedAMD(0), pGlBlendFunciARB(0)
#endif // _IRR_OPENGL_USE_EXTPOINTER_
{
for (u32 i=0; i<IRR_OpenGL_Feature_Count; ++i)
@ -190,6 +190,11 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
pGlGetBufferPointervARB= (PFNGLGETBUFFERPOINTERVARBPROC) wglGetProcAddress("glGetBufferPointervARB");
pGlProvokingVertexARB= (PFNGLPROVOKINGVERTEXPROC) wglGetProcAddress("glProvokingVertex");
pGlProvokingVertexEXT= (PFNGLPROVOKINGVERTEXEXTPROC) wglGetProcAddress("glProvokingVertexEXT");
pGlColorMaskIndexedEXT= (PFNGLCOLORMASKINDEXEDEXTPROC) wglGetProcAddress("glColorMaskIndexedEXT");
pGlEnableIndexedEXT= (PFNGLENABLEINDEXEDEXTPROC) wglGetProcAddress("glEnableIndexedEXT");
pGlDisableIndexedEXT= (PFNGLDISABLEINDEXEDEXTPROC) wglGetProcAddress("glDisableIndexedEXT");
pGlBlendFuncIndexedAMD= (PFNGLBLENDFUNCINDEXEDAMDPROC) wglGetProcAddress("glBlendFuncIndexedAMD");
pGlBlendFunciARB= (PFNGLBLENDFUNCIPROC) wglGetProcAddress("glBlendFunciARB");
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined (_IRR_COMPILE_WITH_SDL_DEVICE_)
@ -406,7 +411,16 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glProvokingVertex"));
pGlProvokingVertexEXT= (PFNGLPROVOKINGVERTEXEXTPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glProvokingVertexEXT"));
pGlColorMaskIndexedEXT= (PFNGLCOLORMASKINDEXEDEXTPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glColorMaskIndexedEXT"));
pGlEnableIndexedEXT= (PFNGLENABLEINDEXEDEXTPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glEnableIndexedEXT"));
pGlDisableIndexedEXT= (PFNGLDISABLEINDEXEDEXTPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glDisableIndexedEXT"));
pGlBlendFuncIndexedAMD= (PFNGLBLENDFUNCINDEXEDAMDPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glBlendFuncIndexedAMD"));
pGlBlendFunciARB= (PFNGLBLENDFUNCIPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glBlendFunciARB"));
#endif // _IRR_OPENGL_USE_EXTPOINTER_
#endif // _IRR_WINDOWS_API_
@ -503,6 +517,8 @@ bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
{
case EVDF_RENDER_TO_TARGET:
return true;
case EVDF_HARDWARE_TL:
return true; // we cannot tell other things
case EVDF_MULTITEXTURE:
return MultiTextureExtension;
case EVDF_BILINEAR_FILTER:
@ -535,6 +551,15 @@ bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return true;
case EVDF_ALPHA_TO_COVERAGE:
return FeatureAvailable[IRR_ARB_multisample];
case EVDF_GEOMETRY_SHADER:
return FeatureAvailable[IRR_ARB_geometry_shader4] || FeatureAvailable[IRR_EXT_geometry_shader4] || FeatureAvailable[IRR_NV_geometry_program4] || FeatureAvailable[IRR_NV_geometry_shader4];
case EVDF_MULTIPLE_RENDER_TARGETS:
return FeatureAvailable[IRR_ARB_draw_buffers] || FeatureAvailable[IRR_ATI_draw_buffers];
case EVDF_MRT_BLEND:
case EVDF_MRT_COLOR_MASK:
return FeatureAvailable[IRR_EXT_draw_buffers2];
case EVDF_MRT_BLEND_FUNC:
return FeatureAvailable[IRR_ARB_draw_buffers_blend] || FeatureAvailable[IRR_AMD_draw_buffers_blend];
default:
return false;
};

View File

@ -89,6 +89,7 @@ static const char* const OpenGLFeatureStrings[] = {
"GL_APPLE_float_pixels",
"GL_APPLE_flush_buffer_range",
"GL_APPLE_object_purgeable",
"GL_APPLE_rgb_422",
"GL_APPLE_row_bytes",
"GL_APPLE_specular_vector",
"GL_APPLE_texture_range",
@ -230,6 +231,7 @@ static const char* const OpenGLFeatureStrings[] = {
"GL_EXT_provoking_vertex",
"GL_EXT_rescale_normal",
"GL_EXT_secondary_color",
"GL_EXT_separate_shader_objects",
"GL_EXT_separate_specular_color",
"GL_EXT_shadow_funcs",
"GL_EXT_shared_texture_palette",
@ -290,6 +292,7 @@ static const char* const OpenGLFeatureStrings[] = {
"GL_NV_blend_square",
"GL_NV_conditional_render",
"GL_NV_copy_depth_to_color",
"GL_NV_copy_image",
"GL_NV_depth_buffer_float",
"GL_NV_depth_clamp",
"GL_NV_evaluators",
@ -311,14 +314,17 @@ static const char* const OpenGLFeatureStrings[] = {
"GL_NV_occlusion_query",
"GL_NV_packed_depth_stencil",
"GL_NV_parameter_buffer_object",
"GL_NV_parameter_buffer_object2",
"GL_NV_pixel_data_range",
"GL_NV_point_sprite",
"GL_NV_present_video",
"GL_NV_primitive_restart",
"GL_NV_register_combiners",
"GL_NV_register_combiners2",
"GL_NV_shader_buffer_load",
"GL_NV_texgen_emboss",
"GL_NV_texgen_reflection",
"GL_NV_texture_barrier",
"GL_NV_texture_compression_vtc",
"GL_NV_texture_env_combine4",
"GL_NV_texture_expand_normal",
@ -330,12 +336,14 @@ static const char* const OpenGLFeatureStrings[] = {
"GL_NV_transform_feedback2",
"GL_NV_vertex_array_range",
"GL_NV_vertex_array_range2",
"GL_NV_vertex_buffer_unified_memory",
"GL_NV_vertex_program",
"GL_NV_vertex_program1_1",
"GL_NV_vertex_program2",
"GL_NV_vertex_program2_option",
"GL_NV_vertex_program3",
"GL_NV_vertex_program4",
"GL_NV_video_capture",
"GL_OES_read_format",
"GL_OML_interlace",
"GL_OML_resample",
@ -434,6 +442,7 @@ class COpenGLExtensionHandler
IRR_APPLE_float_pixels,
IRR_APPLE_flush_buffer_range,
IRR_APPLE_object_purgeable,
IRR_APPLE_rgb_422,
IRR_APPLE_row_bytes,
IRR_APPLE_specular_vector,
IRR_APPLE_texture_range,
@ -575,6 +584,7 @@ class COpenGLExtensionHandler
IRR_EXT_provoking_vertex,
IRR_EXT_rescale_normal,
IRR_EXT_secondary_color,
IRR_EXT_separate_shader_objects,
IRR_EXT_separate_specular_color,
IRR_EXT_shadow_funcs,
IRR_EXT_shared_texture_palette,
@ -635,6 +645,7 @@ class COpenGLExtensionHandler
IRR_NV_blend_square,
IRR_NV_conditional_render,
IRR_NV_copy_depth_to_color,
IRR_NV_copy_image,
IRR_NV_depth_buffer_float,
IRR_NV_depth_clamp,
IRR_NV_evaluators,
@ -656,14 +667,17 @@ class COpenGLExtensionHandler
IRR_NV_occlusion_query,
IRR_NV_packed_depth_stencil,
IRR_NV_parameter_buffer_object,
IRR_NV_parameter_buffer_object2,
IRR_NV_pixel_data_range,
IRR_NV_point_sprite,
IRR_NV_present_video,
IRR_NV_primitive_restart,
IRR_NV_register_combiners,
IRR_NV_register_combiners2,
IRR_NV_shader_buffer_load,
IRR_NV_texgen_emboss,
IRR_NV_texgen_reflection,
IRR_NV_texture_barrier,
IRR_NV_texture_compression_vtc,
IRR_NV_texture_env_combine4,
IRR_NV_texture_expand_normal,
@ -675,12 +689,14 @@ class COpenGLExtensionHandler
IRR_NV_transform_feedback2,
IRR_NV_vertex_array_range,
IRR_NV_vertex_array_range2,
IRR_NV_vertex_buffer_unified_memory,
IRR_NV_vertex_program,
IRR_NV_vertex_program1_1,
IRR_NV_vertex_program2,
IRR_NV_vertex_program2_option,
IRR_NV_vertex_program3,
IRR_NV_vertex_program4,
IRR_NV_video_capture,
IRR_OES_read_format,
IRR_OML_interlace,
IRR_OML_resample,
@ -884,6 +900,10 @@ class COpenGLExtensionHandler
void extGlGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
void extGlGetBufferPointerv (GLenum target, GLenum pname, GLvoid **params);
void extGlProvokingVertex(GLenum mode);
void extGlColorMaskIndexed(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
void extGlEnableIndexed(GLenum target, GLuint index);
void extGlDisableIndexed(GLenum target, GLuint index);
void extGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst);
protected:
@ -954,6 +974,11 @@ class COpenGLExtensionHandler
PFNGLGETBUFFERPOINTERVARBPROC pGlGetBufferPointervARB;
PFNGLPROVOKINGVERTEXPROC pGlProvokingVertexARB;
PFNGLPROVOKINGVERTEXEXTPROC pGlProvokingVertexEXT;
PFNGLCOLORMASKINDEXEDEXTPROC pGlColorMaskIndexedEXT;
PFNGLENABLEINDEXEDEXTPROC pGlEnableIndexedEXT;
PFNGLDISABLEINDEXEDEXTPROC pGlDisableIndexedEXT;
PFNGLBLENDFUNCINDEXEDAMDPROC pGlBlendFuncIndexedAMD;
PFNGLBLENDFUNCIPROC pGlBlendFunciARB;
#endif
};
@ -1665,6 +1690,62 @@ inline void COpenGLExtensionHandler::extGlProvokingVertex(GLenum mode)
}
inline void COpenGLExtensionHandler::extGlColorMaskIndexed(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
if (FeatureAvailable[IRR_EXT_draw_buffers2] && pGlColorMaskIndexedEXT)
pGlColorMaskIndexedEXT(buf, r, g, b, a);
#elif defined(GL_EXT_draw_buffers2)
glColorMaskIndexedEXT(buf, r, g, b, a);
#else
os::Printer::log("glColorMaskIndexed not supported", ELL_ERROR);
#endif
}
inline void COpenGLExtensionHandler::extGlEnableIndexed(GLenum target, GLuint index)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
if (FeatureAvailable[IRR_EXT_draw_buffers2] && pGlEnableIndexedEXT)
pGlEnableIndexedEXT(target, index);
#elif defined(GL_EXT_draw_buffers2)
glEnableIndexedEXT(target, index);
#else
os::Printer::log("glEnableIndexed not supported", ELL_ERROR);
#endif
}
inline void COpenGLExtensionHandler::extGlDisableIndexed(GLenum target, GLuint index)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
if (FeatureAvailable[IRR_EXT_draw_buffers2] && pGlDisableIndexedEXT)
pGlDisableIndexedEXT(target, index);
#elif defined(GL_EXT_draw_buffers2)
glDisableIndexedEXT(target, index);
#else
os::Printer::log("glDisableIndexed not supported", ELL_ERROR);
#endif
}
inline void COpenGLExtensionHandler::extGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
if (FeatureAvailable[IRR_ARB_draw_buffers_blend] && pGlBlendFunciARB)
pGlBlendFunciARB(buf, src, dst);
if (FeatureAvailable[IRR_AMD_draw_buffers_blend] && pGlBlendFuncIndexedAMD)
pGlBlendFuncIndexedAMD(buf, src, dst);
#elif defined(GL_ARB_draw_buffers_blend)
glBlendFunciARB(buf, src, dst);
#elif defined(GL_AMD_draw_buffers_blend)
glBlendFuncIndexedAMD(buf, src, dst);
#else
os::Printer::log("glBlendFuncIndexed not supported", ELL_ERROR);
#endif
}
}
}

View File

@ -308,7 +308,7 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PRIMARY_COLOR_EXT );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@ -319,14 +319,9 @@ public:
virtual void OnUnsetMaterial()
{
// default values
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT );
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
glDisable(GL_BLEND);
}
@ -374,6 +369,8 @@ public:
virtual void OnUnsetMaterial()
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
}
@ -490,6 +487,7 @@ public:
default:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
}
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
}
}
}

View File

@ -120,6 +120,117 @@ ECOLOR_FORMAT COpenGLTexture::getBestColorFormat(ECOLOR_FORMAT format)
}
GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT format,
GLint& filtering,
GLenum& colorformat,
GLenum& type)
{
// default
filtering = GL_LINEAR;
colorformat = GL_RGBA;
type = GL_UNSIGNED_BYTE;
switch(format)
{
case ECF_A1R5G5B5:
colorformat=GL_BGRA_EXT;
type=GL_UNSIGNED_SHORT_1_5_5_5_REV;
return GL_RGBA;
case ECF_R5G6B5:
colorformat=GL_BGR;
type=GL_UNSIGNED_SHORT_5_6_5_REV;
return GL_RGB;
case ECF_R8G8B8:
colorformat=GL_BGR;
type=GL_UNSIGNED_BYTE;
return GL_RGB;
case ECF_A8R8G8B8:
colorformat=GL_BGRA_EXT;
if (Driver->Version > 101)
type=GL_UNSIGNED_INT_8_8_8_8_REV;
return GL_RGBA;
// Floating Point texture formats. Thanks to Patryk "Nadro" Nadrowski.
case ECF_R16F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R16F;
#else
return GL_RGB8;
#endif
}
case ECF_G16R16F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG16F;
#else
return GL_RGB8;
#endif
}
case ECF_A16B16G16R16F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA16F_ARB;
#else
return GL_RGBA8;
#endif
}
case ECF_R32F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R32F;
#else
return GL_RGB8;
#endif
}
case ECF_G32R32F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG32F;
#else
return GL_RGB8;
#endif
}
case ECF_A32B32G32R32F:
{
#ifdef GL_ARB_texture_float
filtering = GL_NEAREST;
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA32F_ARB;
#else
return GL_RGBA8;
#endif
}
default:
{
os::Printer::log("Unsupported texture format", ELL_ERROR);
return GL_RGBA8;
}
}
}
void COpenGLTexture::getImageData(IImage* image)
{
if (!image)
@ -162,34 +273,8 @@ void COpenGLTexture::copyTexture(bool newTexture)
return;
}
switch (ColorFormat)
{
case ECF_A1R5G5B5:
InternalFormat=GL_RGBA;
PixelFormat=GL_BGRA_EXT;
PixelType=GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case ECF_R5G6B5:
InternalFormat=GL_RGB;
PixelFormat=GL_BGR;
PixelType=GL_UNSIGNED_SHORT_5_6_5_REV;
break;
case ECF_R8G8B8:
InternalFormat=GL_RGB;
PixelFormat=GL_BGR;
PixelType=GL_UNSIGNED_BYTE;
break;
case ECF_A8R8G8B8:
InternalFormat=GL_RGBA;
PixelFormat=GL_BGRA_EXT;
if (Driver->Version > 101)
PixelType=GL_UNSIGNED_INT_8_8_8_8_REV;
break;
default:
os::Printer::log("Unsupported texture format", ELL_ERROR);
break;
}
GLint filtering;
InternalFormat = getOpenGLFormatAndParametersFromColorFormat(ColorFormat, filtering, PixelFormat, PixelType);
Driver->setActiveTexture(0, this);
if (Driver->testGLError())
os::Printer::log("Could not bind Texture", ELL_ERROR);
@ -450,9 +535,8 @@ static bool checkFBOStatus(COpenGLDriver* Driver);
//! RTT ColorFrameBuffer constructor
COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<u32>& size,
const io::path& name,
COpenGLDriver* driver,
const ECOLOR_FORMAT format)
const io::path& name, COpenGLDriver* driver,
const ECOLOR_FORMAT format)
: COpenGLTexture(name, driver), DepthTexture(0), ColorFrameBuffer(0)
{
#ifdef _DEBUG
@ -492,98 +576,6 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<u32>& size,
unbindRTT();
}
GLint COpenGLFBOTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT format,
GLint& filtering,
GLenum& colorformat,
GLenum& type)
{
// default
filtering = GL_LINEAR;
colorformat = GL_RGBA;
type = GL_UNSIGNED_BYTE;
switch(format)
{
// Floating Point texture formats. Thanks to Patryk "Nadro" Nadrowski.
case ECF_R16F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R16F;
#else
return GL_RGB8;
#endif
}
case ECF_G16R16F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG16F;
#else
return GL_RGB8;
#endif
}
case ECF_A16B16G16R16F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA16F_ARB;
#else
return GL_RGBA8;
#endif
}
case ECF_R32F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R32F;
#else
return GL_RGB8;
#endif
}
case ECF_G32R32F:
{
#ifdef GL_ARB_texture_rg
filtering = GL_NEAREST;
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG32F;
#else
return GL_RGB8;
#endif
}
case ECF_A32B32G32R32F:
{
#ifdef GL_ARB_texture_float
filtering = GL_NEAREST;
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA32F_ARB;
#else
return GL_RGBA8;
#endif
}
default:
{
return GL_RGBA8;
}
}
}
//! destructor
COpenGLFBOTexture::~COpenGLFBOTexture()
@ -807,6 +799,12 @@ bool checkFBOStatus(COpenGLDriver* Driver)
os::Printer::log("FBO missing an image attachment", ELL_ERROR);
break;
#ifdef GL_EXT_framebuffer_multisample
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
os::Printer::log("FBO wrong multisample setup", ELL_ERROR);
break;
#endif
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
os::Printer::log("FBO format unsupported", ELL_ERROR);
break;

View File

@ -110,6 +110,10 @@ protected:
//! get the desired color format based on texture creation flags and the input format.
ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format);
//! Get the OpenGL color format parameters based on the given Irrlicht color format
GLint getOpenGLFormatAndParametersFromColorFormat(
ECOLOR_FORMAT format, GLint& filtering, GLenum& colorformat, GLenum& type);
//! convert the image into an internal image with better properties for this driver.
void getImageData(IImage* image);
@ -120,7 +124,6 @@ protected:
core::dimension2d<u32> ImageSize;
core::dimension2d<u32> TextureSize;
ECOLOR_FORMAT ColorFormat;
s32 Pitch;
COpenGLDriver* Driver;
IImage* Image;
@ -159,9 +162,6 @@ public:
ITexture* DepthTexture;
protected:
GLint getOpenGLFormatAndParametersFromColorFormat(
ECOLOR_FORMAT format, GLint& filtering, GLenum& colorformat, GLenum& type);
GLuint ColorFrameBuffer;
};

View File

@ -196,3 +196,4 @@ IReadFile* CPakReader::createAndOpenFile(u32 index)
} // end namespace irr
#endif // __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_

View File

@ -378,7 +378,8 @@ void CQuake3ShaderSceneNode::render()
material.MaterialType = blendfunc.type;
material.MaterialTypeParam = blendfunc.param0;
material.TextureLayer[0].TextureWrap = q.TextureAddressMode;
material.TextureLayer[0].TextureWrapU = q.TextureAddressMode;
material.TextureLayer[0].TextureWrapV = q.TextureAddressMode;
//material.TextureLayer[0].TrilinearFilter = 1;
//material.TextureLayer[0].AnisotropicFilter = 0xFF;
material.setTextureMatrix( 0, textureMatrix );

View File

@ -74,10 +74,10 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
core::line3df& ray, s32 bits, bool bNoDebugObjects,
f32& outbestdistance, ISceneNode*& outbestnode)
{
const core::list<ISceneNode*>& children = root->getChildren();
const ISceneNodeList& children = root->getChildren();
const core::vector3df rayVector = ray.getVector().normalize();
core::list<ISceneNode*>::ConstIterator it = children.begin();
ISceneNodeList::ConstIterator it = children.begin();
for (; it != children.end(); ++it)
{
ISceneNode* current = *it;
@ -264,9 +264,9 @@ void CSceneCollisionManager::getPickedNodeFromBBAndSelector(
core::vector3df & outBestCollisionPoint,
core::triangle3df & outBestTriangle)
{
const core::list<ISceneNode*>& children = root->getChildren();
const ISceneNodeList& children = root->getChildren();
core::list<ISceneNode*>::ConstIterator it = children.begin();
ISceneNodeList::ConstIterator it = children.begin();
for (; it != children.end(); ++it)
{
ISceneNode* current = *it;

View File

@ -1320,17 +1320,18 @@ void CSceneManager::drawAll()
Parameters.setAttribute ( "drawn_transparent", 0 );
Parameters.setAttribute ( "drawn_transparent_effect", 0 );
u32 i; // new ISO for scoping problem in some compilers
// reset all transforms
video::IVideoDriver* driver = getVideoDriver();
if ( driver )
{
driver->setMaterial(video::SMaterial());
driver->setTransform ( video::ETS_PROJECTION, core::IdentityMatrix );
driver->setTransform ( video::ETS_VIEW, core::IdentityMatrix );
driver->setTransform ( video::ETS_WORLD, core::IdentityMatrix );
driver->setTransform ( video::ETS_TEXTURE_0, core::IdentityMatrix );
driver->setTransform ( video::ETS_TEXTURE_1, core::IdentityMatrix );
driver->setTransform ( video::ETS_TEXTURE_2, core::IdentityMatrix );
driver->setTransform ( video::ETS_TEXTURE_3, core::IdentityMatrix );
for (i=video::ETS_COUNT-1; i>=video::ETS_TEXTURE_0; --i)
driver->setTransform ( (video::E_TRANSFORMATION_STATE)i, core::IdentityMatrix );
}
driver->setAllowZWriteOnTransparent(Parameters.getAttributeAsBool( ALLOW_ZWRITE_ON_TRANSPARENT) );
@ -1355,8 +1356,6 @@ void CSceneManager::drawAll()
if(LightManager)
LightManager->OnPreRender(LightList);
u32 i; // new ISO for scoping problem in some compilers
//render camera scenes
{
CurrentRendertime = ESNRP_CAMERA;
@ -1818,8 +1817,8 @@ ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* st
ISceneNode* node = 0;
const core::list<ISceneNode*>& list = start->getChildren();
core::list<ISceneNode*>::ConstIterator it = list.begin();
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
for (; it!=list.end(); ++it)
{
node = getSceneNodeFromName(name, *it);
@ -1842,8 +1841,8 @@ ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start)
ISceneNode* node = 0;
const core::list<ISceneNode*>& list = start->getChildren();
core::list<ISceneNode*>::ConstIterator it = list.begin();
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
for (; it!=list.end(); ++it)
{
node = getSceneNodeFromId(id, *it);
@ -1866,8 +1865,8 @@ ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, IS
ISceneNode* node = 0;
const core::list<ISceneNode*>& list = start->getChildren();
core::list<ISceneNode*>::ConstIterator it = list.begin();
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
for (; it!=list.end(); ++it)
{
node = getSceneNodeFromType(type, *it);
@ -1887,8 +1886,8 @@ void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array<sce
if (start->getType() == type || ESNT_ANY == type)
outNodes.push_back(start);
const core::list<ISceneNode*>& list = start->getChildren();
core::list<ISceneNode*>::ConstIterator it = list.begin();
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
for (; it!=list.end(); ++it)
{
@ -1916,6 +1915,9 @@ void CSceneManager::removeAll()
{
ISceneNode::removeAll();
setActiveCamera(0);
// Make sure the driver is reset, might need a more complex method at some point
if (Driver)
Driver->setMaterial(video::SMaterial());
}
@ -2394,7 +2396,7 @@ void CSceneManager::writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISc
writer->writeElement(animatorElement);
writer->writeLineBreak();
core::list<ISceneNodeAnimator*>::ConstIterator it = node->getAnimators().begin();
ISceneNodeAnimatorList::ConstIterator it = node->getAnimators().begin();
for (; it != node->getAnimators().end(); ++it)
{
attr->clear();
@ -2434,7 +2436,7 @@ void CSceneManager::writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISc
// write children
core::list<ISceneNode*>::ConstIterator it = node->getChildren().begin();
ISceneNodeList::ConstIterator it = node->getChildren().begin();
for (; it != node->getChildren().end(); ++it)
writeSceneNode(writer, (*it), userDataSerializer);

View File

@ -108,7 +108,7 @@ namespace scene
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! registers a node for rendering it at a specific time.
virtual u32 registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS = ESNRP_AUTOMATIC);
virtual u32 registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS pass = ESNRP_AUTOMATIC);
//! draws all scene nodes
virtual void drawAll();
@ -556,9 +556,6 @@ namespace scene
//! sort on distance (sphere) to camera
struct DistanceNodeEntry
{
DistanceNodeEntry(ISceneNode* n, f32 d)
: Node(n), Distance(d) {}
DistanceNodeEntry(ISceneNode* n, const core::vector3df& cameraPos)
: Node(n)
{

View File

@ -229,8 +229,8 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
// and if it's not falling, we tell it to jump.
if (CursorKeys[EKA_JUMP_UP])
{
const core::list<ISceneNodeAnimator*> & animators = camera->getAnimators();
core::list<ISceneNodeAnimator*>::ConstIterator it = animators.begin();
const ISceneNodeAnimatorList& animators = camera->getAnimators();
ISceneNodeAnimatorList::ConstIterator it = animators.begin();
while(it != animators.end())
{
if(ESNAT_COLLISION_RESPONSE == (*it)->getType())

View File

@ -1363,7 +1363,7 @@ void CSkinnedMesh::convertMeshToTangents()
{
if (LocalBuffers[b])
{
LocalBuffers[b]->MoveTo_Tangents();
LocalBuffers[b]->convertToTangents();
const s32 idxCnt = LocalBuffers[b]->getIndexCount();
@ -1448,12 +1448,6 @@ void CSkinnedMesh::calculateTangents(
}
} // end namespace scene
} // end namespace irr

View File

@ -41,7 +41,8 @@ CSkyBoxSceneNode::CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom
mat.ZBuffer = video::ECFN_NEVER;
mat.ZWriteEnable = false;
mat.AntiAliasing=0;
mat.TextureLayer[0].TextureWrap = video::ETC_CLAMP;
mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
/* Hey, I am no artist, but look at that
cool ASCII art I made! ;)

View File

@ -956,21 +956,55 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex,
sizeof ( f32 ) * 2 );
}
switch ( Material.org.TextureLayer[t].TextureWrap )
switch ( Material.org.TextureLayer[t].TextureWrapU )
{
case ETC_CLAMP:
case ETC_CLAMP_TO_EDGE:
case ETC_CLAMP_TO_BORDER:
dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );
break;
case ETC_MIRROR:
dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];
if (core::fract(dest->Tex[t].x)>0.5f)
dest->Tex[t].x=1.f-dest->Tex[t].x;
break;
case ETC_MIRROR_CLAMP:
case ETC_MIRROR_CLAMP_TO_EDGE:
case ETC_MIRROR_CLAMP_TO_BORDER:
dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );
if (core::fract(dest->Tex[t].x)>0.5f)
dest->Tex[t].x=1.f-dest->Tex[t].x;
break;
case ETC_REPEAT:
default:
dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];
dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];
break;
}
switch ( Material.org.TextureLayer[t].TextureWrapV )
{
case ETC_CLAMP:
case ETC_CLAMP_TO_EDGE:
dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );
case ETC_CLAMP_TO_BORDER:
dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );
break;
case ETC_MIRROR:
dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];
if (core::fract(dest->Tex[t].y)>0.5f)
dest->Tex[t].y=1.f-dest->Tex[t].y;
break;
case ETC_MIRROR_CLAMP:
case ETC_MIRROR_CLAMP_TO_EDGE:
case ETC_MIRROR_CLAMP_TO_BORDER:
dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );
if (core::fract(dest->Tex[t].y)>0.5f)
dest->Tex[t].y=1.f-dest->Tex[t].y;
break;
case ETC_REPEAT:
default:
dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];
break;
}
}
}
#endif

View File

@ -109,7 +109,7 @@ bool CArchiveLoaderZIP::isALoadableFileFormat(io::IReadFile* file) const
#endif
return header.Sig == 0x04034b50 || // ZIP
*((u16*)(&header.Sig)) == 0x8b1f; // gzip
(header.Sig&0xffff) == 0x8b1f; // gzip
}
// -----------------------------------------------------------------------------

View File

@ -808,6 +808,8 @@
<Unit filename="CPLYMeshWriter.h" />
<Unit filename="CPakReader.cpp" />
<Unit filename="CPakReader.h" />
<Unit filename="CNPKReader.cpp" />
<Unit filename="CNPKReader.h" />
<Unit filename="CParticleAnimatedMeshSceneNodeEmitter.cpp" />
<Unit filename="CParticleAttractionAffector.cpp" />
<Unit filename="CParticleBoxEmitter.cpp" />

View File

@ -9,7 +9,7 @@ CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DIR
Includes=..\..\include;zlib
Linker=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lwinmm -lopengl32_@@_
Libs=
UnitCount=625
UnitCount=627
Folders=doc,include,include/core,include/gui,include/io,include/scene,include/video,Irrlicht,Irrlicht/extern,Irrlicht/extern/jpeglib,Irrlicht/extern/libpng,Irrlicht/extern/zlib,Irrlicht/gui,Irrlicht/io,Irrlicht/io/archive,Irrlicht/io/attributes,Irrlicht/io/file,Irrlicht/io/xml,Irrlicht/irr,Irrlicht/irr/IrrlichtDevice,Irrlicht/scene,Irrlicht/scene/animators,Irrlicht/scene/collision,Irrlicht/scene/mesh,Irrlicht/scene/mesh/loaders,Irrlicht/scene/mesh/writers,Irrlicht/scene/nodes,Irrlicht/scene/nodes/particles,Irrlicht/video,"Irrlicht/video/Burning Video",Irrlicht/video/DirectX8,Irrlicht/video/DirectX9,Irrlicht/video/Null,Irrlicht/video/Null/Loader,Irrlicht/video/Null/Writer,Irrlicht/video/OpenGL,Irrlicht/video/Software
ObjFiles=
PrivateResource=
@ -6298,3 +6298,23 @@ Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit626]
FileName=CNPKReader.h
CompileCpp=1
Folder=Irrlicht/io/archive
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit627]
FileName=CNPKReader.cpp
CompileCpp=1
Folder=Irrlicht/io/archive
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@ -1978,6 +1978,12 @@
<File
RelativePath=".\CPakReader.h">
</File>
<File
RelativePath=".\CNPKReader.cpp">
</File>
<File
RelativePath=".\CNPKReader.h">
</File>
<File
RelativePath=".\CReadFile.cpp">
</File>

View File

@ -2758,6 +2758,14 @@
RelativePath="CPakReader.h"
>
</File>
<File
RelativePath="CNPKReader.cpp"
>
</File>
<File
RelativePath="CNPKReader.h"
>
</File>
<File
RelativePath="CReadFile.cpp"
>

View File

@ -179,7 +179,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib opengl32.lib winmm.lib"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib opengl32.lib winmm.lib"
OutputFile="..\..\bin\Win32-visualstudio\Irrlicht.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
@ -927,6 +927,10 @@
RelativePath="..\..\include\IXMLWriter.h"
>
</File>
<File
RelativePath="..\..\include\path.h"
>
</File>
</Filter>
<Filter
Name="scene"
@ -2206,6 +2210,10 @@
RelativePath="glext.h"
>
</File>
<File
RelativePath=".\wglext.h"
>
</File>
</Filter>
<Filter
Name="Direct3D8"
@ -3139,6 +3147,14 @@
RelativePath="CMemoryFile.h"
>
</File>
<File
RelativePath="CMountPointReader.cpp"
>
</File>
<File
RelativePath="CMountPointReader.h"
>
</File>
<File
RelativePath="CPakReader.cpp"
>
@ -3147,6 +3163,14 @@
RelativePath="CPakReader.h"
>
</File>
<File
RelativePath="CNPKReader.cpp"
>
</File>
<File
RelativePath="CNPKReader.h"
>
</File>
<File
RelativePath="CReadFile.cpp"
>
@ -3163,14 +3187,6 @@
RelativePath="CTarReader.h"
>
</File>
<File
RelativePath="CMountPointReader.cpp"
>
</File>
<File
RelativePath="CMountPointReader.h"
>
</File>
<File
RelativePath="CWriteFile.cpp"
>

View File

@ -2385,6 +2385,14 @@
RelativePath="CPakReader.h"
>
</File>
<File
RelativePath="CNPKReader.cpp"
>
</File>
<File
RelativePath="CNPKReader.h"
>
</File>
<File
RelativePath="CTarReader.cpp"
>

View File

@ -1131,6 +1131,12 @@
<File
RelativePath=".\CPakReader.h">
</File>
<File
RelativePath=".\CNPKReader.cpp">
</File>
<File
RelativePath=".\CNPKReader.h">
</File>
<File
RelativePath=".\CTarReader.cpp">
</File>

View File

@ -60,11 +60,11 @@ struct JoystickInfo
irr::core::array <JoystickComponent> axisComp;
irr::core::array <JoystickComponent> buttonComp;
irr::core::array <JoystickComponent> hatComp;
int hats;
int axes;
int buttons;
int numActiveJoysticks;
irr::SEvent persistentData;
@ -178,7 +178,7 @@ static void addJoystickComponent (CFTypeRef refElement, JoystickInfo* joyInfo)
joyInfo->hatComp.push_back(newComponent);
}
break;
}
}
}
break;
case kHIDPage_Button:
@ -235,10 +235,10 @@ static void getJoystickDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef
{
CFMutableDictionaryRef usbProperties = 0;
io_registry_entry_t parent1, parent2;
/* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
* get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
*/
* get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
*/
if ((KERN_SUCCESS == IORegistryEntryGetParentEntry (hidDevice, kIOServicePlane, &parent1)) &&
(KERN_SUCCESS == IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2)) &&
(KERN_SUCCESS == IORegistryEntryCreateCFProperties (parent2, &usbProperties, kCFAllocatorDefault, kNilOptions)))
@ -247,10 +247,9 @@ static void getJoystickDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef
{
CFTypeRef refCF = 0;
/* get device info
* try hid dictionary first, if fail then go to usb dictionary
*/
* try hid dictionary first, if fail then go to usb dictionary
*/
/* get joystickName name */
refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey));
if (!refCF)
@ -260,7 +259,7 @@ static void getJoystickDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef
if (!CFStringGetCString ((CFStringRef)refCF, joyInfo->joystickName, 256, CFStringGetSystemEncoding ()))
irr::os::Printer::log("CFStringGetCString error getting joyInfo->joystickName", irr::ELL_ERROR);
}
/* get usage page and usage */
refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
if (refCF)
@ -368,17 +367,17 @@ CIrrDeviceMacOSX::CIrrDeviceMacOSX(const SIrrlichtCreationParameters& param)
initKeycodes();
if (CreationParams.DriverType != video::EDT_NULL)
createWindow();
setResizable(false);
CursorControl = new CCursorControl(CreationParams.WindowSize, this);
createDriver();
if (IsSoftwareRenderer && CreationParams.DriverType != video::EDT_NULL)
{
// create context for rendering raw bitmap
}
createGUIAndScene();
}
@ -445,7 +444,7 @@ bool CIrrDeviceMacOSX::createWindow()
display = CGMainDisplayID();
ScreenWidth = (int) CGDisplayPixelsWide(display);
ScreenHeight = (int) CGDisplayPixelsHigh(display);
VideoModeList.setDesktop(CreationParams.Bits, core::dimension2d<u32>(ScreenWidth, ScreenHeight));
if (!CreationParams.Fullscreen)
@ -453,7 +452,7 @@ bool CIrrDeviceMacOSX::createWindow()
Window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,CreationParams.WindowSize.Width,CreationParams.WindowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:NSBackingStoreBuffered defer:FALSE];
if (Window != NULL)
{
NSOpenGLPixelFormatAttribute windowattribs[] =
NSOpenGLPixelFormatAttribute windowattribs[] =
{
NSOpenGLPFANoRecovery,
NSOpenGLPFAAccelerated,
@ -503,7 +502,7 @@ bool CIrrDeviceMacOSX::createWindow()
windowattribs[12] = (NSOpenGLPixelFormatAttribute)((int)windowattribs[12]-1);
format = [[NSOpenGLPixelFormat alloc] initWithAttributes:windowattribs];
}
if (!format)
{
windowattribs[9] = (NSOpenGLPixelFormatAttribute)0;
@ -519,7 +518,7 @@ bool CIrrDeviceMacOSX::createWindow()
{
os::Printer::log("No FSAA available.", ELL_WARNING);
}
}
}
}
@ -622,25 +621,20 @@ bool CIrrDeviceMacOSX::createWindow()
CGLSetCurrentContext(CGLContext);
newSwapInterval = (CreationParams.Vsync) ? 1 : 0;
CGLSetParameter(CGLContext,kCGLCPSwapInterval,&newSwapInterval);
glViewport(0,0,DeviceWidth,DeviceHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
return (result);
}
void CIrrDeviceMacOSX::setResize(int width, int height)
{
{
// set new window size
DeviceWidth = width;
DeviceHeight = height;
// update the size of the opengl rendering context
[OGLContext update];
// resize the driver to the inner pane size
NSRect driverFrame = [Window contentRectForFrameRect:[Window frame]];
getVideoDriver()->OnResize(core::dimension2d<u32>( (s32)driverFrame.size.width, (s32)driverFrame.size.height));
@ -689,7 +683,6 @@ void CIrrDeviceMacOSX::createDriver()
os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
break;
}
}
void CIrrDeviceMacOSX::flush()
@ -728,32 +721,32 @@ bool CIrrDeviceMacOSX::run()
ievent.EventType = irr::EET_KEY_INPUT_EVENT;
ievent.KeyInput.Shift = ([(NSEvent *)event modifierFlags] & NSShiftKeyMask ) != 0;
ievent.KeyInput.Control = ([(NSEvent *)event modifierFlags] & NSControlKeyMask) != 0;
if (IsShiftDown != ievent.KeyInput.Shift)
{
ievent.KeyInput.Char = irr::KEY_SHIFT;
ievent.KeyInput.Key = irr::KEY_SHIFT;
ievent.KeyInput.PressedDown = ievent.KeyInput.Shift;
IsShiftDown = ievent.KeyInput.Shift;
postEventFromUser(ievent);
}
if (IsControlDown != ievent.KeyInput.Control)
{
ievent.KeyInput.Char = irr::KEY_CONTROL;
ievent.KeyInput.Key = irr::KEY_CONTROL;
ievent.KeyInput.PressedDown = ievent.KeyInput.Control;
IsControlDown = ievent.KeyInput.Control;
postEventFromUser(ievent);
}
[NSApp sendEvent:event];
break;
break;
case NSLeftMouseDown:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN;
@ -769,7 +762,7 @@ bool CIrrDeviceMacOSX::run()
ievent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP;
postMouseEvent(event,ievent);
break;
case NSOtherMouseDown:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN;
@ -777,7 +770,7 @@ bool CIrrDeviceMacOSX::run()
ievent.MouseInput.ButtonStates = MouseButtonStates;
postMouseEvent(event,ievent);
break;
case NSOtherMouseUp:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
MouseButtonStates &= !irr::EMBSM_MIDDLE;
@ -816,8 +809,10 @@ bool CIrrDeviceMacOSX::run()
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL;
ievent.MouseInput.Wheel = [(NSEvent *)event deltaY];
if (ievent.MouseInput.Wheel < 1.0f) ievent.MouseInput.Wheel *= 10.0f;
else ievent.MouseInput.Wheel *= 5.0f;
if (ievent.MouseInput.Wheel < 1.0f)
ievent.MouseInput.Wheel *= 10.0f;
else
ievent.MouseInput.Wheel *= 5.0f;
postMouseEvent(event,ievent);
break;
@ -868,7 +863,7 @@ void CIrrDeviceMacOSX::setWindowCaption(const wchar_t* text)
if (Window != NULL)
{
size = wcstombs(title,text,1024);
if (size == 1024) title[1023] = 0;
title[1023] = 0;
[Window setTitle:[NSString stringWithCString:title length:size]];
}
}
@ -912,7 +907,7 @@ void CIrrDeviceMacOSX::postKeyEvent(void *event,irr::SEvent &ievent,bool pressed
c = [str characterAtIndex:0];
iter = KeyCodes.find(c);
if (iter != KeyCodes.end())
if (iter != KeyCodes.end())
mkey = (*iter).second;
else
{
@ -921,8 +916,8 @@ void CIrrDeviceMacOSX::postKeyEvent(void *event,irr::SEvent &ievent,bool pressed
{
mkey = irr::KEY_PERIOD;
mchar = '.';
}
else
}
else
{
cStr = (unsigned char *)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
if (cStr != NULL && strlen((char*)cStr) > 0)
@ -965,8 +960,8 @@ void CIrrDeviceMacOSX::postMouseEvent(void *event,irr::SEvent &ievent)
{
ievent.MouseInput.X = (int)[(NSEvent *)event locationInWindow].x;
ievent.MouseInput.Y = DeviceHeight - (int)[(NSEvent *)event locationInWindow].y;
if (ievent.MouseInput.Y < 0)
if (ievent.MouseInput.Y < 0)
post = false;
}
else
@ -977,7 +972,7 @@ void CIrrDeviceMacOSX::postMouseEvent(void *event,irr::SEvent &ievent)
if (post)
postEventFromUser(ievent);
[NSApp sendEvent:(NSEvent *)event];
}
@ -1090,7 +1085,7 @@ void CIrrDeviceMacOSX::setResizable(bool resize)
{
IsResizable = resize;
}
bool CIrrDeviceMacOSX::isResizable() const
{
return IsResizable;
@ -1100,13 +1095,13 @@ void CIrrDeviceMacOSX::minimizeWindow()
{
// todo: implement
}
//! Maximizes the window if possible.
void CIrrDeviceMacOSX::maximizeWindow()
{
// todo: implement
}
//! Restore the window to normal size if possible.
void CIrrDeviceMacOSX::restoreWindow()
{
@ -1116,23 +1111,23 @@ void CIrrDeviceMacOSX::restoreWindow()
bool CIrrDeviceMacOSX::present(video::IImage* surface, void* windowId, core::rect<s32>* src )
{
// todo: implement window ID and src rectangle
if (!surface)
return false;
if (IsSoftwareRenderer)
{
// do we need to change the size?
bool updateSize = !SoftwareDriverTarget ||
s32([SoftwareDriverTarget size].width) != surface->getDimension().Width ||
s32([SoftwareDriverTarget size].height) != surface->getDimension().Height;
// release if necessary
if (SoftwareDriverTarget && updateSize)
[SoftwareDriverTarget release];
NSRect areaRect = NSMakeRect(0.0, 0.0, surface->getDimension().Width, surface->getDimension().Height);
// get pointer to image data
unsigned char* imgData = (unsigned char*)surface->lock();
@ -1140,25 +1135,25 @@ bool CIrrDeviceMacOSX::present(video::IImage* surface, void* windowId, core::rec
if (updateSize)
{
// allocate target for IImage
SoftwareDriverTarget = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: nil
pixelsWide: areaRect.size.width
pixelsHigh: areaRect.size.height
bitsPerSample: 8
samplesPerPixel: 3
hasAlpha: NO
isPlanar: NO
colorSpaceName: NSCalibratedRGBColorSpace
bytesPerRow: (3 * areaRect.size.width)
bitsPerPixel: 24];
SoftwareDriverTarget = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: nil
pixelsWide: areaRect.size.width
pixelsHigh: areaRect.size.height
bitsPerSample: 8
samplesPerPixel: 3
hasAlpha: NO
isPlanar: NO
colorSpaceName: NSCalibratedRGBColorSpace
bytesPerRow: (3 * areaRect.size.width)
bitsPerPixel: 24];
}
const u32 destwidth = areaRect.size.width;
const u32 minWidth = core::min_(surface->getDimension().Width, destwidth);
const u32 destPitch = (3 * areaRect.size.width);
u8* srcdata = reinterpret_cast<u8*>(imgData);
u8* destData = reinterpret_cast<u8*>([SoftwareDriverTarget bitmapData]);
u8* destData = reinterpret_cast<u8*>([SoftwareDriverTarget bitmapData]);
const u32 destheight = areaRect.size.height;
const u32 srcheight = core::min_(surface->getDimension().Height, destheight);
const u32 srcPitch = surface->getPitch();
@ -1168,22 +1163,20 @@ bool CIrrDeviceMacOSX::present(video::IImage* surface, void* windowId, core::rec
srcdata += srcPitch;
destData += destPitch;
}
// unlock the data
surface->unlock();
// todo: draw properly into a sub-view
[SoftwareDriverTarget draw];
}
return false;
}
#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
static void joystickRemovalCallback(void * target,
IOReturn result,
void * refcon,
void * sender)
IOReturn result, void * refcon, void * sender)
{
JoystickInfo *joy = (JoystickInfo *) refcon;
joy->removed = 1;
@ -1279,27 +1272,27 @@ bool CIrrDeviceMacOSX::activateJoysticks(core::array<SJoystickInfo> & joystickIn
{
CFRelease (hidProperties);
os::Printer::log("initialiseJoysticks Open interface failed", ELL_ERROR);
continue;
continue;
}
CFRelease (hidProperties);
result = IOObjectRelease (hidObject);
if ( (info.usagePage != kHIDPage_GenericDesktop) ||
((info.usage != kHIDUsage_GD_Joystick &&
info.usage != kHIDUsage_GD_GamePad &&
info.usage != kHIDUsage_GD_MultiAxisController)) )
((info.usage != kHIDUsage_GD_Joystick &&
info.usage != kHIDUsage_GD_GamePad &&
info.usage != kHIDUsage_GD_MultiAxisController)) )
{
closeJoystickDevice (&info);
continue;
}
for (u32 i = 0; i < 6; i++)
for (u32 i = 0; i < 6; ++i)
info.persistentData.JoystickEvent.Axis[i] = 0;
ActiveJoysticks.push_back(info);
SJoystickInfo returnInfo;
returnInfo.Axes = info.axes;
//returnInfo.Hats = info.hats;
@ -1340,7 +1333,7 @@ void CIrrDeviceMacOSX::pollJoysticks()
{
if (ActiveJoysticks[joystick].removed)
continue;
bool found = false;
ActiveJoysticks[joystick].persistentData.JoystickEvent.Joystick = joystick;
@ -1363,7 +1356,7 @@ void CIrrDeviceMacOSX::pollJoysticks()
ActiveJoysticks[joystick].axisComp[n].minRead = hidEvent.value;
if (hidEvent.value > ActiveJoysticks[joystick].axisComp[n].maxRead)
ActiveJoysticks[joystick].axisComp[n].maxRead = hidEvent.value;
if (readScale != 0.0f)
hidEvent.value = (int)(((f32)((f32)hidEvent.value - (f32)ActiveJoysticks[joystick].axisComp[n].minRead) * deviceScale / readScale) + min);

View File

@ -36,7 +36,7 @@ IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderJPG.o CIm
CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)
IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CZipReader.o CPakReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CZipReader.o CPakReader.o CNPKReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o
IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CLogger.o COSOperator.o Irrlicht.o os.o
IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o
ZLIBOBJ = zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o zlib/uncompr.o zlib/zutil.o

View File

@ -41,7 +41,7 @@ IRRVIDEOOBJ = ['CVideoModeList.cpp', 'CFPSCounter.cpp'] + IRRDRVROBJ + IRRIMAGEO
IRRSWRENDEROBJ = ['CSoftwareDriver.cpp', 'CSoftwareTexture.cpp', 'CTRFlat.cpp', 'CTRFlatWire.cpp', 'CTRGouraud.cpp', 'CTRGouraudWire.cpp', 'CTRTextureFlat.cpp', 'CTRTextureFlatWire.cpp', 'CTRTextureGouraud.cpp', 'CTRTextureGouraudAdd.cpp', 'CTRTextureGouraudNoZ.cpp', 'CTRTextureGouraudWire.cpp', 'CZBuffer.cpp', 'CTRTextureGouraudVertexAlpha2.cpp', 'CTRTextureGouraudNoZ2.cpp', 'CTRTextureLightMap2_M2.cpp', 'CTRTextureLightMap2_M4.cpp', 'CTRTextureLightMap2_M1.cpp', 'CSoftwareDriver2.cpp', 'CSoftwareTexture2.cpp', 'CTRTextureGouraud2.cpp', 'CTRGouraud2.cpp', 'CTRGouraudAlpha2.cpp', 'CTRGouraudAlphaNoZ2.cpp', 'CTRTextureDetailMap2.cpp', 'CTRTextureGouraudAdd2.cpp', 'CTRTextureGouraudAddNoZ2.cpp', 'CTRTextureWire2.cpp', 'CTRTextureLightMap2_Add.cpp', 'CTRTextureLightMapGouraud2_M4.cpp', 'IBurningShader.cpp', 'CTRTextureBlend.cpp', 'CTRTextureGouraudAlpha.cpp', 'CTRTextureGouraudAlphaNoZ.cpp', 'CDepthBuffer.cpp', 'CBurningShader_Raster_Reference.cpp'];
IRRIOOBJ = ['CFileList.cpp', 'CFileSystem.cpp', 'CLimitReadFile.cpp', 'CMemoryReadFile.cpp', 'CReadFile.cpp', 'CWriteFile.cpp', 'CXMLReader.cpp', 'CXMLWriter.cpp', 'CZipReader.cpp', 'CPakReader.cpp', 'irrXML.cpp', 'CAttributes.cpp'];
IRRIOOBJ = ['CFileList.cpp', 'CFileSystem.cpp', 'CLimitReadFile.cpp', 'CMemoryReadFile.cpp', 'CReadFile.cpp', 'CWriteFile.cpp', 'CXMLReader.cpp', 'CXMLWriter.cpp', 'CZipReader.cpp', 'CPakReader.cpp', 'CNPKReader.cpp', 'irrXML.cpp', 'CAttributes.cpp'];
IRROTHEROBJ = ['CIrrDeviceSDL.cpp', 'CIrrDeviceLinux.cpp', 'CIrrDeviceStub.cpp', 'CIrrDeviceWin32.cpp', 'CLogger.cpp', 'COSOperator.cpp', 'Irrlicht.cpp', 'os.cpp'];

View File

@ -418,7 +418,7 @@ REALINLINE f32 fix_inverse32 ( const f32 x )
static inline int f_round2(f32 f)
{
f += (3<<22);
return *((int*)&f) - 0x4b400000;
return IR(f) - 0x4b400000;
}
/*
@ -514,7 +514,7 @@ inline s32 roundFix ( const tFixPoint x )
inline s32 f32_to_23Bits(const f32 x)
{
f32 y = x + 1.f;
return ((u32&)y) & 0x7FFFFF; // last 23 bits
return IR(y) & 0x7FFFFF; // last 23 bits
}
/*!

View File

@ -14,8 +14,6 @@
// This support library has been made by Salvatore Russo and is released under GNU public license for general uses.
// For uses in Irrlicht core and only for Irrlicht related uses I release this library under zlib license.
// It uses standard template libraries to create String class and StringList class used in DeleD
// plugins made by me.
#ifndef __DMF_SUPPORT_H_INCLUDED__
#define __DMF_SUPPORT_H_INCLUDED__
@ -27,6 +25,8 @@ namespace irr
{
namespace scene
{
namespace
{
/** A structure representing some DeleD infos.
This structure contains data about DeleD level file like: version, ambient colour, number of objects etc...*/
@ -73,7 +73,7 @@ struct dmfFace
};
/** A structure rapresenting a single vertice.
/** A structure representing a single vertice.
This structure contains vertice position coordinates and texture an lightmap UV.*/
struct dmfVert
{
@ -93,7 +93,7 @@ struct dmfLight
f32 radius;//!<Maximum radius of light.
};
/** A structure rapresenting a single water plane.
/** A structure representing a single water plane.
This structure contains light position coordinates, diffuse colour, specular colour and maximum radius of light.*/
struct dmfWaterPlane
{
@ -117,87 +117,50 @@ int axtoi(const char *hexStg)
return (intValue);
}
typedef core::array<core::stringc> StringList;
/** A standard string.
A standard string created with standard template libraries.*/
typedef core::stringc String;
//Define a class StringList based on core::array and the defined class String
/** A simple stringlist class based on core::array.
This StringList class is based on core::array and the defined String class.
*/
class StringList : public core::array<String>
//Loads a stringlist from a file
//note that each String added to StringList
//is separated by a \\n character and it's present
//at the end of line.
/** Loads a StringList from a file.
This function loads a StringList from a file where each string is divided by a \\n char.*/
void LoadFromFile(io::IReadFile* file, StringList& strlist)
{
public:
const long sz = file->getSize();
char* buf = new char[sz+1];
file->read(buf, sz);
buf[sz] = 0;
char* p = buf;
char* start = p;
/**Basic Constructor*/
StringList()
while(*p)
{
}
/**Constructor based on file loading.
Look at LoadFromFile specifications.*/
StringList(io::IReadFile* file)
{
LoadFromFile(file);
}
/**Basic destructor.*/
~StringList()
{
clear();
}
//Adds a String to StringList
/** Add a string to this StringList.*/
void Add(String str/*<String to add to the current StringList*/)
{
push_back(str);
}
//Loads a stringlist from a file
//note that each String added to StringList
//is separated by a \\n character and it's present
//at the end of line.
/** Loads a StringList from a file.
This function loads a StringList from a file where each string is divided by a \\n char.*/
void LoadFromFile(io::IReadFile* file)
{
const long sz = file->getSize();
char* buf = new char[sz+1];
file->read(buf, sz);
buf[sz] = 0;
char* p = buf;
char* start = p;
while(*p)
{
if (*p == '\n')
{
core::stringc str(start, (u32)(p - start - 1));
str.trim();
Add(str);
start = p+1;
}
++p;
}
if (p - start > 1)
if (*p == '\n')
{
core::stringc str(start, (u32)(p - start - 1));
str.trim();
Add(str);
strlist.push_back(str);
start = p+1;
}
delete [] buf;
++p;
}
if (p - start > 1)
{
core::stringc str(start, (u32)(p - start - 1));
str.trim();
strlist.push_back(str);
}
delete [] buf;
};
//This function subdivides a string in a list of strings
/** This function subdivides strings divided by divider in a list of strings.
\return A StringList made of all strings divided by divider.*/
StringList SubdivideString(const String& str, const String& divider)
StringList SubdivideString(const core::stringc& str, const core::stringc& divider)
{
StringList strings; //returned StringList
strings.clear(); //clear returned stringlist
@ -208,7 +171,7 @@ StringList SubdivideString(const String& str, const String& divider)
//process entire string
while(c<l)
{
String resultstr;
core::stringc resultstr;
resultstr = "";
//read characters until divider is encountered
while((str[c]!=divider[0]) && c<l)
@ -221,7 +184,7 @@ StringList SubdivideString(const String& str, const String& divider)
//pay attention or change it in dll.h if you don't want to remove
//a particular char.
resultstr.trim();//trims string resultstr
strings.Add(resultstr);//add trimmed string
strings.push_back(resultstr);//add trimmed string
++c;
}
@ -235,21 +198,23 @@ You must give in input a StringList representing a DMF file loaded with LoadFrom
\return true if function succeed or false on fail.*/
bool GetDMFHeader(const StringList& RawFile, dmfHeader& header)
{
StringList temp=SubdivideString(RawFile[0],String(";")); //file info
StringList temp;
RawFile[0].split(temp, ";"); //file info
// StringList temp=SubdivideString(RawFile[0],";"); //file info
if ( temp[0] != String("DeleD Map File") )
if ( temp[0] != "DeleD Map File" )
return false; //not a deled file
temp.clear();
temp = SubdivideString(RawFile[1],String(" "));//get version
StringList temp1=SubdivideString(temp[1],String(";"));
temp = SubdivideString(RawFile[1]," ");//get version
StringList temp1=SubdivideString(temp[1],";");
header.dmfVersion = (float)atof(temp1[0].c_str());//save version
if (header.dmfVersion < 0.91)
return false;//not correct version
temp.clear();
temp = SubdivideString(RawFile[2],String(";"));//get name,ambient color and shadow opacity
temp = SubdivideString(RawFile[2],";");//get name,ambient color and shadow opacity
header.dmfName=temp[0];//save name
//set ambient color
@ -281,8 +246,8 @@ bool GetDMFHeader(const StringList& RawFile, dmfHeader& header)
for(i=0; i < (int)header.numObjects; i++)
{
StringList wat=SubdivideString(RawFile[offs],String(";"));
StringList wat1=SubdivideString(wat[0],String("_"));
StringList wat=SubdivideString(RawFile[offs],";");
StringList wat1=SubdivideString(wat[0],"_");
++offs;
offs += atoi(RawFile[offs].c_str());
@ -290,7 +255,7 @@ bool GetDMFHeader(const StringList& RawFile, dmfHeader& header)
fac=atoi(RawFile[offs].c_str());
if(!(wat1[0]==String("water") && wat[2]==String("0")))
if(!(wat1[0]=="water" && wat[2]=="0"))
header.numFaces = header.numFaces + fac;
else
header.numWatFaces = header.numWatFaces + fac;
@ -299,7 +264,7 @@ bool GetDMFHeader(const StringList& RawFile, dmfHeader& header)
for(int j=0; j<fac; j++)
{
if(!(wat1[0] == String("water") && wat[2] == String("0")))
if(!(wat1[0] == "water" && wat[2] == "0"))
header.numVertices=header.numVertices + atoi(RawFile[offs+j].c_str());
else
header.numWatVertices=header.numWatVertices + atoi(RawFile[offs + j].c_str());
@ -317,13 +282,13 @@ bool GetDMFHeader(const StringList& RawFile, dmfHeader& header)
for (i=0; i<lit; i++)
{
offs++;
temp=SubdivideString(RawFile[offs],String(";"));
temp=SubdivideString(RawFile[offs],";");
if(atoi(temp[0].c_str())==1)
{
temp1=SubdivideString(temp[18],String("_"));
temp1=SubdivideString(temp[18],"_");
if(temp1[0]==String("dynamic"))
if(temp1[0]=="dynamic")
header.numLights++;
}
temp.clear();
@ -404,14 +369,14 @@ bool GetDMFWaterMaterials(const StringList& RawFile /**<StringList representing
StringList temp1;
StringList temp2;
//Checking if this is a DeleD map File of version >= 0.91
temp=SubdivideString(RawFile[0],String(";"));//file info
temp=SubdivideString(RawFile[0],";");//file info
if ( temp[0] != String("DeleD Map File") )
if ( temp[0] != "DeleD Map File" )
return false;//not a deled file
temp.clear();
temp=SubdivideString(RawFile[1],String(" "));//get version
temp1=SubdivideString(temp[1],String(";"));
temp=SubdivideString(RawFile[1]," ");//get version
temp1=SubdivideString(temp[1],";");
if (atof(temp1[0].c_str()) < 0.91)
return false;//not correct version
@ -498,7 +463,7 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a
const s32 numFaces=atoi(RawFile[offs].c_str());
offs++;
if(!(wat1[0]==String("water") && wat[2]==String("0")))
if(!(wat1[0]=="water" && wat[2]=="0"))
{
for(s32 j=0; j<numFaces; ++j)
{
@ -550,14 +515,14 @@ bool GetDMFLights(const StringList& RawFile/**<StringList representing a DMF fil
StringList temp,temp1;
//Checking if this is a DeleD map File of version >= 0.91
temp=SubdivideString(RawFile[0],String(";"));//file info
temp=SubdivideString(RawFile[0],";");//file info
if ( temp[0] != String("DeleD Map File") )
if ( temp[0] != "DeleD Map File" )
return false;//not a deled file
temp.clear();
temp=SubdivideString(RawFile[1],String(" "));//get version
temp1=SubdivideString(temp[1],String(";"));
temp=SubdivideString(RawFile[1]," ");//get version
temp1=SubdivideString(temp[1],";");
if (atof(temp1[0].c_str()) < 0.91)
return false;//not correct version
@ -592,11 +557,11 @@ bool GetDMFLights(const StringList& RawFile/**<StringList representing a DMF fil
for(i=0;i<lit;i++)
{
offs++;
temp=SubdivideString(RawFile[offs],String(";"));
temp=SubdivideString(RawFile[offs],";");
if(atoi(temp[0].c_str())==1)
{
temp1=SubdivideString(temp[18],String("_"));
if(temp1[0]==String("dynamic"))
temp1=SubdivideString(temp[18],"_");
if(temp1[0]=="dynamic")
{
lights[d_lit].radius = (float)atof(temp[4].c_str());
lights[d_lit].pos.set((float)atof(temp[5].c_str()),
@ -637,14 +602,14 @@ bool GetDMFWaterPlanes(const StringList& RawFile/**<StringList representing a DM
StringList temp,temp1;
//Checking if this is a DeleD map File of version >= 0.91
temp=SubdivideString(RawFile[0],String(";"));//file info
temp=SubdivideString(RawFile[0],";");//file info
if ( temp[0] != String("DeleD Map File") )
if ( temp[0] != "DeleD Map File" )
return false;//not a deled file
temp.clear();
temp=SubdivideString(RawFile[1],String(" "));//get version
temp1=SubdivideString(temp[1],String(";"));
temp=SubdivideString(RawFile[1]," ");//get version
temp1=SubdivideString(temp[1],";");
if (atof(temp1[0].c_str()) < 0.91)
return false;//not correct version
@ -675,7 +640,7 @@ bool GetDMFWaterPlanes(const StringList& RawFile/**<StringList representing a DM
fac=atoi(RawFile[offs].c_str());
offs++;
if(wat1[0]==String("water") && wat[2]==String("0"))
if(wat1[0]=="water" && wat[2]=="0")
{
StringList userinfo=SubdivideString(wat[7],",");
@ -760,6 +725,8 @@ bool GetDMFWaterPlanes(const StringList& RawFile/**<StringList representing a DM
}
} // end namespace
} // end namespace
} // end namespace scene
} // end namespace irr
#endif /* __DMF_SUPPORT_H__ */

View File

@ -29,9 +29,9 @@ extern "C" {
*/
/* Header file version number, required by OpenGL ABI for Linux */
/* glext.h last updated $Date: 2009-08-03 02:13:51 -0700 (Mon, 03 Aug 2009) $ */
/* glext.h last updated $Date: 2009-09-24 13:55:03 -0700 (Thu, 24 Sep 2009) $ */
/* Current version at http://www.opengl.org/registry/ */
#define GL_GLEXT_VERSION 54
#define GL_GLEXT_VERSION 56
/* Function declaration macros - to move into glplatform.h */
@ -4236,7 +4236,7 @@ extern "C" {
#define GL_LUMINANCE16_SNORM 0x9019
#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
#define GL_INTENSITY16_SNORM 0x901B
/* reuse GL_R_SNORM */
/* reuse GL_RED_SNORM */
/* reuse GL_RG_SNORM */
/* reuse GL_RGB_SNORM */
/* reuse GL_RGBA_SNORM */
@ -4311,6 +4311,88 @@ extern "C" {
#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
#endif
#ifndef GL_APPLE_rgb_422
#define GL_RGB_422_APPLE 0x8A1F
/* reuse GL_UNSIGNED_SHORT_8_8_APPLE */
/* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */
#endif
#ifndef GL_NV_video_capture
#define GL_VIDEO_BUFFER_NV 0x9020
#define GL_VIDEO_BUFFER_BINDING_NV 0x9021
#define GL_FIELD_UPPER_NV 0x9022
#define GL_FIELD_LOWER_NV 0x9023
#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
#define GL_VIDEO_BUFFER_PITCH_NV 0x9028
#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
#define GL_PARTIAL_SUCCESS_NV 0x902E
#define GL_SUCCESS_NV 0x902F
#define GL_FAILURE_NV 0x9030
#define GL_YCBYCR8_422_NV 0x9031
#define GL_YCBAYCR8A_4224_NV 0x9032
#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
#endif
#ifndef GL_NV_copy_image
#endif
#ifndef GL_EXT_separate_shader_objects
#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
#endif
#ifndef GL_NV_parameter_buffer_object2
#endif
#ifndef GL_NV_shader_buffer_load
#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
#define GL_GPU_ADDRESS_NV 0x8F34
#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
#endif
#ifndef GL_NV_vertex_buffer_unified_memory
#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
#endif
#ifndef GL_NV_texture_barrier
#endif
/*************************************************************/
@ -9245,6 +9327,136 @@ typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType,
#define GL_APPLE_row_bytes 1
#endif
#ifndef GL_APPLE_rgb_422
#define GL_APPLE_rgb_422 1
#endif
#ifndef GL_NV_video_capture
#define GL_NV_video_capture 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint);
GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint, GLuint, GLenum, GLintptrARB);
GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint, GLuint, GLenum, GLenum, GLuint);
GLAPI void APIENTRY glEndVideoCaptureNV (GLuint);
GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint, GLenum, GLint *);
GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint, GLuint, GLenum, GLint *);
GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint, GLuint, GLenum, GLfloat *);
GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint, GLuint, GLenum, GLdouble *);
GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint, GLuint *, GLuint64EXT *);
GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint, GLuint, GLenum, const GLint *);
GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint, GLuint, GLenum, const GLfloat *);
GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint, GLuint, GLenum, const GLdouble *);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
#endif
#ifndef GL_NV_copy_image
#define GL_NV_copy_image 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glCopyImageSubDataNV (GLuint, GLenum, GLint, GLint, GLint, GLint, GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif
#ifndef GL_EXT_separate_shader_objects
#define GL_EXT_separate_shader_objects 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glUseShaderProgramEXT (GLenum, GLuint);
GLAPI void APIENTRY glActiveProgramEXT (GLuint);
GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum, const GLchar *);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string);
#endif
#ifndef GL_NV_parameter_buffer_object2
#define GL_NV_parameter_buffer_object2 1
#endif
#ifndef GL_NV_shader_buffer_load
#define GL_NV_shader_buffer_load 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glMakeBufferResidentNV (GLenum, GLenum);
GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum);
GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum);
GLAPI void APIENTRY glNamedMakeBufferResidentNV (GLuint, GLenum);
GLAPI void APIENTRY glNamedMakeBufferNonResidentNV (GLuint);
GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint);
GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum, GLenum, GLuint64EXT *);
GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint, GLenum, GLuint64EXT *);
GLAPI void APIENTRY glGetIntegerui64vNV (GLenum, GLuint64EXT *);
GLAPI void APIENTRY glUniformui64NV (GLint, GLuint64EXT);
GLAPI void APIENTRY glUniformui64vNV (GLint, GLsizei, const GLuint64EXT *);
GLAPI void APIENTRY glGetUniformui64vNV (GLuint, GLint, GLuint64EXT *);
GLAPI void APIENTRY glProgramUniformui64NV (GLuint, GLint, GLuint64EXT);
GLAPI void APIENTRY glProgramUniformui64vNV (GLuint, GLint, GLsizei, const GLuint64EXT *);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
typedef void (APIENTRYP PFNGLNAMEDMAKEBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
typedef void (APIENTRYP PFNGLNAMEDMAKEBUFFERNONRESIDENTNVPROC) (GLuint buffer);
typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params);
typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params);
typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result);
typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params);
typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
#endif
#ifndef GL_NV_vertex_buffer_unified_memory
#define GL_NV_vertex_buffer_unified_memory 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glBufferAddressRangeNV (GLenum, GLuint, GLuint64EXT, GLsizeiptr);
GLAPI void APIENTRY glVertexFormatNV (GLint, GLenum, GLsizei);
GLAPI void APIENTRY glNormalFormatNV (GLenum, GLsizei);
GLAPI void APIENTRY glColorFormatNV (GLint, GLenum, GLsizei);
GLAPI void APIENTRY glIndexFormatNV (GLenum, GLsizei);
GLAPI void APIENTRY glTexCoordFormatNV (GLint, GLenum, GLsizei);
GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei);
GLAPI void APIENTRY glSecondaryColorFormatNV (GLint, GLenum, GLsizei);
GLAPI void APIENTRY glFogCoordFormatNV (GLenum, GLsizei);
GLAPI void APIENTRY glVertexAttribFormatNV (GLuint, GLint, GLenum, GLboolean, GLsizei);
GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint, GLint, GLenum, GLsizei);
GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum, GLuint, GLuint64EXT *);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
#endif
#ifndef GL_NV_texture_barrier
#define GL_NV_texture_barrier 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glTextureBarrierNV (void);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void);
#endif
#ifdef __cplusplus
}

View File

@ -48,9 +48,9 @@ extern "C" {
/*************************************************************/
/* Header file version number, required by OpenGL ABI for Linux */
/* glxext.h last updated 2009/08/03 */
/* glxext.h last updated 2009/10/08 */
/* Current version at http://www.opengl.org/registry/ */
#define GLX_GLXEXT_VERSION 23
#define GLX_GLXEXT_VERSION 25
#ifndef GLX_VERSION_1_3
#define GLX_WINDOW_BIT 0x00000001
@ -382,6 +382,20 @@ extern "C" {
#ifndef GLX_NV_swap_group
#endif
#ifndef GLX_NV_video_capture
#define GLX_DEVICE_ID_NV 0x20CD
#define GLX_UNIQUE_ID_NV 0x20CE
#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
#endif
#ifndef GLX_EXT_swap_control
#define GLX_SWAP_INTERVAL_EXT 0x20F1
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
#endif
#ifndef GLX_NV_copy_image
#endif
/*************************************************************/
@ -415,6 +429,14 @@ typedef struct {
} GLXBufferClobberEventSGIX;
#endif
#ifndef GLX_NV_video_output
typedef unsigned int GLXVideoDeviceNV;
#endif
#ifndef GLX_NV_video_capture
typedef XID GLXVideoCaptureDeviceNV;
#endif
#ifndef GLEXT_64_TYPES_DEFINED
/* This code block is duplicated in glext.h, so must be protected */
#define GLEXT_64_TYPES_DEFINED
@ -827,14 +849,80 @@ typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawab
#ifndef GLX_NV_present_video
#define GLX_NV_present_video 1
#ifdef GLX_GLXEXT_PROTOTYPES
extern unsigned int * glXEnumerateVideoDevicesNV (Display *, int, int *);
extern int glXBindVideoDeviceNV (Display *, unsigned int, unsigned int, const int *);
#endif /* GLX_GLXEXT_PROTOTYPES */
typedef unsigned int * ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements);
typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
#endif
#ifndef GLX_NV_video_out
#define GLX_NV_video_out 1
#ifndef GLX_NV_video_output
#define GLX_NV_video_output 1
#ifdef GLX_GLXEXT_PROTOTYPES
extern int glXGetVideoDeviceNV (Display *, int, int, GLXVideoDeviceNV *);
extern int glXReleaseVideoDeviceNV (Display *, int, GLXVideoDeviceNV);
extern int glXBindVideoImageNV (Display *, GLXVideoDeviceNV, GLXPbuffer, int);
extern int glXReleaseVideoImageNV (Display *, GLXPbuffer);
extern int glXSendPbufferToVideoNV (Display *, GLXPbuffer, int, unsigned long *, GLboolean);
extern int glXGetVideoInfoNV (Display *, int, GLXVideoDeviceNV, unsigned long *, unsigned long *);
#endif /* GLX_GLXEXT_PROTOTYPES */
typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, GLXPbuffer pbuf);
typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#ifndef GLX_NV_swap_group
#define GLX_NV_swap_group 1
#ifdef GLX_GLXEXT_PROTOTYPES
extern Bool glXJoinSwapGroupNV (Display *, GLXDrawable, GLuint);
extern Bool glXBindSwapBarrierNV (Display *, GLuint, GLuint);
extern Bool glXQuerySwapGroupNV (Display *, GLXDrawable, GLuint *, GLuint *);
extern Bool glXQueryMaxSwapGroupsNV (Display *, int, GLuint *, GLuint *);
extern Bool glXQueryFrameCountNV (Display *, int, GLuint *);
extern Bool glXResetFrameCountNV (Display *, int);
#endif /* GLX_GLXEXT_PROTOTYPES */
typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group);
typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier);
typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, int screen, GLuint *count);
typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen);
#endif
#ifndef GLX_NV_video_capture
#define GLX_NV_video_capture 1
#ifdef GLX_GLXEXT_PROTOTYPES
extern int glXBindVideoCaptureDeviceNV (Display *, unsigned int, GLXVideoCaptureDeviceNV);
extern GLXVideoCaptureDeviceNV * glXEnumerateVideoCaptureDevicesNV (Display *, int, int *);
extern void glXLockVideoCaptureDeviceNV (Display *, GLXVideoCaptureDeviceNV);
extern int glXQueryVideoCaptureDeviceNV (Display *, GLXVideoCaptureDeviceNV, int, int *);
extern void glXReleaseVideoCaptureDeviceNV (Display *, GLXVideoCaptureDeviceNV);
#endif /* GLX_GLXEXT_PROTOTYPES */
typedef int ( * PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
typedef GLXVideoCaptureDeviceNV * ( * PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display *dpy, int screen, int *nelements);
typedef void ( * PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
typedef int ( * PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
typedef void ( * PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
#endif
#ifndef GLX_EXT_swap_control
#define GLX_EXT_swap_control 1
#ifdef GLX_GLXEXT_PROTOTYPES
extern int glXSwapIntervalEXT (Display *, GLXDrawable, int);
#endif /* GLX_GLXEXT_PROTOTYPES */
typedef int ( * PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable drawable, int interval);
#endif
#ifndef GLX_NV_copy_image
#define GLX_NV_copy_image 1
#ifdef GLX_GLXEXT_PROTOTYPES
extern void glXCopyImageSubDataNV (Display *, GLXContext, GLuint, GLenum, GLint, GLint, GLint, GLint, GLXContext, GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei);
#endif /* GLX_GLXEXT_PROTOTYPES */
typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif

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