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-e03cc46cb475master
parent
9167c11177
commit
329f550b17
85
changes.txt
85
changes.txt
|
@ -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
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
||||
|
|
|
@ -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.
|
||||
};
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
|
@ -113,7 +113,7 @@ enum eAllocStrategy
|
|||
{
|
||||
ALLOC_STRATEGY_SAFE = 0,
|
||||
ALLOC_STRATEGY_DOUBLE = 1,
|
||||
ALLOC_STRATEGY_SQRT = 2,
|
||||
ALLOC_STRATEGY_SQRT = 2
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -47,7 +47,7 @@ void CDepthBuffer::clear()
|
|||
#endif
|
||||
|
||||
u32 zMaxValue;
|
||||
zMaxValue = *(u32*) &zMax;
|
||||
zMaxValue = IR(zMax);
|
||||
|
||||
memset32 ( Buffer, zMaxValue, TotalSize );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -79,6 +79,7 @@ namespace gui
|
|||
bool Dragging, IsDraggable;
|
||||
bool DrawBackground;
|
||||
bool DrawTitlebar;
|
||||
bool IsActive;
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
@ -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__
|
||||
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -196,3 +196,4 @@ IReadFile* CPakReader::createAndOpenFile(u32 index)
|
|||
} // end namespace irr
|
||||
|
||||
#endif // __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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! ;)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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=
|
||||
|
||||
|
|
|
@ -1978,6 +1978,12 @@
|
|||
<File
|
||||
RelativePath=".\CPakReader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CNPKReader.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CNPKReader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CReadFile.cpp">
|
||||
</File>
|
||||
|
|
|
@ -2758,6 +2758,14 @@
|
|||
RelativePath="CPakReader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CNPKReader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CNPKReader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CReadFile.cpp"
|
||||
>
|
||||
|
|
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -2385,6 +2385,14 @@
|
|||
RelativePath="CPakReader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CNPKReader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CNPKReader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CTarReader.cpp"
|
||||
>
|
||||
|
|
|
@ -1131,6 +1131,12 @@
|
|||
<File
|
||||
RelativePath=".\CPakReader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CNPKReader.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CNPKReader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CTarReader.cpp">
|
||||
</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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'];
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue