Commit 07670acf authored by hybrid's avatar hybrid

Merged 1134:1151 from branch 1.4

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1152 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 86eda333
......@@ -109,7 +109,7 @@ int main()
*/
IrrlichtDevice *device =
#ifdef MACOSX
#ifdef _IRR_OSX_PLATFORM_
createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 16,
false, false, false, 0);
#else
......
......@@ -33,8 +33,8 @@ namespace gui
virtual u32 addItem(const wchar_t* text) = 0;
//! Removes an item from the combo box.
/** Warning. This will change the IDs of all following items */
virtual void removeItem(u32 id) = 0;
/** Warning. This will change the index of all following items */
virtual void removeItem(u32 idx) = 0;
//! Deletes all items in the combo box
virtual void clear() = 0;
......@@ -43,7 +43,7 @@ namespace gui
virtual s32 getSelected() const = 0;
//! Sets the selected item. Set this to -1 if no item should be selected
virtual void setSelected(s32 id) = 0;
virtual void setSelected(s32 idx) = 0;
};
......
......@@ -14,17 +14,22 @@
//! _IRR_WINDOWS_API_ for Windows or XBox
//! _IRR_LINUX_PLATFORM_ for Linux (it is defined here if no other os is defined)
//! _IRR_SOLARIS_PLATFORM_ for Solaris
//! _IRR_OSX_PLATFORM_ for Apple systems running OSX
//! _IRR_POSIX_API_ for Posix compatible systems
//! _IRR_USE_SDL_DEVICE_ for platform independent SDL framework
//! _IRR_USE_WINDOWS_DEVICE_ for Windows API based device
//! _IRR_USE_WINDOWS_CE_DEVICE_ for Windows CE API based device
//! _IRR_USE_LINUX_DEVICE_ for X11 based device
//! MACOSX for Mac OS X
//! _IRR_USE_OSX_DEVICE_ for Cocoa native windowing on OSX
//! Note: PLATFORM defines the OS specific layer, API can groups several platforms
//! DEVICE is the windowing system used, several PLATFORMs support more than one DEVICE
//! Moreover, the DEVICE defined here is not directly related to the Irrlicht devices created in the app (but may depend on each other).
//#define _IRR_USE_SDL_DEVICE_ 1
//! WIN32 for Windows32
//! WIN64 for Windows64
// The windows platform and API support SDL and WINDOW device
#if defined(WIN32) || defined(WIN64) || defined(_WIN32_WCE)
#define _IRR_WINDOWS_
#define _IRR_WINDOWS_API_
......@@ -33,12 +38,24 @@
#endif
#endif
// XBox only suppots the native Window stuff
#if defined(_XBOX)
#define _IRR_XBOX_PLATFORM_
#define _IRR_WINDOWS_API_
#define _IRR_USE_WINDOWS_DEVICE_
#endif
#if defined(__APPLE__) || defined(MACOSX)
#if !defined(MACOSX)
#define MACOSX // legacy support
#endif
#define _IRR_OSX_PLATFORM_
#if !defined(_IRR_USE_LINUX_DEVICE_) // for X11 windowing declare this
#define _IRR_USE_OSX_DEVICE_
#endif
#endif
#if !defined(_IRR_WINDOWS_API_) && !defined(MACOSX)
#if !defined(_IRR_WINDOWS_API_) && !defined(_IRR_OSX_PLATFORM_)
#if defined(__sparc__) || defined(__sun__)
#define __BIG_ENDIAN__
#define _IRR_SOLARIS_PLATFORM_
......@@ -93,7 +110,7 @@ define out. */
//! Define _IRR_OPENGL_USE_EXTPOINTER_ if the OpenGL renderer should use OpenGL extensions via function pointers.
/** On some systems there is no support for the dynamic extension of OpenGL
via function pointers such that this has to be undef'ed. */
#if !defined(MACOSX) && !defined(_IRR_SOLARIS_PLATFORM_)
#if !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_SOLARIS_PLATFORM_)
#define _IRR_OPENGL_USE_EXTPOINTER_
#endif
......@@ -302,7 +319,7 @@ B3D, MS3D or X meshes */
/** Irrlicht should use approximate float and integer fpu techniques
precision will be lower but speed higher. currently X86 only
*/
#if !defined(MACOSX) && !defined(_IRR_SOLARIS_PLATFORM_)
#if !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_SOLARIS_PLATFORM_)
//#define IRRLICHT_FAST_MATH
#endif
......
......@@ -211,7 +211,9 @@ namespace core
// only same sign
#define F32_A_GREATER_B(a,b) (F32_AS_S32((a)) > F32_AS_S32((b)))
#else
#define F32_LOWER_0(n) ((n) < 0.0f)
#define F32_LOWER_EQUAL_0(n) ((n) <= 0.0f)
#define F32_GREATER_0(n) ((n) > 0.0f)
......@@ -246,7 +248,7 @@ namespace core
/*
if (condition) state |= m; else state &= ~m;
*/
REALINLINE void setbit ( u32 &state, s32 condition, u32 mask )
REALINLINE void setbit_cond ( u32 &state, s32 condition, u32 mask )
{
// 0, or any postive to mask
//s32 conmask = -condition >> 31;
......
......@@ -12,7 +12,7 @@ namespace irr
namespace io
{
#if (defined(_IRR_POSIX_API_) || defined(MACOSX))
#if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -72,7 +72,7 @@ CFileList::CFileList()
// --------------------------------------------
// Linux version
#if (defined(_IRR_POSIX_API_) || defined(MACOSX))
#if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
FileEntry entry;
......
......@@ -191,7 +191,7 @@ const c8* CFileSystem::getWorkingDirectory()
#endif
#endif
#if (defined(_IRR_POSIX_API_) || defined(MACOSX))
#if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
getcwd(WorkingDirectory, (size_t)FILE_SYSTEM_MAX_PATH);
#endif
return WorkingDirectory;
......@@ -227,7 +227,7 @@ core::stringc CFileSystem::getAbsolutePath(const core::stringc& filename) const
ret = p;
#endif
#elif (defined(_IRR_POSIX_API_) || defined(MACOSX))
#elif (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
c8 fpath[4096];
p = realpath(filename.c_str(), fpath);
......
......@@ -127,12 +127,12 @@ s32 CGUIComboBox::getSelected() const
//! sets the selected item. Set this to -1 if no item should be selected
void CGUIComboBox::setSelected(s32 id)
void CGUIComboBox::setSelected(s32 idx)
{
if (id < -1 || id >= (s32)Items.size())
if (idx < -1 || idx >= (s32)Items.size())
return;
Selected = id;
Selected = idx;
}
void CGUIComboBox::updateAbsolutePosition()
......
......@@ -50,7 +50,7 @@ namespace gui
virtual s32 getSelected() const;
//! sets the selected item. Set this to -1 if no item should be selected
virtual void setSelected(s32 id);
virtual void setSelected(s32 idx);
//! update the position
virtual void updateAbsolutePosition();
......
......@@ -11,7 +11,6 @@
#include "CSkinnedMesh.h"
namespace irr
{
namespace scene
......@@ -31,16 +30,16 @@ namespace scene
// File header
struct MS3DHeader
{
c8 ID[10];
s32 Version;
char ID[10];
int Version;
} PACK_STRUCT;
// Vertex information
struct MS3DVertex
{
u8 Flags;
f32 Vertex[3];
s8 BoneID;
float Vertex[3];
char BoneID;
u8 RefCount;
} PACK_STRUCT;
......@@ -49,8 +48,8 @@ struct MS3DTriangle
{
u16 Flags;
u16 VertexIndices[3];
f32 VertexNormals[3][3];
f32 S[3], T[3];
float VertexNormals[3][3];
float S[3], T[3];
u8 SmoothingGroup;
u8 GroupIndex;
} PACK_STRUCT;
......@@ -58,26 +57,26 @@ struct MS3DTriangle
// Material information
struct MS3DMaterial
{
s8 Name[32];
f32 Ambient[4];
f32 Diffuse[4];
f32 Specular[4];
f32 Emissive[4];
f32 Shininess; // 0.0f - 128.0f
f32 Transparency; // 0.0f - 1.0f
char Name[32];
float Ambient[4];
float Diffuse[4];
float Specular[4];
float Emissive[4];
float Shininess; // 0.0f - 128.0f
float Transparency; // 0.0f - 1.0f
u8 Mode; // 0, 1, 2 is unused now
s8 Texture[128];
s8 Alphamap[128];
char Texture[128];
char Alphamap[128];
} PACK_STRUCT;
// Joint information
struct MS3DJoint
{
u8 Flags;
s8 Name[32];
s8 ParentName[32];
f32 Rotation[3];
f32 Translation[3];
char Name[32];
char ParentName[32];
float Rotation[3];
float Translation[3];
u16 NumRotationKeyframes;
u16 NumTranslationKeyframes;
} PACK_STRUCT;
......@@ -85,8 +84,15 @@ struct MS3DJoint
// Keyframe data
struct MS3DKeyframe
{
f32 Time;
f32 Parameter[3];
float Time;
float Parameter[3];
} PACK_STRUCT;
// vertex weights in 1.8.x
struct MS3DVertexWeights
{
char boneIds[3];
u8 weights[3];
} PACK_STRUCT;
// Default alignment
......@@ -96,6 +102,13 @@ struct MS3DKeyframe
#undef PACK_STRUCT
struct SGroup
{
core::stringc Name;
core::array<u16> VertexIds;
u16 MaterialIdx;
};
//! Constructor
CMS3DMeshFileLoader::CMS3DMeshFileLoader(video::IVideoDriver *driver)
: Driver(driver), AnimatedMesh(0)
......@@ -137,7 +150,7 @@ IAnimatedMesh* CMS3DMeshFileLoader::createMesh(io::IReadFile* file)
}
//! loads an md2 file
//! loads a milkshape file
bool CMS3DMeshFileLoader::load(io::IReadFile* file)
{
if (!file)
......@@ -180,11 +193,6 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
return false;
}
if ( pHeader->Version == 4 )
{
os::Printer::log("Milkshape3D version 4 (1.8) is not fully supported. Some features may not be available.", file->getFileName(), ELL_WARNING);
}
// get pointers to data
// vertices
......@@ -195,6 +203,12 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
pPtr += sizeof(u16);
MS3DVertex *vertices = (MS3DVertex*)pPtr;
pPtr += sizeof(MS3DVertex) * numVertices;
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
#ifdef __BIG_ENDIAN__
for (u16 tmp=0; tmp<numVertices; ++tmp)
for (u16 j=0; j<3; ++j)
......@@ -209,6 +223,12 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
pPtr += sizeof(u16);
MS3DTriangle *triangles = (MS3DTriangle*)pPtr;
pPtr += sizeof(MS3DTriangle) * numTriangles;
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
#ifdef __BIG_ENDIAN__
for (u16 tmp=0; tmp<numTriangles; ++tmp)
{
......@@ -230,13 +250,16 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
numGroups = os::Byteswap::byteswap(numGroups);
#endif
pPtr += sizeof(u16);
core::array<SGroup> groups;
groups.reallocate(numGroups);
//skip groups
//store groups
u32 i;
for (i=0; i<numGroups; ++i)
{
Groups.push_back(SGroup());
SGroup& grp = Groups.getLast();
groups.push_back(SGroup());
SGroup& grp = groups.getLast();
// The byte flag is before the name, so add 1
grp.Name = ((const c8*) pPtr) + 1;
......@@ -247,6 +270,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
triangleCount = os::Byteswap::byteswap(triangleCount);
#endif
pPtr += sizeof(u16);
grp.VertexIds.reallocate(triangleCount);
//pPtr += sizeof(u16) * triangleCount; // triangle indices
for (u16 j=0; j<triangleCount; ++j)
......@@ -264,6 +288,12 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
grp.MaterialIdx = 0;
pPtr += sizeof(c8); // material index
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
}
// skip materials
......@@ -276,12 +306,10 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
// MS3DMaterial *materials = (MS3DMaterial*)pPtr;
// pPtr += sizeof(MS3DMaterial) * numMaterials;
if(numMaterials <= 0)
if(numMaterials == 0)
{
// if there are no materials, add at least one buffer
AnimatedMesh->createBuffer();
}
for (i=0; i<numMaterials; ++i)
......@@ -300,7 +328,12 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
material->Transparency = os::Byteswap::byteswap(material->Transparency);
#endif
pPtr += sizeof(MS3DMaterial);
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
scene::SSkinMeshBuffer *tmpBuffer = AnimatedMesh->createBuffer();
......@@ -331,26 +364,36 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
}
// animation time
f32 framesPerSecond = *(f32*)pPtr;
f32 framesPerSecond = *(float*)pPtr;
#ifdef __BIG_ENDIAN__
framesPerSecond = os::Byteswap::byteswap(framesPerSecond);
#endif
pPtr += sizeof(f32) * 2; // fps and current time
pPtr += sizeof(float) * 2; // fps and current time
if (framesPerSecond==0)
framesPerSecond=1;
if (framesPerSecond<1.f)
framesPerSecond=1.f;
pPtr += sizeof(s32); // frameCount
// calculated inside SkinnedMesh
// s32 frameCount = *(int*)pPtr;
#ifdef __BIG_ENDIAN__
// frameCount = os::Byteswap::byteswap(frameCount);
#endif
pPtr += sizeof(int);
u16 jointCount = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
jointCount = os::Byteswap::byteswap(jointCount);
#endif
pPtr += sizeof(u16);
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
core::array<core::stringc> ParentNames;
core::array<core::stringc> parentNames;
parentNames.reallocate(jointCount);
// load joints
for (i=0; i<jointCount; ++i)
......@@ -366,34 +409,24 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes);
#endif
pPtr += sizeof(MS3DJoint);
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
ISkinnedMesh::SJoint *jnt = AnimatedMesh->createJoint();
/*
jnt.Name = pJoint->Name;
jnt.Index = i;
jnt.Rotation.X = pJoint->Rotation[0];
jnt.Rotation.Y = pJoint->Rotation[1];
jnt.Rotation.Z = pJoint->Rotation[2];
jnt.Translation.X = pJoint->Translation[0];
jnt.Translation.Y = pJoint->Translation[1];
jnt.Translation.Z = pJoint->Translation[2];
jnt.ParentName = pJoint->ParentName;
jnt.Parent = -1;
*/
jnt->Name = pJoint->Name;
jnt->LocalMatrix.makeIdentity();
jnt->LocalMatrix.setRotationRadians(
core::vector3df(pJoint->Rotation[0], pJoint->Rotation[1], pJoint->Rotation[2]) );
jnt->LocalMatrix.setTranslation(
core::vector3df(pJoint->Translation[0], pJoint->Translation[1], pJoint->Translation[2]) );
ParentNames.push_back( (c8*)pJoint->ParentName );
parentNames.push_back( (c8*)pJoint->ParentName );
/*if (pJoint->NumRotationKeyframes ||
pJoint->NumTranslationKeyframes)
......@@ -411,6 +444,12 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
#endif
pPtr += sizeof(MS3DKeyframe);
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
ISkinnedMesh::SRotationKey *k=AnimatedMesh->createRotationKey(jnt);
k->frame = kf->Time * framesPerSecond;
......@@ -436,6 +475,12 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
#endif
pPtr += sizeof(MS3DKeyframe);
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
ISkinnedMesh::SPositionKey *k=AnimatedMesh->createPositionKey(jnt);
k->frame = kf->Time * framesPerSecond;
......@@ -447,21 +492,109 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
}
}
core::array<MS3DVertexWeights> vertexWeights;
if ((pHeader->Version == 4) && (pPtr < buffer+fileSize))
{
s32 subVersion = *(s32*)pPtr; // comment subVersion, always 1
#ifdef __BIG_ENDIAN__
subVersion = os::Byteswap::byteswap(subVersion);
#endif
pPtr += sizeof(s32);
for (u32 j=0; j<4; ++j) // four comment groups
{
u32 numComments = *(u32*)pPtr;
#ifdef __BIG_ENDIAN__
numComments = os::Byteswap::byteswap(numComments);
#endif
pPtr += sizeof(u32);
for (i=0; i<numComments; ++i)
{
pPtr += sizeof(s32); // index
s32 commentLength = *(s32*)pPtr;
#ifdef __BIG_ENDIAN__
commentLength = os::Byteswap::byteswap(commentLength);
#endif
pPtr += sizeof(s32);
pPtr += commentLength;
}
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
}
if (pPtr < buffer+fileSize)
{
subVersion = *(s32*)pPtr; // vertex subVersion, 1 or 2
#ifdef __BIG_ENDIAN__
subVersion = os::Byteswap::byteswap(subVersion);
#endif
pPtr += sizeof(s32);
// read vertex weights, ignoring data 'extra' from 1.8.2
vertexWeights.reallocate(numVertices);
const char offset = (subVersion==1)?6:10;
for (i=0; i<numVertices; ++i)
{
vertexWeights.push_back(*(MS3DVertexWeights*)pPtr);
pPtr += offset;
}
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
}
if (pPtr < buffer+fileSize)
{
subVersion = *(s32*)pPtr; // joint subVersion, 1 or 2
#ifdef __BIG_ENDIAN__
subVersion = os::Byteswap::byteswap(subVersion);
#endif
pPtr += sizeof(s32);
// skip joint colors
pPtr += 3*sizeof(float)*jointCount;
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false;
}
}
if (pPtr < buffer+fileSize)
{
subVersion = *(s32*)pPtr; // model subVersion, 1 or 2
#ifdef __BIG_ENDIAN__
subVersion = os::Byteswap::byteswap(subVersion);
#endif
pPtr += sizeof(s32);
// now the model extra information would follow
// we also skip this for now
}
}
//find parent of every joint
for (u32 jointnum=0; jointnum<AnimatedMesh->getAllJoints().size(); ++jointnum)
{
for (u32 j2=0; j2<AnimatedMesh->getAllJoints().size(); ++j2)
{
if (jointnum != j2 && ParentNames[jointnum] == AnimatedMesh->getAllJoints()[j2]->Name )
if (jointnum != j2 && parentNames[jointnum] == AnimatedMesh->getAllJoints()[j2]->Name )
{
AnimatedMesh->getAllJoints()[j2]->Children.push_back(AnimatedMesh->getAllJoints()[jointnum]);
break;
}
}
}
/*if (Joints[jointnum].Parent == -1)
os::Printer::log("Found joint in model without parent.", ELL_WARNING);*/
// create vertices and indices, attach them to the joints.
video::S3DVertex v;
......@@ -470,7 +603,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
for (i=0; i<numTriangles; ++i)
{
u32 tmp = Groups[triangles[i].GroupIndex].MaterialIdx;
u32 tmp = groups[triangles[i].GroupIndex].MaterialIdx;
Vertices = &AnimatedMesh->getMeshBuffers()[tmp]->Vertices_Standard;
for (u16 j = 0; j<3; ++j)
......@@ -482,8 +615,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
v.Normal.Y = triangles[i].VertexNormals[j][1];
v.Normal.Z = triangles[i].VertexNormals[j][2];
if(triangles[i].GroupIndex < Groups.size() && Groups[triangles[i].GroupIndex].MaterialIdx < AnimatedMesh->getMeshBuffers().size())
v.Color = AnimatedMesh->getMeshBuffers()[Groups[triangles[i].GroupIndex].MaterialIdx]->Material.DiffuseColor;
if(triangles[i].GroupIndex < groups.size() && groups[triangles[i].GroupIndex].MaterialIdx < AnimatedMesh->getMeshBuffers().size())
v.Color = AnimatedMesh->getMeshBuffers()[groups[triangles[i].GroupIndex].MaterialIdx]->Material.DiffuseColor;
else
v.Color.set(255,255,255,255);
v.Pos.X = vertices[triangles[i].VertexIndices[j]].Vertex[0];
......@@ -503,20 +636,67 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (index == -1)
{
s32 boneid = vertices[triangles[i].VertexIndices[j]].BoneID;
if (boneid>=0 && boneid<(s32)AnimatedMesh->getAllJoints().size())
index = Vertices->size();
const u32 vertidx = triangles[i].VertexIndices[j];
const u32 matidx = groups[triangles[i].GroupIndex].MaterialIdx;
if (vertexWeights.size()==0)
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = Groups[triangles[i].GroupIndex].MaterialIdx;
w->strength = 1.0f;
w->vertex_id = Vertices->size();
//Joints[boneid]->VertexIds.push_back(Vertices.size());
const s32 boneid = vertices[vertidx].BoneID;
if ((u32)boneid < AnimatedMesh->getAllJoints().size())
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
w->strength = 1.0f;
w->vertex_id = index;
}
}
else // new weights from 1.8.x
{
f32 sum = 1.0f;
s32 boneid = vertices[vertidx].BoneID;
if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[0] != 0))
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
sum -= (w->strength = vertexWeights[vertidx].weights[0]/100.f);
w->vertex_id = index;
}
boneid = vertexWeights[vertidx].boneIds[0];
if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[1] != 0))
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
sum -= (w->strength = vertexWeights[vertidx].weights[1]/100.f);
w->vertex_id = index;
}
boneid = vertexWeights[vertidx].boneIds[1];
if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[2] != 0))
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
sum -= (w->strength = vertexWeights[vertidx].weights[2]/100.f);
w->vertex_id = index;
}
boneid = vertexWeights[vertidx].boneIds[2];
if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (sum > 0.f))
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
w->strength = sum;
w->vertex_id = index;
}
// fallback, if no bone chosen. Seems to be an error in the specs
boneid = vertices[vertidx].BoneID;
if ((sum == 1.f) && ((u32)boneid < AnimatedMesh->getAllJoints().size()))
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = matidx;
w->strength = 1.f;
w->vertex_id = index;
}
}
Vertices->push_back(v);
index = Vertices->size() - 1;
}
Indices.push_back(index);
}
......@@ -524,9 +704,9 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
//create groups
s32 iIndex = -1;
for (i=0; i<Groups.size(); ++i)
for (i=0; i<groups.size(); ++i)
{
SGroup& grp = Groups[i];
SGroup& grp = groups[i];
if (grp.MaterialIdx >= AnimatedMesh->getMeshBuffers().size())
grp.MaterialIdx = 0;
......@@ -538,31 +718,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
indices.push_back(Indices[++iIndex]);
}
// calculate bounding box
/*
// inverse translate and rotate all vertices for making animation easier
if (HasAnimation)
for (i=0; i<Joints.size(); ++i)
{
for (u32 j=0; j<Joints[i].VertexIds.size(); ++j)
{
Joints[i].AbsoluteTransformation.inverseTranslateVect(
Vertices[Joints[i].VertexIds[j]].Pos);
Joints[i].AbsoluteTransformation.inverseRotateVect(
Vertices[Joints[i].VertexIds[j]].Pos);
Joints[i].AbsoluteTransformation.inverseRotateVect(
Vertices[Joints[i].VertexIds[j]].Normal);
}
}
AnimatedVertices = Vertices;
*/
delete [] buffer;
// clear arrays
Groups.clear();
return true;
}
......
......@@ -22,7 +22,7 @@ public:
//! Constructor
CMS3DMeshFileLoader(video::IVideoDriver* driver);
//! returns true if the file maybe is able to be loaded by this class
//! returns true if the file might be loadable by this class
//! based on the file extension (e.g. ".bsp")
virtual bool isALoadableFileExtension(const c8* fileName) const;
......@@ -39,16 +39,6 @@ private:
bool load(io::IReadFile* file);
video::IVideoDriver* Driver;
CSkinnedMesh* AnimatedMesh;
struct SGroup
{
core::stringc Name;
core::array<u16> VertexIds;
u16 MaterialIdx;
};
core::array<SGroup> Groups;
};
} // end namespace scene
......
......@@ -10,7 +10,7 @@
#else
#include <string.h>
#include <unistd.h>
#ifdef MACOSX
#ifdef _IRR_USE_OSX_DEVICE_
#include "OSXClipboard.h"
#include <sys/types.h>
#include <sys/sysctl.h>
......@@ -59,9 +59,10 @@ void COSOperator::copyToClipboard(const c8* text) const
CloseClipboard();
// MacOSX version
#elif defined(MACOSX)
#elif defined(_IRR_USE_OSX_DEVICE_)
OSXCopyToClipboard(text);
#else
// todo: Linux version
#endif
......@@ -84,7 +85,7 @@ c8* COSOperator::getTextFromClipboard() const
CloseClipboard();
return buffer;
#elif defined(MACOSX)
#elif defined(_IRR_USE_OSX_DEVICE_)
return (OSXCopyFromClipboard());
#else
......@@ -121,7 +122,7 @@ bool COSOperator::getProcessorSpeedMHz(u32* MHz) const
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return true;
#elif defined(MACOSX)
#elif defined(_IRR_OSX_PLATFORM_)
struct clockinfo CpuClock;
size_t Size = sizeof(clockinfo);
......
......@@ -156,9 +156,9 @@ bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
#endif //IRR_USE_WINDOWS_DEVICE_
// -----------------------------------------------------------------------
// MACOSX CONSTRUCTOR
// MacOSX CONSTRUCTOR
// -----------------------------------------------------------------------
#ifdef MACOSX
#ifdef _IRR_USE_OSX_DEVICE_
//! Windows constructor and init code
COpenGLDriver::COpenGLDriver(const core::dimension2d<s32>& screenSize, bool fullscreen, bool stencilBuffer, CIrrDeviceMacOSX *device, io::IFileSystem* io, bool vsync, bool antiAlias)
: CNullDriver(io, screenSize), COpenGLExtensionHandler(),
......@@ -400,7 +400,7 @@ bool COpenGLDriver::endScene( s32 windowId, core::rect<s32>* sourceRect )
#elif defined(_IRR_USE_LINUX_DEVICE_)
glXSwapBuffers(XDisplay, XWindow);
return true;
#elif defined(MACOSX)
#elif defined(_IRR_USE_OSX_DEVICE_)
_device->flush();
return true;
#elif defined(_IRR_USE_SDL_DEVICE_)
......@@ -2661,7 +2661,7 @@ IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize,
// -----------------------------------
// MACOSX VERSION
// -----------------------------------
#ifdef MACOSX
#if defined(_IRR_USE_OSX_DEVICE_)
IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize,
CIrrDeviceMacOSX *device, bool fullscreen, bool stencilBuffer,
io::IFileSystem* io, bool vsync, bool antiAlias)
......@@ -2673,7 +2673,7 @@ IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize,
return 0;
#endif // _IRR_COMPILE_WITH_OPENGL_
}
#endif // MACOSX
#endif // _IRR_USE_OSX_DEVICE_
// -----------------------------------
// LINUX VERSION
......
......@@ -22,7 +22,7 @@
#pragma comment(lib, "OpenGL32.lib")
#pragma comment(lib, "GLu32.lib")
#endif
#elif defined(MACOSX)
#elif defined(_IRR_USE_OSX_DEVICE_)
#include "CIrrDeviceMacOSX.h"
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
......@@ -84,7 +84,7 @@ namespace video
bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias);
#endif
#ifdef MACOSX
#ifdef _IRR_USE_OSX_DEVICE_
COpenGLDriver(const core::dimension2d<s32>& screenSize, bool fullscreen,
bool stencilBuffer, CIrrDeviceMacOSX *device,io::IFileSystem* io, bool vsync, bool antiAlias);
#endif
......@@ -388,7 +388,7 @@ namespace video
#elif defined(_IRR_USE_LINUX_DEVICE_)
GLXDrawable XWindow;
Display* XDisplay;
#elif defined(MACOSX)
#elif defined(_IRR_USE_OSX_DEVICE_)
CIrrDeviceMacOSX *_device;
#endif
};
......
......@@ -21,7 +21,7 @@
#ifdef _MSC_VER
#pragma comment(lib, "OpenGL32.lib")
#endif
#elif defined(MACOSX)
#elif defined(_IRR_USE_OSX_DEVICE_)
#include "CIrrDeviceMacOSX.h"
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
......
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__
#define __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "COpenGLDriver.h"
#include "IMaterialRenderer.h"
//Varmint: 2007/12/18
#ifdef MACOSX
#define GL_COMBINE_EXT 0x8570
#define GL_COMBINE_RGB_EXT 0x8571
#define GL_COMBINE_ALPHA_EXT 0x8572
#define GL_RGB_SCALE_EXT 0x8573
#define GL_ADD_SIGNED_EXT 0x8574
#define GL_INTERPOLATE_EXT 0x8575
#define GL_CONSTANT_EXT 0x8576
#define GL_PRIMARY_COLOR_EXT 0x8577
#define GL_PREVIOUS_EXT 0x8578
#define GL_SOURCE0_RGB_EXT 0x8580
#define GL_SOURCE1_RGB_EXT 0x8581
#define GL_SOURCE2_RGB_EXT 0x8582
#define GL_SOURCE3_RGB_EXT 0x8583
#define GL_SOURCE4_RGB_EXT 0x8584
#define GL_SOURCE5_RGB_EXT 0x8585
#define GL_SOURCE6_RGB_EXT 0x8586
#define GL_SOURCE7_RGB_EXT 0x8587
#define GL_SOURCE0_ALPHA_EXT 0x8588
#define GL_SOURCE1_ALPHA_EXT 0x8589
#define GL_SOURCE2_ALPHA_EXT 0x858A
#define GL_SOURCE3_ALPHA_EXT 0x858B
#define GL_SOURCE4_ALPHA_EXT 0x858C
#define GL_SOURCE5_ALPHA_EXT 0x858D
#define GL_SOURCE6_ALPHA_EXT 0x858E
#define GL_SOURCE7_ALPHA_EXT 0x858F
#define GL_OPERAND0_RGB_EXT 0x8590
#define GL_OPERAND1_RGB_EXT 0x8591
#define GL_OPERAND2_RGB_EXT 0x8592
#define GL_OPERAND3_RGB_EXT 0x8593
#define GL_OPERAND4_RGB_EXT 0x8594
#define GL_OPERAND5_RGB_EXT 0x8595
#define GL_OPERAND6_RGB_EXT 0x8596
#define GL_OPERAND7_RGB_EXT 0x8597
#define GL_OPERAND0_ALPHA_EXT 0x8598
#define GL_OPERAND1_ALPHA_EXT 0x8599
#define GL_OPERAND2_ALPHA_EXT 0x859A
#define GL_OPERAND3_ALPHA_EXT 0x859B
#define GL_OPERAND4_ALPHA_EXT 0x859C
#define GL_OPERAND5_ALPHA_EXT 0x859D
#define GL_OPERAND6_ALPHA_EXT 0x859E
#define GL_OPERAND7_ALPHA_EXT 0x859F
#endif
namespace irr
{
namespace video
{
//! Base class for all internal OpenGL material renderers
class COpenGLMaterialRenderer : public IMaterialRenderer
{
public:
//! Constructor
COpenGLMaterialRenderer(video::COpenGLDriver* driver) : Driver(driver)
{
}
protected:
video::COpenGLDriver* Driver;
};
//! Solid material renderer
class COpenGLMaterialRenderer_SOLID : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
// thanks to Murphy, the following line removed some
// bugs with several OpenGL implementations.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
};
//! Generic Texture Blend
class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
// if (material.MaterialType != lastMaterial.MaterialType ||
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
// resetAllRenderstates)
{
E_BLEND_FACTOR srcFact,dstFact;
E_MODULATE_FUNC modulate;
unpack_texureBlendFunc ( srcFact, dstFact, modulate, material.MaterialTypeParam );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_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);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
glBlendFunc( getGLBlend(srcFact), getGLBlend(dstFact) );
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
if ( getTexelAlpha ( srcFact ) + getTexelAlpha ( dstFact ) )
{
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
}
}
}
virtual void OnUnsetMaterial()
{
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
}
private:
u32 getGLBlend ( E_BLEND_FACTOR factor ) const
{
u32 r = 0;
switch ( factor )
{
case EBF_ZERO: r = GL_ZERO; break;
case EBF_ONE: r = GL_ONE; break;
case EBF_DST_COLOR: r = GL_DST_COLOR; break;
case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break;
case EBF_SRC_COLOR: r = GL_SRC_COLOR; break;
case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break;
case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break;
case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break;
case EBF_DST_ALPHA: r = GL_DST_ALPHA; break;
case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break;
case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break;
}
return r;
}
u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const
{
u32 r;
switch ( factor )
{
case EBF_SRC_ALPHA: r = 1; break;
case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break;
case EBF_DST_ALPHA: r = 1; break;
case EBF_ONE_MINUS_DST_ALPHA: r = 1; break;
case EBF_SRC_ALPHA_SATURATE: r = 1; break;
default: r = 0; break;
}
return r;
}
};
//! Solid 2 layer material renderer
class COpenGLMaterialRenderer_SOLID_2_LAYER : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
};
//! Transparent add color material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if ((material.MaterialType != lastMaterial.MaterialType) || resetAllRenderstates)
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_BLEND);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent vertex alpha material renderer
class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
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_SOURCE1_RGB_EXT, GL_TEXTURE);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
}
glDepthMask(GL_FALSE);
}
virtual void OnUnsetMaterial()
{
// default values
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
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);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent alpha channel material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_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);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
f32 refValue = material.MaterialTypeParam;
if ( refValue == 0.0f )
refValue = 0.5f;
glAlphaFunc(GL_GREATER, refValue);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent alpha channel material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_ALPHA_TEST);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return false; // this material is not really transparent because it does no blending.
}
};
//! material renderer for all kinds of lightmaps
class COpenGLMaterialRenderer_LIGHTMAP : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
// diffuse map
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
switch (material.MaterialType)
{
case EMT_LIGHTMAP_LIGHTING:
case EMT_LIGHTMAP_LIGHTING_M2:
case EMT_LIGHTMAP_LIGHTING_M4:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
break;
case EMT_LIGHTMAP_ADD:
case EMT_LIGHTMAP:
case EMT_LIGHTMAP_M2:
case EMT_LIGHTMAP_M4:
default:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
break;
}
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR );
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
// lightmap
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
if (material.MaterialType == EMT_LIGHTMAP_ADD)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_ARB);
else
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
switch (material.MaterialType)
{
case EMT_LIGHTMAP_M4:
case EMT_LIGHTMAP_LIGHTING_M4:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 4.0f);
break;
case EMT_LIGHTMAP_M2:
case EMT_LIGHTMAP_LIGHTING_M2:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);
break;
default:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
}
}
}
}
virtual void OnUnsetMaterial()
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
};
//! detail map material renderer
class COpenGLMaterialRenderer_DETAIL_MAP : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
// diffuse map
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
// detail map
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR);
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
}
}
}
};
//! sphere map material renderer
class COpenGLMaterialRenderer_SPHERE_MAP : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
}
};
//! reflection 2 layer material renderer
class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(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_PRIMARY_COLOR_EXT );
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
}
virtual void OnUnsetMaterial()
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
};
//! reflection 2 layer material renderer
class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(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_PRIMARY_COLOR_EXT );
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND);
}
}
virtual void OnUnsetMaterial()
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
glDisable(GL_BLEND);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
} // end namespace video
} // end namespace irr
#endif
#endif
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__
#define __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "COpenGLDriver.h"
#include "IMaterialRenderer.h"
#include "IMaterialRenderer.h"
#if defined(_IRR_USE_OSX_DEVICE_)
#define GL_COMBINE_EXT 0x8570
#define GL_COMBINE_RGB_EXT 0x8571
#define GL_COMBINE_ALPHA_EXT 0x8572
#define GL_RGB_SCALE_EXT 0x8573
#define GL_ADD_SIGNED_EXT 0x8574
#define GL_INTERPOLATE_EXT 0x8575
#define GL_CONSTANT_EXT 0x8576
#define GL_PRIMARY_COLOR_EXT 0x8577
#define GL_PREVIOUS_EXT 0x8578
#define GL_SOURCE0_RGB_EXT 0x8580
#define GL_SOURCE1_RGB_EXT 0x8581
#define GL_SOURCE2_RGB_EXT 0x8582
#define GL_SOURCE3_RGB_EXT 0x8583
#define GL_SOURCE4_RGB_EXT 0x8584
#define GL_SOURCE5_RGB_EXT 0x8585
#define GL_SOURCE6_RGB_EXT 0x8586
#define GL_SOURCE7_RGB_EXT 0x8587
#define GL_SOURCE0_ALPHA_EXT 0x8588
#define GL_SOURCE1_ALPHA_EXT 0x8589
#define GL_SOURCE2_ALPHA_EXT 0x858A
#define GL_SOURCE3_ALPHA_EXT 0x858B
#define GL_SOURCE4_ALPHA_EXT 0x858C
#define GL_SOURCE5_ALPHA_EXT 0x858D
#define GL_SOURCE6_ALPHA_EXT 0x858E
#define GL_SOURCE7_ALPHA_EXT 0x858F
#define GL_OPERAND0_RGB_EXT 0x8590
#define GL_OPERAND1_RGB_EXT 0x8591
#define GL_OPERAND2_RGB_EXT 0x8592
#define GL_OPERAND3_RGB_EXT 0x8593
#define GL_OPERAND4_RGB_EXT 0x8594
#define GL_OPERAND5_RGB_EXT 0x8595
#define GL_OPERAND6_RGB_EXT 0x8596
#define GL_OPERAND7_RGB_EXT 0x8597
#define GL_OPERAND0_ALPHA_EXT 0x8598
#define GL_OPERAND1_ALPHA_EXT 0x8599
#define GL_OPERAND2_ALPHA_EXT 0x859A
#define GL_OPERAND3_ALPHA_EXT 0x859B
#define GL_OPERAND4_ALPHA_EXT 0x859C
#define GL_OPERAND5_ALPHA_EXT 0x859D
#define GL_OPERAND6_ALPHA_EXT 0x859E
#define GL_OPERAND7_ALPHA_EXT 0x859F
#endif
namespace irr
{
namespace video
{
//! Base class for all internal OpenGL material renderers
class COpenGLMaterialRenderer : public IMaterialRenderer
{
public:
//! Constructor
COpenGLMaterialRenderer(video::COpenGLDriver* driver) : Driver(driver)
{
}
protected:
video::COpenGLDriver* Driver;
};
//! Solid material renderer
class COpenGLMaterialRenderer_SOLID : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
// thanks to Murphy, the following line removed some
// bugs with several OpenGL implementations.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
};
//! Generic Texture Blend
class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
// if (material.MaterialType != lastMaterial.MaterialType ||
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
// resetAllRenderstates)
{
E_BLEND_FACTOR srcFact,dstFact;
E_MODULATE_FUNC modulate;
unpack_texureBlendFunc ( srcFact, dstFact, modulate, material.MaterialTypeParam );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_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);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
glBlendFunc( getGLBlend(srcFact), getGLBlend(dstFact) );
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
if ( getTexelAlpha ( srcFact ) + getTexelAlpha ( dstFact ) )
{
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
}
}
}
virtual void OnUnsetMaterial()
{
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
}
private:
u32 getGLBlend ( E_BLEND_FACTOR factor ) const
{
u32 r = 0;
switch ( factor )
{
case EBF_ZERO: r = GL_ZERO; break;
case EBF_ONE: r = GL_ONE; break;
case EBF_DST_COLOR: r = GL_DST_COLOR; break;
case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break;
case EBF_SRC_COLOR: r = GL_SRC_COLOR; break;
case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break;
case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break;
case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break;
case EBF_DST_ALPHA: r = GL_DST_ALPHA; break;
case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break;
case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break;
}
return r;
}
u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const
{
u32 r;
switch ( factor )
{
case EBF_SRC_ALPHA: r = 1; break;
case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break;
case EBF_DST_ALPHA: r = 1; break;
case EBF_ONE_MINUS_DST_ALPHA: r = 1; break;
case EBF_SRC_ALPHA_SATURATE: r = 1; break;
default: r = 0; break;
}
return r;
}
};
//! Solid 2 layer material renderer
class COpenGLMaterialRenderer_SOLID_2_LAYER : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
};
//! Transparent add color material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if ((material.MaterialType != lastMaterial.MaterialType) || resetAllRenderstates)
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_BLEND);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent vertex alpha material renderer
class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
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_SOURCE1_RGB_EXT, GL_TEXTURE);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
}
glDepthMask(GL_FALSE);
}
virtual void OnUnsetMaterial()
{
// default values
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
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);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent alpha channel material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_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);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
f32 refValue = material.MaterialTypeParam;
if ( refValue == 0.0f )
refValue = 0.5f;
glAlphaFunc(GL_GREATER, refValue);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent alpha channel material renderer
class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_ALPHA_TEST);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return false; // this material is not really transparent because it does no blending.
}
};
//! material renderer for all kinds of lightmaps
class COpenGLMaterialRenderer_LIGHTMAP : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
// diffuse map
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
switch (material.MaterialType)
{
case EMT_LIGHTMAP_LIGHTING:
case EMT_LIGHTMAP_LIGHTING_M2:
case EMT_LIGHTMAP_LIGHTING_M4:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
break;
case EMT_LIGHTMAP_ADD:
case EMT_LIGHTMAP:
case EMT_LIGHTMAP_M2:
case EMT_LIGHTMAP_M4:
default:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
break;
}
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR );
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
// lightmap
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
if (material.MaterialType == EMT_LIGHTMAP_ADD)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_ARB);
else
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
switch (material.MaterialType)
{
case EMT_LIGHTMAP_M4:
case EMT_LIGHTMAP_LIGHTING_M4:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 4.0f);
break;
case EMT_LIGHTMAP_M2:
case EMT_LIGHTMAP_LIGHTING_M2:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);
break;
default:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
}
}
}
}
virtual void OnUnsetMaterial()
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
}
}
};
//! detail map material renderer
class COpenGLMaterialRenderer_DETAIL_MAP : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
// diffuse map
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
// detail map
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR);
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
}
}
}
};
//! sphere map material renderer
class COpenGLMaterialRenderer_SPHERE_MAP : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(1);
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
}
};
//! reflection 2 layer material renderer
class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(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_PRIMARY_COLOR_EXT );
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
}
virtual void OnUnsetMaterial()
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
};
//! reflection 2 layer material renderer
class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public COpenGLMaterialRenderer
{
public:
COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d)
: COpenGLMaterialRenderer(d) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
Driver->disableTextures(2);
Driver->setTexture(1, material.getTexture(1));
Driver->setTexture(0, material.getTexture(0));
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(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_PRIMARY_COLOR_EXT );
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND);
}
}
virtual void OnUnsetMaterial()
{
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
if (Driver->queryFeature(EVDF_MULTITEXTURE))
{
Driver->extGlActiveTexture(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
glDisable(GL_BLEND);
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
} // end namespace video
} // end namespace irr
#endif
#endif
......@@ -17,7 +17,7 @@
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#endif
#if defined(MACOSX)
#if defined(_IRR_USE_OSX_DEVICE_)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
......
......@@ -16,7 +16,7 @@
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#endif
#if defined(MACOSX)
#if defined(_IRR_USE_OSX_DEVICE_)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
......
......@@ -25,7 +25,7 @@
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#endif
#if defined(MACOSX)
#if defined(_IRR_USE_OSX_DEVICE_)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
......
......@@ -174,13 +174,11 @@ void CPakReader::deletePathFromFilename(core::stringc& filename)
// delete path from filename
const c8* p = filename.c_str() + filename.size();
// suche ein slash oder den anfang.
// search for path separator or beginning
while (*p!='/' && *p!='\\' && p!=filename.c_str())
--p;
core::stringc newName;
if (p != filename.c_str())
{
++p;
......
......@@ -515,16 +515,16 @@ const sVec4 CBurningVideoDriver::NDCPlane[6] =
for ( u32 i = 0; i!= 6; ++i )
{
dotPlane = v->Pos.dotProduct ( NDCPlane[i] );
setbit ( flag, dotPlane <= 0.f, 1 << i );
core::setbit_cond( flag, dotPlane <= 0.f, 1 << i );
}
// this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w>
setbits ( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );
setbits ( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );
setbits ( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );
setbits ( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );
setbits ( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );
setbits ( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );
core::setbit_cond( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );
core::setbit_cond( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );
core::setbit_cond( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );
core::setbit_cond( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );
core::setbit_cond( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );
core::setbit_cond( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );
*/
#ifdef _MSC_VER
......@@ -572,7 +572,7 @@ REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) c
u32 flag = 0;
for ( u32 i = 0; i!= 6; ++i )
{
core::setbit ( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i );
core::setbit_cond( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i );
}
return flag;
}
......
......@@ -233,7 +233,7 @@ void CXMLWriter::writeLineBreak()
if (!File)
return;
#if defined(MACOSX)
#if defined(_IRR_OSX_PLATFORM_)
File->write(L"\r", sizeof(wchar_t));
#elif defined(_IRR_WINDOWS_API_)
File->write(L"\r\n", 2*sizeof(wchar_t));
......
......@@ -298,13 +298,11 @@ void CZipReader::deletePathFromFilename(core::stringc& filename)
// delete path from filename
const c8* p = filename.c_str() + filename.size();
// suche ein slash oder den anfang.
// search for path separator or beginning
while (*p!='/' && *p!='\\' && p!=filename.c_str())
--p;
core::stringc newName;
if (p != filename.c_str())
{
++p;
......
// Copyright (C) 2005 Etienne Petitjean
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_IRR_DEVICE_MACOSX_H_INCLUDED__
#define __C_IRR_DEVICE_MACOSX_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef MACOSX
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "IImagePresenter.h"
#include "IGUIEnvironment.h"
#include "ICursorControl.h"
#include <OpenGL/OpenGL.h>
#include <map>
namespace irr
{
class CIrrDeviceMacOSX : public CIrrDeviceStub, video::IImagePresenter
{
public:
//! constructor
CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType,
const core::dimension2d<s32>& windowSize,
u32 bits, bool fullscreen,
bool sbuffer, bool vsync,
bool antiAlias, IEventReceiver* receiver,
const char* version);
//! destructor
virtual ~CIrrDeviceMacOSX();
//! runs the device. Returns false if device wants to be deleted
virtual bool run();
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
virtual void yield();
//! Pause execution and let other processes to run for a specified amount of time.
virtual void sleep(u32 timeMs, bool pauseTimer);
//! sets the caption of the window
virtual void setWindowCaption(const wchar_t* text);
//! returns if window is active. if not, nothing need to be drawn
virtual bool isWindowActive() const;
//! presents a surface in the client area
virtual void present(video::IImage* surface, s32 windowId = 0, core::rect<s32>* src=0 );
//! notifies the device that it should close itself
virtual void closeDevice();
//! Sets if the window should be resizeable in windowed mode.
virtual void setResizeAble(bool resize);
void flush();
void setMouseLocation(int x,int y);
void setResize(int width,int height);
void setCursorVisible(bool visible);
private:
//! create the driver
void createDriver(video::E_DRIVER_TYPE driverType,
const core::dimension2d<s32>& windowSize, u32 bits, bool fullscreen,
bool stencilbuffer, bool vsync, bool antiAlias);
//! Implementation of the macos x cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(const core::dimension2d<s32>& wsize, CIrrDeviceMacOSX *device) : WindowSize(wsize), IsVisible(true), InvWindowSize(0.0f, 0.0f), _device(device), UseReferenceRect(false)
{
CursorPos.X = CursorPos.Y = 0;
if (WindowSize.Width!=0) InvWindowSize.Width = 1.0f / WindowSize.Width;
if (WindowSize.Height!=0) InvWindowSize.Height = 1.0f / WindowSize.Height;
}
//! Changes the visible state of the mouse cursor.
virtual void setVisible(bool visible)
{
IsVisible = visible;
_device->setCursorVisible(visible);
}
//! Returns if the cursor is currently visible.
virtual bool isVisible() const
{
return IsVisible;
}
//! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<f32> &pos)
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
virtual void setPosition(f32 x, f32 y)
{
setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height));
}
//! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<s32> &pos)
{
if (CursorPos.X != pos.X || CursorPos.Y != pos.Y)
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
virtual void setPosition(s32 x, s32 y)
{
if (UseReferenceRect)
{
_device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y);
}
else
{
_device->setMouseLocation(x,y);
}
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<s32> getPosition()
{
return CursorPos;
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<f32> getRelativePosition()
{
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
CursorPos.Y * InvWindowSize.Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
//! Sets an absolute reference rect for calculating the cursor position.
virtual void setReferenceRect(core::rect<s32>* rect=0)
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
//! Updates the internal cursor position
void updateInternalCursorPosition(int x,int y)
{
CursorPos.X = x;
CursorPos.Y = y;
}
private:
core::position2d<s32> CursorPos;
core::dimension2d<s32> WindowSize;
core::dimension2d<float> InvWindowSize;
CIrrDeviceMacOSX *_device;
bool IsVisible;
bool UseReferenceRect;
core::rect<s32> ReferenceRect;
};
bool createWindow(const irr::core::dimension2d<irr::s32>& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer);
void initKeycodes();
void storeMouseLocation();
void postMouseEvent(void *event,irr::SEvent &ievent);
void postKeyEvent(void *event,irr::SEvent &ievent,bool pressed);
video::E_DRIVER_TYPE DriverType;
bool stencilbuffer;
void *_window;
CGLContextObj _cglcontext;
void *_oglcontext;
int _width;
int _height;
std::map<int,int> _keycodes;
int _screenWidth;
int _screenHeight;
bool _active;
};
} // end namespace irr
#endif // MACOSX
#endif // __C_IRR_DEVICE_MACOSX_H_INCLUDED__
// Copyright (C) 2005 Etienne Petitjean
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_IRR_DEVICE_MACOSX_H_INCLUDED__
#define __C_IRR_DEVICE_MACOSX_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_USE_OSX_DEVICE_
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "IImagePresenter.h"
#include "IGUIEnvironment.h"
#include "ICursorControl.h"
#include <OpenGL/OpenGL.h>
#include <map>
namespace irr
{
class CIrrDeviceMacOSX : public CIrrDeviceStub, video::IImagePresenter
{
public:
//! constructor
CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType,
const core::dimension2d<s32>& windowSize,
u32 bits, bool fullscreen,
bool sbuffer, bool vsync,
bool antiAlias, IEventReceiver* receiver,
const char* version);
//! destructor
virtual ~CIrrDeviceMacOSX();
//! runs the device. Returns false if device wants to be deleted
virtual bool run();
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
virtual void yield();
//! Pause execution and let other processes to run for a specified amount of time.
virtual void sleep(u32 timeMs, bool pauseTimer);
//! sets the caption of the window
virtual void setWindowCaption(const wchar_t* text);
//! returns if window is active. if not, nothing need to be drawn
virtual bool isWindowActive() const;
//! presents a surface in the client area
virtual void present(video::IImage* surface, s32 windowId = 0, core::rect<s32>* src=0 );
//! notifies the device that it should close itself
virtual void closeDevice();
//! Sets if the window should be resizeable in windowed mode.
virtual void setResizeAble(bool resize);
void flush();
void setMouseLocation(int x,int y);
void setResize(int width,int height);
void setCursorVisible(bool visible);
private:
//! create the driver
void createDriver(video::E_DRIVER_TYPE driverType,
const core::dimension2d<s32>& windowSize, u32 bits, bool fullscreen,
bool stencilbuffer, bool vsync, bool antiAlias);
//! Implementation of the macos x cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(const core::dimension2d<s32>& wsize, CIrrDeviceMacOSX *device) : WindowSize(wsize), IsVisible(true), InvWindowSize(0.0f, 0.0f), _device(device), UseReferenceRect(false)
{
CursorPos.X = CursorPos.Y = 0;
if (WindowSize.Width!=0) InvWindowSize.Width = 1.0f / WindowSize.Width;
if (WindowSize.Height!=0) InvWindowSize.Height = 1.0f / WindowSize.Height;
}
//! Changes the visible state of the mouse cursor.
virtual void setVisible(bool visible)
{
IsVisible = visible;
_device->setCursorVisible(visible);
}
//! Returns if the cursor is currently visible.
virtual bool isVisible() const
{
return IsVisible;
}
//! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<f32> &pos)
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
virtual void setPosition(f32 x, f32 y)
{
setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height));
}
//! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<s32> &pos)
{
if (CursorPos.X != pos.X || CursorPos.Y != pos.Y)
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
virtual void setPosition(s32 x, s32 y)
{
if (UseReferenceRect)
{
_device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y);
}
else
{
_device->setMouseLocation(x,y);
}
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<s32> getPosition()
{
return CursorPos;
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<f32> getRelativePosition()
{
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
CursorPos.Y * InvWindowSize.Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
//! Sets an absolute reference rect for calculating the cursor position.
virtual void setReferenceRect(core::rect<s32>* rect=0)
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
//! Updates the internal cursor position
void updateInternalCursorPosition(int x,int y)
{
CursorPos.X = x;
CursorPos.Y = y;
}
private:
core::position2d<s32> CursorPos;
core::dimension2d<s32> WindowSize;
core::dimension2d<float> InvWindowSize;
CIrrDeviceMacOSX *_device;
bool IsVisible;
bool UseReferenceRect;
core::rect<s32> ReferenceRect;
};
bool createWindow(const irr::core::dimension2d<irr::s32>& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer);
void initKeycodes();
void storeMouseLocation();
void postMouseEvent(void *event,irr::SEvent &ievent);
void postKeyEvent(void *event,irr::SEvent &ievent,bool pressed);
video::E_DRIVER_TYPE DriverType;
bool stencilbuffer;
void *_window;
CGLContextObj _cglcontext;
void *_oglcontext;
int _width;
int _height;
std::map<int,int> _keycodes;
int _screenWidth;
int _screenHeight;
bool _active;
};
} // end namespace irr
#endif // _IRR_USE_OSX_DEVICE_
#endif // __C_IRR_DEVICE_MACOSX_H_INCLUDED__
// Copyright (C) 2005 Etienne Petitjean
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifdef MACOSX
#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>
#include "CIrrDeviceMacOSX.h"
#include "IEventReceiver.h"
#include "irrList.h"
#include "os.h"
#include "CTimer.h"
#include "irrString.h"
#include "Keycodes.h"
#include <stdio.h>
#include <sys/utsname.h>
#include "COSOperator.h"
#include "irrlicht.h"
#import <wchar.h>
#import <time.h>
#import "AppDelegate.h"
namespace irr
{
namespace video
{
IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize, CIrrDeviceMacOSX *device, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias);
}
} // end namespace irr
static bool firstLaunch = true;
namespace irr
{
//! constructor
CIrrDeviceMacOSX::CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType,
const core::dimension2d<s32>& windowSize,
u32 bits, bool fullscreen,
bool sbuffer, bool vsync,
bool antiAlias, IEventReceiver* receiver,
const char* version)
: CIrrDeviceStub(version, receiver), DriverType(driverType), stencilbuffer(sbuffer), _window(NULL), _active(true), _oglcontext(NULL), _cglcontext(NULL)
{
struct utsname name;
NSString *path;
#ifdef _DEBUG
setDebugName("CIrrDeviceMacOSX");
#endif
if (firstLaunch)
{
firstLaunch = false;
[[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
[NSApp setDelegate:[[[AppDelegate alloc] initWithDevice:this] autorelease]];
[NSBundle loadNibNamed:@"MainMenu" owner:[NSApp delegate]];
[NSApp finishLaunching];
path = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
chdir([path cString]);
}
uname(&name);
Operator = new COSOperator(name.version);
os::Printer::log(name.version,ELL_INFORMATION);
initKeycodes();
if (driverType != video::EDT_NULL) createWindow(windowSize,bits,fullscreen,vsync,stencilbuffer);
CursorControl = new CCursorControl(windowSize, this);
createDriver(driverType,windowSize,bits,fullscreen,stencilbuffer,vsync,antiAlias);
createGUIAndScene();
}
CIrrDeviceMacOSX::~CIrrDeviceMacOSX()
{
closeDevice();
}
void CIrrDeviceMacOSX::closeDevice()
{
if (_window != NULL)
{
[_window setIsVisible:FALSE];
if (_oglcontext != NULL)
{
[_oglcontext clearDrawable];
[_oglcontext release];
_oglcontext = NULL;
}
[_window setReleasedWhenClosed:TRUE];
[_window release];
_window = NULL;
}
else
{
if (_cglcontext != NULL)
{
CGLSetCurrentContext(NULL);
CGLClearDrawable(_cglcontext);
CGLDestroyContext(_cglcontext);
}
}
_active = FALSE;
_cglcontext = NULL;
}
bool CIrrDeviceMacOSX::createWindow(const irr::core::dimension2d<irr::s32>& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer)
{
int index;
CGDisplayErr error;
bool result;
NSOpenGLPixelFormat *format;
CGDirectDisplayID display;
CGLPixelFormatObj pixelFormat;
CGRect displayRect;
CGLPixelFormatAttribute fullattribs[32];
NSOpenGLPixelFormatAttribute windowattribs[32];
CFDictionaryRef displaymode,olddisplaymode;
long numPixelFormats,newSwapInterval;
result = false;
display = CGMainDisplayID();
_screenWidth = (int) CGDisplayPixelsWide(display);
_screenHeight = (int) CGDisplayPixelsHigh(display);
if (!fullscreen)
{
_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,windowSize.Width,windowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:NSBackingStoreBuffered defer:FALSE];
if (_window != NULL)
{
index = 0;
windowattribs[index++] = NSOpenGLPFANoRecovery;
windowattribs[index++] = NSOpenGLPFADoubleBuffer;
windowattribs[index++] = NSOpenGLPFAAccelerated;
windowattribs[index++] = NSOpenGLPFADepthSize;
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)16;
windowattribs[index++] = NSOpenGLPFAColorSize;
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)bits;
if (stencilBuffer)
{
windowattribs[index++] = NSOpenGLPFAStencilSize;
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)1;
}
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)NULL;
format = [[NSOpenGLPixelFormat alloc] initWithAttributes:windowattribs];
if (format != NULL)
{
_oglcontext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:NULL];
[format release];
}
if (_oglcontext != NULL)
{
[_window center];
[_window setDelegate:[NSApp delegate]];
[_oglcontext setView:[_window contentView]];
[_window setAcceptsMouseMovedEvents:TRUE];
[_window setIsVisible:TRUE];
[_window makeKeyAndOrderFront:nil];
_cglcontext = (CGLContextObj) [_oglcontext CGLContextObj];
_width = windowSize.Width;
_height = windowSize.Height;
result = true;
}
}
}
else
{
displaymode = CGDisplayBestModeForParameters(display,bits,windowSize.Width,windowSize.Height,NULL);
if (displaymode != NULL)
{
olddisplaymode = CGDisplayCurrentMode(display);
error = CGCaptureAllDisplays();
if (error == CGDisplayNoErr)
{
error = CGDisplaySwitchToMode(display,displaymode);
if (error == CGDisplayNoErr)
{
pixelFormat = NULL;
numPixelFormats = 0;
index = 0;
fullattribs[index++] = kCGLPFAFullScreen;
fullattribs[index++] = kCGLPFADisplayMask;
fullattribs[index++] = (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(display);
fullattribs[index++] = kCGLPFADoubleBuffer;
fullattribs[index++] = kCGLPFAAccelerated;
fullattribs[index++] = kCGLPFADepthSize;
fullattribs[index++] = (CGLPixelFormatAttribute)16;
fullattribs[index++] = kCGLPFAColorSize;
fullattribs[index++] = (CGLPixelFormatAttribute)bits;
if (stencilBuffer)
{
fullattribs[index++] = kCGLPFAStencilSize;
fullattribs[index++] = (CGLPixelFormatAttribute)1;
}
fullattribs[index++] = (CGLPixelFormatAttribute)NULL;
CGLChoosePixelFormat(fullattribs,&pixelFormat,&numPixelFormats);
if (pixelFormat != NULL)
{
CGLCreateContext(pixelFormat,NULL,&_cglcontext);
CGLDestroyPixelFormat(pixelFormat);
}
if (_cglcontext != NULL)
{
CGLSetFullScreen(_cglcontext);
displayRect = CGDisplayBounds(display);
_width = (int)displayRect.size.width;
_height = (int)displayRect.size.height;
result = true;
}
}
}
}
}
if (result)
{
CGLSetCurrentContext(_cglcontext);
newSwapInterval = (vsync) ? 1 : 0;
CGLSetParameter(_cglcontext,kCGLCPSwapInterval,&newSwapInterval);
glViewport(0,0,_width,_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
return (result);
}
void CIrrDeviceMacOSX::setResize(int width,int height)
{
_width = width;
_height = height;
[_oglcontext update];
getVideoDriver()->OnResize(core::dimension2d<s32>(width, height));
}
void CIrrDeviceMacOSX::createDriver(video::E_DRIVER_TYPE driverType,const core::dimension2d<s32>& windowSize,u32 bits,bool fullscreen,bool stencilbuffer, bool vsync, bool antiAlias)
{
switch (driverType)
{
case video::EDT_SOFTWARE:
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
VideoDriver = video::createSoftwareDriver(windowSize, fullscreen, FileSystem, this);
#else
os::Printer::log("No Software driver support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_BURNINGSVIDEO:
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
VideoDriver = video::createSoftwareDriver2(windowSize, fullscreen, FileSystem, this);
#else
os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_OPENGL:
#ifdef _IRR_COMPILE_WITH_OPENGL_
VideoDriver = video::createOpenGLDriver(windowSize, this, fullscreen, stencilbuffer, FileSystem, vsync, antiAlias);
#else
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_DIRECT3D8:
case video::EDT_DIRECT3D9:
os::Printer::log("This driver is not available in OSX. Try OpenGL or Software renderer.", ELL_ERROR);
break;
case video::EDT_NULL:
VideoDriver = video::createNullDriver(FileSystem, windowSize);
break;
default:
os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
break;
}
}
void CIrrDeviceMacOSX::flush()
{
if (_cglcontext != NULL)
{
glFinish();
CGLFlushDrawable(_cglcontext);
}
}
bool CIrrDeviceMacOSX::run()
{
NSEvent *event;
irr::SEvent ievent;
os::Timer::tick();
storeMouseLocation();
event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
if (event != nil)
{
bzero(&ievent,sizeof(ievent));
switch([event type])
{
case NSKeyDown:
postKeyEvent(event,ievent,true);
break;
case NSKeyUp:
postKeyEvent(event,ievent,false);
break;
case NSLeftMouseDown:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN;
postMouseEvent(event,ievent);
break;
case NSLeftMouseUp:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP;
postMouseEvent(event,ievent);
break;
case NSMouseMoved:
case NSLeftMouseDragged:
case NSRightMouseDragged:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
postMouseEvent(event,ievent);
break;
case NSRightMouseDown:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN;
postMouseEvent(event,ievent);
break;
case NSRightMouseUp:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP;
postMouseEvent(event,ievent);
break;
case NSScrollWheel:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL;
ievent.MouseInput.Wheel = [event deltaY];
if (ievent.MouseInput.Wheel < 1.0f) ievent.MouseInput.Wheel *= 10.0f;
else ievent.MouseInput.Wheel *= 5.0f;
postMouseEvent(event,ievent);
break;
default:
[NSApp sendEvent:event];
break;
}
}
return (![[NSApp delegate] isQuit] && _active);
}
//! Pause the current process for the minimum time allowed only to allow other processes to execute
void CIrrDeviceMacOSX::yield()
{
// TODO: Does this work or maybe is there a better way?
struct timespec ts = {0,0};
nanosleep(&ts, NULL);
}
//! Pause execution and let other processes to run for a specified amount of time.
void CIrrDeviceMacOSX::sleep(u32 timeMs, bool pauseTimer=false)
{
// TODO: Does this work or maybe is there a better way?
bool wasStopped = Timer ? Timer->isStopped() : true;
struct timespec ts;
ts.tv_sec = (time_t) (timeMs / 1000);
ts.tv_nsec = (long) (timeMs % 1000) * 1000000;
if (pauseTimer && !wasStopped)
Timer->stop();
nanosleep(&ts, NULL);
if (pauseTimer && !wasStopped)
Timer->start();
}
void CIrrDeviceMacOSX::present(video::IImage* image, s32 windowId, core::rect<s32>* src )
{
}
void CIrrDeviceMacOSX::setWindowCaption(const wchar_t* text)
{
size_t size;
char title[1024];
if (_window != NULL)
{
size = wcstombs(title,text,1024);
if (size == 1024) title[1023] = 0;
[_window setTitle:[NSString stringWithCString:title length:size]];
}
}
bool CIrrDeviceMacOSX::isWindowActive() const
{
return (_active);
}
void CIrrDeviceMacOSX::postKeyEvent(void *event,irr::SEvent &ievent,bool pressed)
{
NSString *str;
std::map<int,int>::const_iterator iter;
unsigned int result,c,mkey,mchar;
const unsigned char *cStr;
BOOL skipCommand;
str = [event characters];
if (str != nil && [str length] > 0)
{
mkey = mchar = 0;
skipCommand = false;
c = [str characterAtIndex:0];
iter = _keycodes.find(c);
if (iter != _keycodes.end()) mkey = (*iter).second;
else
{
cStr = (unsigned char *)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
if (cStr != NULL && strlen((char*)cStr) > 0)
{
mchar = cStr[0];
mkey = toupper(mchar);
if ([event modifierFlags] & NSCommandKeyMask)
{
if (mkey == 'C' || mkey == 'V' || mkey == 'X')
{
mchar = 0;
skipCommand = true;
}
}
}
}
ievent.EventType = irr::EET_KEY_INPUT_EVENT;
ievent.KeyInput.Key = (irr::EKEY_CODE)mkey;
ievent.KeyInput.PressedDown = pressed;
ievent.KeyInput.Shift = ([event modifierFlags] & NSShiftKeyMask) != 0;
ievent.KeyInput.Control = ([event modifierFlags] & NSControlKeyMask) != 0;
ievent.KeyInput.Char = (irr::EKEY_CODE)mchar;
if (skipCommand)
ievent.KeyInput.Control = true;
else if ([event modifierFlags] & NSCommandKeyMask)
[NSApp sendEvent:(NSEvent *)event];
postEventFromUser(ievent);
}
}
void CIrrDeviceMacOSX::postMouseEvent(void *event,irr::SEvent &ievent)
{
BOOL post = true;
if (_window != NULL)
{
ievent.MouseInput.X = (int)[event locationInWindow].x;
ievent.MouseInput.Y = _height - (int)[event locationInWindow].y;
if (ievent.MouseInput.Y < 0) post = false;
}
else
{
ievent.MouseInput.X = (int)[NSEvent mouseLocation].x;
ievent.MouseInput.Y = _height - (int)[NSEvent mouseLocation].y;
}
if (post) postEventFromUser(ievent);
[NSApp sendEvent:(NSEvent *)event];
}
void CIrrDeviceMacOSX::storeMouseLocation()
{
NSPoint p;
int x,y;
p = [NSEvent mouseLocation];
if (_window != NULL)
{
p = [_window convertScreenToBase:p];
x = (int)p.x;
y = _height - (int)p.y;
}
else
{
x = (int)p.x;
y = _screenHeight - (int)p.y;
}
((CCursorControl *)CursorControl)->updateInternalCursorPosition(x,y);
}
void CIrrDeviceMacOSX::setMouseLocation(int x,int y)
{
NSPoint p;
CGPoint c;
if (_window != NULL)
{
p.x = (float) x;
p.y = (float) (_height - y);
p = [_window convertBaseToScreen:p];
p.y = _screenHeight - p.y;
}
else
{
p.x = (float) x;
p.y = (float) (_height - y);
}
c.x = p.x;
c.y = p.y;
CGSetLocalEventsSuppressionInterval(0);
CGWarpMouseCursorPosition(c);
}
void CIrrDeviceMacOSX::setCursorVisible(bool visible)
{
CGDirectDisplayID display;
display = CGMainDisplayID();
if (visible) CGDisplayShowCursor(display);
else CGDisplayHideCursor(display);
}
void CIrrDeviceMacOSX::initKeycodes()
{
_keycodes[NSUpArrowFunctionKey] = irr::KEY_UP;
_keycodes[NSDownArrowFunctionKey] = irr::KEY_DOWN;
_keycodes[NSLeftArrowFunctionKey] = irr::KEY_LEFT;
_keycodes[NSRightArrowFunctionKey] = irr::KEY_RIGHT;
_keycodes[NSF1FunctionKey] = irr::KEY_F1;
_keycodes[NSF2FunctionKey] = irr::KEY_F2;
_keycodes[NSF3FunctionKey] = irr::KEY_F3;
_keycodes[NSF4FunctionKey] = irr::KEY_F4;
_keycodes[NSF5FunctionKey] = irr::KEY_F5;
_keycodes[NSF6FunctionKey] = irr::KEY_F6;
_keycodes[NSF7FunctionKey] = irr::KEY_F7;
_keycodes[NSF8FunctionKey] = irr::KEY_F8;
_keycodes[NSF9FunctionKey] = irr::KEY_F9;
_keycodes[NSF10FunctionKey] = irr::KEY_F10;
_keycodes[NSF11FunctionKey] = irr::KEY_F11;
_keycodes[NSF12FunctionKey] = irr::KEY_F12;
_keycodes[NSF13FunctionKey] = irr::KEY_F13;
_keycodes[NSF14FunctionKey] = irr::KEY_F14;
_keycodes[NSF15FunctionKey] = irr::KEY_F15;
_keycodes[NSF16FunctionKey] = irr::KEY_F16;
_keycodes[NSHomeFunctionKey] = irr::KEY_HOME;
_keycodes[NSEndFunctionKey] = irr::KEY_END;
_keycodes[NSInsertFunctionKey] = irr::KEY_INSERT;
_keycodes[NSDeleteFunctionKey] = irr::KEY_DELETE;
_keycodes[NSHelpFunctionKey] = irr::KEY_HELP;
_keycodes[NSSelectFunctionKey] = irr::KEY_SELECT;
_keycodes[NSPrintFunctionKey] = irr::KEY_PRINT;
_keycodes[NSExecuteFunctionKey] = irr::KEY_EXECUT;
_keycodes[NSPrintScreenFunctionKey] = irr::KEY_SNAPSHOT;
_keycodes[NSPauseFunctionKey] = irr::KEY_PAUSE;
_keycodes[NSScrollLockFunctionKey] = irr::KEY_SCROLL;
_keycodes[0x7F] = irr::KEY_BACK;
_keycodes[0x09] = irr::KEY_TAB;
_keycodes[0x0D] = irr::KEY_RETURN;
_keycodes[0x03] = irr::KEY_RETURN;
_keycodes[0x1B] = irr::KEY_ESCAPE;
}
//! Sets if the window should be resizeable in windowed mode.
void CIrrDeviceMacOSX::setResizeAble(bool resize)
{
// todo: implement resize
}
IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& param)
{
CIrrDeviceMacOSX* dev = new CIrrDeviceMacOSX(
param.DriverType,
param.WindowSize,
param.Bits,
param.Fullscreen,
param.Stencilbuffer,
param.Vsync,
param.AntiAlias,
param.EventReceiver,
param.SDK_version_do_not_use);
if (dev && !dev->getVideoDriver() && param.DriverType != video::EDT_NULL)
{
dev->drop();
dev = 0;
}
return dev;
}
}
#endif
// Copyright (C) 2005 Etienne Petitjean
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_USE_OSX_DEVICE_
#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>
#include "CIrrDeviceMacOSX.h"
#include "IEventReceiver.h"
#include "irrList.h"
#include "os.h"
#include "CTimer.h"
#include "irrString.h"
#include "Keycodes.h"
#include <stdio.h>
#include <sys/utsname.h>
#include "COSOperator.h"
#include "irrlicht.h"
#import <wchar.h>
#import <time.h>
#import "AppDelegate.h"
namespace irr
{
namespace video
{
IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize, CIrrDeviceMacOSX *device, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias);
}
} // end namespace irr
static bool firstLaunch = true;
namespace irr
{
//! constructor
CIrrDeviceMacOSX::CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType,
const core::dimension2d<s32>& windowSize,
u32 bits, bool fullscreen,
bool sbuffer, bool vsync,
bool antiAlias, IEventReceiver* receiver,
const char* version)
: CIrrDeviceStub(version, receiver), DriverType(driverType), stencilbuffer(sbuffer), _window(NULL), _active(true), _oglcontext(NULL), _cglcontext(NULL)
{
struct utsname name;
NSString *path;
#ifdef _DEBUG
setDebugName("CIrrDeviceMacOSX");
#endif
if (firstLaunch)
{
firstLaunch = false;
[[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
[NSApp setDelegate:[[[AppDelegate alloc] initWithDevice:this] autorelease]];
[NSBundle loadNibNamed:@"MainMenu" owner:[NSApp delegate]];
[NSApp finishLaunching];
path = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
chdir([path cString]);
}
uname(&name);
Operator = new COSOperator(name.version);
os::Printer::log(name.version,ELL_INFORMATION);
initKeycodes();
if (driverType != video::EDT_NULL) createWindow(windowSize,bits,fullscreen,vsync,stencilbuffer);
CursorControl = new CCursorControl(windowSize, this);
createDriver(driverType,windowSize,bits,fullscreen,stencilbuffer,vsync,antiAlias);
createGUIAndScene();
}
CIrrDeviceMacOSX::~CIrrDeviceMacOSX()
{
closeDevice();
}
void CIrrDeviceMacOSX::closeDevice()
{
if (_window != NULL)
{
[_window setIsVisible:FALSE];
if (_oglcontext != NULL)
{
[_oglcontext clearDrawable];
[_oglcontext release];
_oglcontext = NULL;
}
[_window setReleasedWhenClosed:TRUE];
[_window release];
_window = NULL;
}
else
{
if (_cglcontext != NULL)
{
CGLSetCurrentContext(NULL);
CGLClearDrawable(_cglcontext);
CGLDestroyContext(_cglcontext);
}
}
_active = FALSE;
_cglcontext = NULL;
}
bool CIrrDeviceMacOSX::createWindow(const irr::core::dimension2d<irr::s32>& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer)
{
int index;
CGDisplayErr error;
bool result;
NSOpenGLPixelFormat *format;
CGDirectDisplayID display;
CGLPixelFormatObj pixelFormat;
CGRect displayRect;
CGLPixelFormatAttribute fullattribs[32];
NSOpenGLPixelFormatAttribute windowattribs[32];
CFDictionaryRef displaymode,olddisplaymode;
long numPixelFormats,newSwapInterval;
result = false;
display = CGMainDisplayID();
_screenWidth = (int) CGDisplayPixelsWide(display);
_screenHeight = (int) CGDisplayPixelsHigh(display);
if (!fullscreen)
{
_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,windowSize.Width,windowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:NSBackingStoreBuffered defer:FALSE];
if (_window != NULL)
{
index = 0;
windowattribs[index++] = NSOpenGLPFANoRecovery;
windowattribs[index++] = NSOpenGLPFADoubleBuffer;
windowattribs[index++] = NSOpenGLPFAAccelerated;
windowattribs[index++] = NSOpenGLPFADepthSize;
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)16;
windowattribs[index++] = NSOpenGLPFAColorSize;
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)bits;
if (stencilBuffer)
{
windowattribs[index++] = NSOpenGLPFAStencilSize;
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)1;
}
windowattribs[index++] = (NSOpenGLPixelFormatAttribute)NULL;
format = [[NSOpenGLPixelFormat alloc] initWithAttributes:windowattribs];
if (format != NULL)
{
_oglcontext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:NULL];
[format release];
}
if (_oglcontext != NULL)
{
[_window center];
[_window setDelegate:[NSApp delegate]];
[_oglcontext setView:[_window contentView]];
[_window setAcceptsMouseMovedEvents:TRUE];
[_window setIsVisible:TRUE];
[_window makeKeyAndOrderFront:nil];
_cglcontext = (CGLContextObj) [_oglcontext CGLContextObj];
_width = windowSize.Width;
_height = windowSize.Height;
result = true;
}
}
}
else
{
displaymode = CGDisplayBestModeForParameters(display,bits,windowSize.Width,windowSize.Height,NULL);
if (displaymode != NULL)
{
olddisplaymode = CGDisplayCurrentMode(display);
error = CGCaptureAllDisplays();
if (error == CGDisplayNoErr)
{
error = CGDisplaySwitchToMode(display,displaymode);
if (error == CGDisplayNoErr)
{
pixelFormat = NULL;
numPixelFormats = 0;
index = 0;
fullattribs[index++] = kCGLPFAFullScreen;
fullattribs[index++] = kCGLPFADisplayMask;
fullattribs[index++] = (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(display);
fullattribs[index++] = kCGLPFADoubleBuffer;
fullattribs[index++] = kCGLPFAAccelerated;
fullattribs[index++] = kCGLPFADepthSize;
fullattribs[index++] = (CGLPixelFormatAttribute)16;
fullattribs[index++] = kCGLPFAColorSize;
fullattribs[index++] = (CGLPixelFormatAttribute)bits;
if (stencilBuffer)
{
fullattribs[index++] = kCGLPFAStencilSize;
fullattribs[index++] = (CGLPixelFormatAttribute)1;
}
fullattribs[index++] = (CGLPixelFormatAttribute)NULL;
CGLChoosePixelFormat(fullattribs,&pixelFormat,&numPixelFormats);
if (pixelFormat != NULL)
{
CGLCreateContext(pixelFormat,NULL,&_cglcontext);
CGLDestroyPixelFormat(pixelFormat);
}
if (_cglcontext != NULL)
{
CGLSetFullScreen(_cglcontext);
displayRect = CGDisplayBounds(display);
_width = (int)displayRect.size.width;
_height = (int)displayRect.size.height;
result = true;
}
}
}
}
}
if (result)
{
CGLSetCurrentContext(_cglcontext);
newSwapInterval = (vsync) ? 1 : 0;
CGLSetParameter(_cglcontext,kCGLCPSwapInterval,&newSwapInterval);
glViewport(0,0,_width,_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
return (result);
}
void CIrrDeviceMacOSX::setResize(int width,int height)
{
_width = width;
_height = height;
[_oglcontext update];
getVideoDriver()->OnResize(core::dimension2d<s32>(width, height));
}
void CIrrDeviceMacOSX::createDriver(video::E_DRIVER_TYPE driverType,const core::dimension2d<s32>& windowSize,u32 bits,bool fullscreen,bool stencilbuffer, bool vsync, bool antiAlias)
{
switch (driverType)
{
case video::EDT_SOFTWARE:
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
VideoDriver = video::createSoftwareDriver(windowSize, fullscreen, FileSystem, this);
#else
os::Printer::log("No Software driver support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_BURNINGSVIDEO:
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
VideoDriver = video::createSoftwareDriver2(windowSize, fullscreen, FileSystem, this);
#else
os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_OPENGL:
#ifdef _IRR_COMPILE_WITH_OPENGL_
VideoDriver = video::createOpenGLDriver(windowSize, this, fullscreen, stencilbuffer, FileSystem, vsync, antiAlias);
#else
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_DIRECT3D8:
case video::EDT_DIRECT3D9:
os::Printer::log("This driver is not available in OSX. Try OpenGL or Software renderer.", ELL_ERROR);
break;
case video::EDT_NULL:
VideoDriver = video::createNullDriver(FileSystem, windowSize);
break;
default:
os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
break;
}
}
void CIrrDeviceMacOSX::flush()
{
if (_cglcontext != NULL)
{
glFinish();
CGLFlushDrawable(_cglcontext);
}
}
bool CIrrDeviceMacOSX::run()
{
NSEvent *event;
irr::SEvent ievent;
os::Timer::tick();
storeMouseLocation();
event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
if (event != nil)
{
bzero(&ievent,sizeof(ievent));
switch([event type])
{
case NSKeyDown:
postKeyEvent(event,ievent,true);
break;
case NSKeyUp:
postKeyEvent(event,ievent,false);
break;
case NSLeftMouseDown:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN;
postMouseEvent(event,ievent);
break;
case NSLeftMouseUp:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP;
postMouseEvent(event,ievent);
break;
case NSMouseMoved:
case NSLeftMouseDragged:
case NSRightMouseDragged:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
postMouseEvent(event,ievent);
break;
case NSRightMouseDown:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN;
postMouseEvent(event,ievent);
break;
case NSRightMouseUp:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP;
postMouseEvent(event,ievent);
break;
case NSScrollWheel:
ievent.EventType = irr::EET_MOUSE_INPUT_EVENT;
ievent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL;
ievent.MouseInput.Wheel = [event deltaY];
if (ievent.MouseInput.Wheel < 1.0f) ievent.MouseInput.Wheel *= 10.0f;
else ievent.MouseInput.Wheel *= 5.0f;
postMouseEvent(event,ievent);
break;
default:
[NSApp sendEvent:event];
break;
}
}
return (![[NSApp delegate] isQuit] && _active);
}
//! Pause the current process for the minimum time allowed only to allow other processes to execute
void CIrrDeviceMacOSX::yield()
{
// TODO: Does this work or maybe is there a better way?
struct timespec ts = {0,0};
nanosleep(&ts, NULL);
}
//! Pause execution and let other processes to run for a specified amount of time.
void CIrrDeviceMacOSX::sleep(u32 timeMs, bool pauseTimer=false)
{
// TODO: Does this work or maybe is there a better way?
bool wasStopped = Timer ? Timer->isStopped() : true;
struct timespec ts;
ts.tv_sec = (time_t) (timeMs / 1000);
ts.tv_nsec = (long) (timeMs % 1000) * 1000000;
if (pauseTimer && !wasStopped)
Timer->stop();
nanosleep(&ts, NULL);
if (pauseTimer && !wasStopped)
Timer->start();
}
void CIrrDeviceMacOSX::present(video::IImage* image, s32 windowId, core::rect<s32>* src )
{
}
void CIrrDeviceMacOSX::setWindowCaption(const wchar_t* text)
{
size_t size;
char title[1024];
if (_window != NULL)
{
size = wcstombs(title,text,1024);
if (size == 1024) title[1023] = 0;
[_window setTitle:[NSString stringWithCString:title length:size]];
}
}
bool CIrrDeviceMacOSX::isWindowActive() const
{
return (_active);
}
void CIrrDeviceMacOSX::postKeyEvent(void *event,irr::SEvent &ievent,bool pressed)
{
NSString *str;
std::map<int,int>::const_iterator iter;
unsigned int result,c,mkey,mchar;
const unsigned char *cStr;
BOOL skipCommand;
str = [event characters];
if (str != nil && [str length] > 0)
{
mkey = mchar = 0;
skipCommand = false;
c = [str characterAtIndex:0];
iter = _keycodes.find(c);
if (iter != _keycodes.end()) mkey = (*iter).second;
else
{
cStr = (unsigned char *)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
if (cStr != NULL && strlen((char*)cStr) > 0)
{
mchar = cStr[0];
mkey = toupper(mchar);
if ([event modifierFlags] & NSCommandKeyMask)
{
if (mkey == 'C' || mkey == 'V' || mkey == 'X')
{
mchar = 0;
skipCommand = true;
}
}
}
}
ievent.EventType = irr::EET_KEY_INPUT_EVENT;
ievent.KeyInput.Key = (irr::EKEY_CODE)mkey;
ievent.KeyInput.PressedDown = pressed;
ievent.KeyInput.Shift = ([event modifierFlags] & NSShiftKeyMask) != 0;
ievent.KeyInput.Control = ([event modifierFlags] & NSControlKeyMask) != 0;
ievent.KeyInput.Char = (irr::EKEY_CODE)mchar;
if (skipCommand)
ievent.KeyInput.Control = true;
else if ([event modifierFlags] & NSCommandKeyMask)
[NSApp sendEvent:(NSEvent *)event];
postEventFromUser(ievent);
}
}
void CIrrDeviceMacOSX::postMouseEvent(void *event,irr::SEvent &ievent)
{
BOOL post = true;
if (_window != NULL)
{
ievent.MouseInput.X = (int)[event locationInWindow].x;
ievent.MouseInput.Y = _height - (int)[event locationInWindow].y;
if (ievent.MouseInput.Y < 0) post = false;
}
else
{
ievent.MouseInput.X = (int)[NSEvent mouseLocation].x;
ievent.MouseInput.Y = _height - (int)[NSEvent mouseLocation].y;
}
if (post) postEventFromUser(ievent);
[NSApp sendEvent:(NSEvent *)event];
}
void CIrrDeviceMacOSX::storeMouseLocation()
{
NSPoint p;
int x,y;
p = [NSEvent mouseLocation];
if (_window != NULL)
{
p = [_window convertScreenToBase:p];
x = (int)p.x;
y = _height - (int)p.y;
}
else
{
x = (int)p.x;
y = _screenHeight - (int)p.y;
}
((CCursorControl *)CursorControl)->updateInternalCursorPosition(x,y);
}
void CIrrDeviceMacOSX::setMouseLocation(int x,int y)
{
NSPoint p;
CGPoint c;
if (_window != NULL)
{
p.x = (float) x;
p.y = (float) (_height - y);
p = [_window convertBaseToScreen:p];
p.y = _screenHeight - p.y;
}
else
{
p.x = (float) x;
p.y = (float) (_height - y);
}
c.x = p.x;
c.y = p.y;
CGSetLocalEventsSuppressionInterval(0);
CGWarpMouseCursorPosition(c);
}
void CIrrDeviceMacOSX::setCursorVisible(bool visible)
{
CGDirectDisplayID display;
display = CGMainDisplayID();
if (visible) CGDisplayShowCursor(display);
else CGDisplayHideCursor(display);
}
void CIrrDeviceMacOSX::initKeycodes()
{
_keycodes[NSUpArrowFunctionKey] = irr::KEY_UP;
_keycodes[NSDownArrowFunctionKey] = irr::KEY_DOWN;
_keycodes[NSLeftArrowFunctionKey] = irr::KEY_LEFT;
_keycodes[NSRightArrowFunctionKey] = irr::KEY_RIGHT;
_keycodes[NSF1FunctionKey] = irr::KEY_F1;
_keycodes[NSF2FunctionKey] = irr::KEY_F2;
_keycodes[NSF3FunctionKey] = irr::KEY_F3;
_keycodes[NSF4FunctionKey] = irr::KEY_F4;
_keycodes[NSF5FunctionKey] = irr::KEY_F5;
_keycodes[NSF6FunctionKey] = irr::KEY_F6;
_keycodes[NSF7FunctionKey] = irr::KEY_F7;
_keycodes[NSF8FunctionKey] = irr::KEY_F8;
_keycodes[NSF9FunctionKey] = irr::KEY_F9;
_keycodes[NSF10FunctionKey] = irr::KEY_F10;
_keycodes[NSF11FunctionKey] = irr::KEY_F11;
_keycodes[NSF12FunctionKey] = irr::KEY_F12;
_keycodes[NSF13FunctionKey] = irr::KEY_F13;
_keycodes[NSF14FunctionKey] = irr::KEY_F14;
_keycodes[NSF15FunctionKey] = irr::KEY_F15;
_keycodes[NSF16FunctionKey] = irr::KEY_F16;
_keycodes[NSHomeFunctionKey] = irr::KEY_HOME;
_keycodes[NSEndFunctionKey] = irr::KEY_END;
_keycodes[NSInsertFunctionKey] = irr::KEY_INSERT;
_keycodes[NSDeleteFunctionKey] = irr::KEY_DELETE;
_keycodes[NSHelpFunctionKey] = irr::KEY_HELP;
_keycodes[NSSelectFunctionKey] = irr::KEY_SELECT;
_keycodes[NSPrintFunctionKey] = irr::KEY_PRINT;
_keycodes[NSExecuteFunctionKey] = irr::KEY_EXECUT;
_keycodes[NSPrintScreenFunctionKey] = irr::KEY_SNAPSHOT;
_keycodes[NSPauseFunctionKey] = irr::KEY_PAUSE;
_keycodes[NSScrollLockFunctionKey] = irr::KEY_SCROLL;
_keycodes[0x7F] = irr::KEY_BACK;
_keycodes[0x09] = irr::KEY_TAB;
_keycodes[0x0D] = irr::KEY_RETURN;
_keycodes[0x03] = irr::KEY_RETURN;
_keycodes[0x1B] = irr::KEY_ESCAPE;
}
//! Sets if the window should be resizeable in windowed mode.
void CIrrDeviceMacOSX::setResizeAble(bool resize)
{
// todo: implement resize
}
IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& param)
{
CIrrDeviceMacOSX* dev = new CIrrDeviceMacOSX(
param.DriverType,
param.WindowSize,
param.Bits,
param.Fullscreen,
param.Stencilbuffer,
param.Vsync,
param.AntiAlias,
param.EventReceiver,
param.SDK_version_do_not_use);
if (dev && !dev->getVideoDriver() && param.DriverType != video::EDT_NULL)
{
dev->drop();
dev = 0;
}
return dev;
}
}
#endif // _IRR_USE_OSX_DEVICE_
......@@ -1155,7 +1155,7 @@
4C53E18D0A484C2C0014E966 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = uncompr.c; sourceTree = "<group>"; };
4C53E1920A484C2C0014E966 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = zutil.c; sourceTree = "<group>"; };
4C53E24D0A4850120014E966 /* libIrrlicht.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIrrlicht.a; sourceTree = BUILT_PRODUCTS_DIR; };
4C53E2520A4850550014E966 /* Quake3Map.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Quake3Map.app; sourceTree = BUILT_PRODUCTS_DIR; };
4C53E2520A4850550014E966 /* Quake3Map_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Quake3Map_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4C53E26D0A4850D60014E966 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
4C53E26E0A4850D60014E966 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = "DemoApp-Info.plist"; sourceTree = "<group>"; };
......@@ -1219,18 +1219,18 @@
4C53E76F0A485CD90014E966 /* wrrle.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrrle.c; sourceTree = "<group>"; };
4C53E7700A485CD90014E966 /* wrtarga.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrtarga.c; sourceTree = "<group>"; };
4C6DC9B60A48715A0017A6E5 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inflate.c; sourceTree = "<group>"; };
4CA25B980A485D9800B4E469 /* CustomSceneNode.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomSceneNode.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25B9A0A485D9800B4E469 /* MeshViewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshViewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RenderToTexture.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25B9E0A485D9800B4E469 /* UserInterface.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UserInterface.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerPixelLighting.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA20A485D9800B4E469 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA40A485D9800B4E469 /* Movement.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movement.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA60A485D9800B4E469 /* Shaders.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Shaders.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA80A485D9800B4E469 /* SpecialFx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpecialFx.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TerrainRendering.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2DGraphics.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BAE0A485D9800B4E469 /* Collision.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Collision.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomSceneNode_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshViewer_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RenderToTexture_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UserInterface_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = PerPixelLighting_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA20A485D9800B4E469 /* Demo_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA40A485D9800B4E469 /* Movement_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movement_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Shaders_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpecialFx_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TerrainRendering_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2DGraphics_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Collision_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSphereSceneNode.cpp; sourceTree = "<group>"; };
4CC36B0E0A6B61DB0076C4B2 /* CSphereSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSphereSceneNode.h; sourceTree = "<group>"; };
4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderBMP.cpp; sourceTree = "<group>"; };
......@@ -2588,19 +2588,19 @@
isa = PBXGroup;
children = (
4C53E24D0A4850120014E966 /* libIrrlicht.a */,
4C53E2520A4850550014E966 /* Quake3Map.app */,
4CA25B980A485D9800B4E469 /* CustomSceneNode.app */,
4CA25BA40A485D9800B4E469 /* Movement.app */,
4CA25B9E0A485D9800B4E469 /* UserInterface.app */,
4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */,
4CA25BAE0A485D9800B4E469 /* Collision.app */,
4CA25BA80A485D9800B4E469 /* SpecialFx.app */,
4CA25B9A0A485D9800B4E469 /* MeshViewer.app */,
4CA25BA60A485D9800B4E469 /* Shaders.app */,
4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */,
4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */,
4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */,
4CA25BA20A485D9800B4E469 /* Demo.app */,
4C53E2520A4850550014E966 /* Quake3Map_dbg.app */,
4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */,
4CA25BA40A485D9800B4E469 /* Movement_dbg.app */,
4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */,
4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */,
4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */,
4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */,
4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */,
4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */,
4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */,
4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */,
4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */,
4CA25BA20A485D9800B4E469 /* Demo_dbg.app */,
09F6493E0D2CE03E001E0599 /* LoadIrrFile.app */,
09F649650D2CE206001E0599 /* Quake3Shader.app */,
09F649030D2CDED9001E0599 /* HelloWorld.app */,
......@@ -2828,7 +2828,7 @@
);
name = 2DGraphics;
productName = DemoApp;
productReference = 4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */;
productReference = 4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFE82097FDDE20057C06F /* Collision */ = {
......@@ -2846,7 +2846,7 @@
);
name = Collision;
productName = DemoApp;
productReference = 4CA25BAE0A485D9800B4E469 /* Collision.app */;
productReference = 4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFEA4097FDE900057C06F /* PerPixelLightning */ = {
......@@ -2864,7 +2864,7 @@
);
name = PerPixelLightning;
productName = DemoApp;
productReference = 4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */;
productReference = 4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFEC2097FDF020057C06F /* TerrainRendering */ = {
......@@ -2882,7 +2882,7 @@
);
name = TerrainRendering;
productName = DemoApp;
productReference = 4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */;
productReference = 4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFEE8097FE05F0057C06F /* SpecialFx */ = {
......@@ -2900,7 +2900,7 @@
);
name = SpecialFx;
productName = DemoApp;
productReference = 4CA25BA80A485D9800B4E469 /* SpecialFx.app */;
productReference = 4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFF07097FE13E0057C06F /* UserInterface */ = {
......@@ -2918,7 +2918,7 @@
);
name = UserInterface;
productName = DemoApp;
productReference = 4CA25B9E0A485D9800B4E469 /* UserInterface.app */;
productReference = 4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFF1E097FE1E00057C06F /* CustomSceneNode */ = {
......@@ -2936,7 +2936,7 @@
);
name = CustomSceneNode;
productName = DemoApp;
productReference = 4CA25B980A485D9800B4E469 /* CustomSceneNode.app */;
productReference = 4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFF33097FE25F0057C06F /* Quake3Map */ = {
......@@ -2954,7 +2954,7 @@
);
name = Quake3Map;
productName = DemoApp;
productReference = 4C53E2520A4850550014E966 /* Quake3Map.app */;
productReference = 4C53E2520A4850550014E966 /* Quake3Map_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFF4A097FE3050057C06F /* Shaders */ = {
......@@ -2972,7 +2972,7 @@
);
name = Shaders;
productName = DemoApp;
productReference = 4CA25BA60A485D9800B4E469 /* Shaders.app */;
productReference = 4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFF78097FE3DC0057C06F /* Movement */ = {
......@@ -2990,7 +2990,7 @@
);
name = Movement;
productName = DemoApp;
productReference = 4CA25BA40A485D9800B4E469 /* Movement.app */;
productReference = 4CA25BA40A485D9800B4E469 /* Movement_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFF91097FE45E0057C06F /* MeshViewer */ = {
......@@ -3008,7 +3008,7 @@
);
name = MeshViewer;
productName = DemoApp;
productReference = 4CA25B9A0A485D9800B4E469 /* MeshViewer.app */;
productReference = 4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */;
productType = "com.apple.product-type.application";
};
B81CFFAF097FE5F80057C06F /* RenderToTexture */ = {
......@@ -3026,7 +3026,7 @@
);
name = RenderToTexture;
productName = DemoApp;
productReference = 4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */;
productReference = 4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */;
productType = "com.apple.product-type.application";
};
B8DEF35C0950229200FDEA7E /* Demo */ = {
......@@ -3044,7 +3044,7 @@
);
name = Demo;
productName = DemoApp;
productReference = 4CA25BA20A485D9800B4E469 /* Demo.app */;
productReference = 4CA25BA20A485D9800B4E469 /* Demo_dbg.app */;
productType = "com.apple.product-type.application";
};
D2AAC07D0554694100DB518D /* libIrrlicht.a */ = {
......
......@@ -145,12 +145,6 @@ REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b )
return ( mask & ( a ^ b ) ) ^ b;
}
inline void setbits ( u32 &state, s32 condition, u32 mask )
{
state ^= ( ( -condition >> 31 ) ^ state ) & mask;
}
// ------------------ Video---------------------------------------
/*!
Pixel = dest * ( 1 - alpha ) + source * alpha
......
......@@ -21,7 +21,8 @@
#define bswap_32(X) ( (((X)&0x000000FF)<<24) | (((X)&0xFF000000) >> 24) | (((X)&0x0000FF00) << 8) | (((X) &0x00FF0000) >> 8))
#endif
#else
#ifdef MACOSX
#if defined(_IRR_OSX_PLATFORM_)
#include <libkern/OSByteOrder.h>
#define bswap_16(X) OSReadSwapInt16(&X,0)
#define bswap_32(X) OSReadSwapInt32(&X,0)
#elif defined(__FreeBSD__)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment