Exemple #1
0
//! looks if file is in the same directory of path. returns offset of directory.
//! 0 means in same directory. 1 means file is direct child of path
		s32 ioutils::isInSameDirectory(const core::stringc& path,
				const core::stringc& file)
		{
			s32 subA = 0;
			s32 subB = 0;
			s32 pos;

			if (path.size() && !path.equalsn(file, path.size()))
				return -1;

			pos = 0;
			while ((pos = path.findFirst('/', pos)) >= 0)
			{
				subA += 1;
				pos += 1;
			}

			pos = 0;
			while ((pos = file.findFirst('/', pos)) >= 0)
			{
				subB += 1;
				pos += 1;
			}

			return subB - subA;
		}
Exemple #2
0
//! returns the base part of a filename, i.e. all except for the directory
//! part. If no directory path is prefixed, the full name is returned.
core::stringc CFileSystem::getFileBasename(const core::stringc& filename, bool keepExtension) const
{
    // find last forward or backslash
    s32 lastSlash = filename.findLast('/');
    const s32 lastBackSlash = filename.findLast('\\');
    lastSlash = core::max_(lastSlash, lastBackSlash);

    // get number of chars after last dot
    s32 end = 0;
    if (!keepExtension)
    {
        // take care to search only after last slash to check only for
        // dots in the filename
        end = filename.findLast('.', lastSlash);
        if (end == -1)
            end=0;
        else
            end = filename.size()-end;
    }

    if ((u32)lastSlash < filename.size())
        return filename.subString(lastSlash+1, filename.size()-lastSlash-1-end);
    else if (end != 0)
        return filename.subString(0, filename.size()-end);
    else
        return filename;
}
bool CSTLMeshWriter::writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	// write STL MESH header

	file->write("solid ",6);
	const core::stringc name(SceneManager->getMeshCache()->getMeshFilename(mesh));
	file->write(name.c_str(),name.size());
	file->write("\n\n",2);

	// write mesh buffers
	
	for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
	{
		IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if (buffer)
		{
			const u16 indexCount = buffer->getIndexCount();

			switch(buffer->getVertexType())
			{
			case video::EVT_STANDARD:
				{
					video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
					for (u32 j=0; j<indexCount; j+=3)
						writeFace(file,
							vtx[buffer->getIndices()[j]].Pos,
							vtx[buffer->getIndices()[j+1]].Pos,
							vtx[buffer->getIndices()[j+2]].Pos);
				}
				break;
			case video::EVT_2TCOORDS:
				{
					video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
					for (u32 j=0; j<indexCount; j+=3)
						writeFace(file,
							vtx[buffer->getIndices()[j]].Pos,
							vtx[buffer->getIndices()[j+1]].Pos,
							vtx[buffer->getIndices()[j+2]].Pos);
				}
				break;
			case video::EVT_TANGENTS:
				{
					video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
					for (u32 j=0; j<indexCount; j+=3)
						writeFace(file,
							vtx[buffer->getIndices()[j]].Pos,
							vtx[buffer->getIndices()[j+1]].Pos,
							vtx[buffer->getIndices()[j+2]].Pos);
				}
				break;
			}
			file->write("\n",1);
		}
	}

	file->write("endsolid ",9);
	file->write(name.c_str(),name.size());

	return true;
}
Exemple #4
0
bool CSTLMeshWriter::writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	// write STL MESH header

	file->write("solid ",6);
	const core::stringc name(SceneManager->getMeshCache()->getMeshName(mesh));
	file->write(name.c_str(),name.size());
	file->write("\n\n",2);

	// write mesh buffers

	for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
	{
		IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if (buffer)
		{
			const u32 indexCount = buffer->getIndexCount();
			for (u32 j=0; j<indexCount; j+=3)
			{
				writeFace(file,
					buffer->getPosition(buffer->getIndices()[j]),
					buffer->getPosition(buffer->getIndices()[j+1]),
					buffer->getPosition(buffer->getIndices()[j+2]));
			}
			file->write("\n",1);
		}
	}

	file->write("endsolid ",9);
	file->write(name.c_str(),name.size());

	return true;
}
Exemple #5
0
bool FileSceneNode::isimg(core::stringc name) {
    if ((name.subString(name.size() - 4, 4).equals_ignore_case(".bmp")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".jpg")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".tga")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".pcx")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".png")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".psd")))
        return true;
    return false;
}
Exemple #6
0
bool FileSceneNode::isanimesh(core::stringc name) {
    if ((name.subString(name.size() - 4, 4).equals_ignore_case(".md2")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".md3")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".obj")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".bsp")) ||
            (name.subString(name.size() - 5, 5).equals_ignore_case(".my3d")) ||
            (name.subString(name.size() - 5, 5).equals_ignore_case(".lmts")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".csm")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".oct")))
        return true;
    return false;
}
Exemple #7
0
bool FileSceneNode::isvid(core::stringc name) {
    if ((name.subString(name.size() - 4, 4).equals_ignore_case(".avi")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".wmv")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".mpg")) ||
            (name.subString(name.size() - 5, 5).equals_ignore_case(".mpeg")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".mp4")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".mkv")) ||
            (name.subString(name.size() - 4, 4).equals_ignore_case(".ogm")) ||
            (name.subString(name.size() - 3, 3).equals_ignore_case(".rm")) ||
            (name.subString(name.size() - 5, 5).equals_ignore_case(".divx")))
        return true;
    return false;
}
Exemple #8
0
core::stringc CFileSystem::getAbsolutePath(const core::stringc& filename) const
{
	c8 *p=0;

#ifdef _IRR_WINDOWS_API_
	#if !defined ( _WIN32_WCE )
	c8 fpath[_MAX_PATH];
	p = _fullpath( fpath, filename.c_str(), _MAX_PATH);
	#endif

#elif (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
	c8 fpath[4096];
	fpath[0]=0;
	p = realpath(filename.c_str(), fpath);
	if (!p)
	{
		// content in fpath is undefined at this point
		if ('0'==fpath[0]) // seems like fpath wasn't altered
		{
			// at least remove a ./ prefix
			if ('.'==filename[0] && '/'==filename[1])
				return filename.subString(2, filename.size()-2);
			else
				return filename;
		}
		else
			return core::stringc(fpath);
	}

#endif

	return core::stringc(p);
}
Exemple #9
0
bool CSTLMeshWriter::writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	// write STL MESH header

	file->write("binary ",7);
	const core::stringc name(SceneManager->getMeshCache()->getMeshName(mesh));
	const s32 sizeleft = 73-name.size(); // 80 byte header
	if (sizeleft<0)
		file->write(name.c_str(),73);
	else
	{
		char* buf = new char[80];
		memset(buf, 0, 80);
		file->write(name.c_str(),name.size());
		file->write(buf,sizeleft);
		delete [] buf;
	}
	u32 facenum = 0;
	for (u32 j=0; j<mesh->getMeshBufferCount(); ++j)
		facenum += mesh->getMeshBuffer(j)->getIndexCount()/3;
	file->write(&facenum,4);

	// write mesh buffers

	for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
	{
		IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if (buffer)
		{
			const u32 indexCount = buffer->getIndexCount();
			const u16 attributes = 0;
			for (u32 j=0; j<indexCount; j+=3)
			{
				const core::vector3df& v1 = buffer->getPosition(buffer->getIndices()[j]);
				const core::vector3df& v2 = buffer->getPosition(buffer->getIndices()[j+1]);
				const core::vector3df& v3 = buffer->getPosition(buffer->getIndices()[j+2]);
				const core::plane3df tmpplane(v1,v2,v3);
				file->write(&tmpplane.Normal, 12);
				file->write(&v1, 12);
				file->write(&v2, 12);
				file->write(&v3, 12);
				file->write(&attributes, 2);
			}
		}
	}
	return true;
}
Exemple #10
0
core::stringc GetContextPathFromFilename( const core::stringc& filename )
{
    core::stringc path;
    s32 i=filename.size()-1;
    while ( i >= 0 && filename[i] != '/' )
    {
        i--;
    }
    path = filename.subString( 0, i+1 );
    return path;
}
Exemple #11
0
//! returns the directory part of a filename, i.e. all until the first
//! slash or backslash, excluding it. If no directory path is prefixed, a '.'
//! is returned.
core::stringc CFileSystem::getFileDir(const core::stringc& filename) const
{
	// find last forward or backslash
	s32 lastSlash = filename.findLast('/');
	const s32 lastBackSlash = filename.findLast('\\');
	lastSlash = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;

	if ((u32)lastSlash < filename.size())
		return filename.subString(0, lastSlash);
	else
		return ".";
}
Exemple #12
0
//! returns the base part of a filename, i.e. all except for the directory
//! part. If no directory path is prefixed, the full name is returned.
core::stringc CFileSystem::getFileBasename(const core::stringc& filename, bool keepExtension) const
{
	// find last forward or backslash
	s32 lastSlash = filename.findLast('/');
	const s32 lastBackSlash = filename.findLast('\\');
	lastSlash = core::max_(lastSlash, lastBackSlash);
	s32 end = 0;
	if (!keepExtension)
	{
		end = filename.findLast('.');
		if (end == -1)
			end=0;
		else
			end = filename.size()-end;
	}

	if ((u32)lastSlash < filename.size())
		return filename.subString(lastSlash+1, filename.size()-lastSlash-1-end);
	else if (end != 0)
		return filename.subString(0, filename.size()-end);
	else
		return filename;
}
Exemple #13
0
//! deletes the path from a filename
void CPakReader::deletePathFromFilename(core::stringc& filename)
{
	// delete path from filename
	const c8* p = filename.c_str() + filename.size();

	// search for path separator or beginning

	while (*p!='/' && *p!='\\' && p!=filename.c_str())
		--p;

	if (p != filename.c_str())
	{
		++p;
		filename = p;
	}
}
Exemple #14
0
//! deletes the path from a filename
void CPakReader::deletePathFromFilename(core::stringc& filename)
{
	// delete path from filename
	const c8* p = filename.c_str() + filename.size();

	// suche ein slash oder den anfang.

	while (*p!='/' && *p!='\\' && p!=filename.c_str())
		--p;

	core::stringc newName;

	if (p != filename.c_str())
	{
		++p;
		filename = p;
	}
}
core::stringc CMS3DMeshFileLoader::stripPathFromString(const core::stringc& inString, bool returnPath) const
{
	s32 slashIndex=inString.findLast('/'); // forward slash
	s32 backSlash=inString.findLast('\\'); // back slash

	if (backSlash>slashIndex) slashIndex=backSlash;

	if (slashIndex==-1)//no slashes found
	{
		if (returnPath)
			return core::stringc(); //no path to return
		else
			return inString;
	}

	if (returnPath)
		return inString.subString(0, slashIndex + 1);
	else
		return inString.subString(slashIndex+1, inString.size() - (slashIndex+1));
}
Exemple #16
0
core::stringc CHashMD5::quickHash(core::stringc str)
{
	hash_start();
	hash_append((u8*)str.c_str(), str.size());
	u8 digest[16];
	hash_finish(digest, 16);
	c8 retstr[33];
	memset(retstr, 0, 33);
	c8* temp = retstr;
	for(int i = 0; i < 16; i++)
	{
		if((digest[i] & 0xff) > 0xf){
			sprintf(temp, "%x", (digest[i] & 0xff));
		}else{
			sprintf(temp, "0%x", (digest[i] & 0xff));
		}
		temp += 2;
	}
	core::stringc ret(retstr);
	return ret;
};
Exemple #17
0
core::array<SDefineExp> grabDefineExpressions(core::stringc &shaderProgram)
{
	s32 CurrentSearchPos = 1;
	s32 FindHelper = 1;
	s32 FindHelper2 = 1;
	
	core::array<SDefineExp> DefineArray;

	// Dont bother stripping comments if theres no defines.
	if((CurrentSearchPos = shaderProgram.find("##ifdef")) == -1)
		return DefineArray;

	// Strip all comments, they get in the way.
	while((CurrentSearchPos = shaderProgram.find("//")) > -1)
	{
		FindHelper = shaderProgram.findNext('\n',CurrentSearchPos);
		if(FindHelper != -1)
			for(u32 i = CurrentSearchPos;i < (u32)FindHelper;++i)
				shaderProgram[i] = ' ';
		else
			for(u32 i = CurrentSearchPos;i < shaderProgram.size();++i)
				shaderProgram[i] = ' ';
	}

	while((CurrentSearchPos = shaderProgram.find("/*")) > -1)
	{
		FindHelper = shaderProgram.find("*/");
		if(FindHelper > CurrentSearchPos)
			for(u32 i = CurrentSearchPos;i <= (u32)(FindHelper + 1);++i)
				shaderProgram[i] = ' ';
		else
			for(u32 i = CurrentSearchPos;i < shaderProgram.size();++i)
				shaderProgram[i] = ' ';
	}

	while((CurrentSearchPos = shaderProgram.find("##ifdef")) > -1)
	{
		SDefineExp DExp;
		
		DExp.IfPos = CurrentSearchPos;
		
		// Comment out the ##ifdef so that we do not find it again, and so that the compiler ignores it.
		shaderProgram[CurrentSearchPos] = '/';
		shaderProgram[CurrentSearchPos + 1] = '/';

		FindHelper = shaderProgram.findNext(' ',CurrentSearchPos);
		FindHelper2 = shaderProgram.findNext('\n',FindHelper);

		if(FindHelper == -1 || FindHelper2 == -1)
		{
			std::cerr << "Shader preprocessor encountered invalid if statement." << std::endl;
			return DefineArray;
		}

		// Find the appropriate expression and trim all white space.
		DExp.IfExp = shaderProgram.subString(FindHelper,FindHelper2 - FindHelper);
		DExp.IfExp.trim();
		
		// Record if its inverse and remove ! sign from expression.
		if(DExp.IfExp[0] == '!')
		{
			DExp.IfExp[0] = ' ';
			DExp.IfExp.trim();
			DExp.Inverse = true;
		}

		bool EndIfFound = false;

		FindHelper2 = CurrentSearchPos;
		s32 IfEndScope = 0;

		while(!EndIfFound)
		{
			FindHelper = shaderProgram.findNext('#',FindHelper2);

			if(FindHelper == -1 || FindHelper >= (s32)(shaderProgram.size() - 3))
			{
				std::cerr << "Shader preprocessor encountered unmatched if statement." << std::endl;
				return DefineArray;
			}

			if(IfEndScope < 0)
			{
				std::cerr << "Shader preprocessor encountered unmatched endif statement." << std::endl;
				return DefineArray;
			}
			
			if(shaderProgram[FindHelper + 1] != '#')
			{
				FindHelper2 = FindHelper + 1;
				continue;
			}
			else if(shaderProgram[FindHelper + 2] == 'i')
			{
				IfEndScope++;
			}
			else if(shaderProgram[FindHelper + 2] == 'e' && shaderProgram[FindHelper + 3] == 'n')
			{
				if(IfEndScope == 0)
					break;

				IfEndScope--;
			}
			else if(shaderProgram[FindHelper + 2] == 'e' && shaderProgram[FindHelper + 3] == 'l')
			{
				if(IfEndScope == 0)
				{
					if(DExp.ElsePos != -1)
					{
						std::cerr << "Shader preprocessor encountered duplicate else statements per if statement." << std::endl;
						return DefineArray;
					}

					// Comment out the ##else so that we do not find it again, and so that the compiler ignores it.
					shaderProgram[FindHelper] = '/';
					shaderProgram[FindHelper + 1] = '/';

					DExp.ElsePos = FindHelper;
				}
			}
			
			FindHelper2 = FindHelper + 2;
		}

		// Comment out the ##endif so that we do not find it again, and so that the compiler ignores it.
		shaderProgram[FindHelper] = '/';
		shaderProgram[FindHelper + 1] = '/';

		DExp.EndPos = FindHelper;
		
		// Add the define expression to the array.
		DefineArray.push_back(DExp);
	}

	return DefineArray;
}
IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
{
	MaterialEntry.clear();
	MeshBufferEntry.clear();
	ChildNodes.clear();

	// working directory (from which we load the scene)
	core::stringc filepath = FileSystem->getFileDir(file->getFileName());
	if (filepath==".")
		filepath="";
	else
		filepath.append("/");

	// read file into memory
	SMyFileHeader fileHeader;
	file->read(&fileHeader, sizeof(SMyFileHeader));
#ifdef __BIG_ENDIAN__
	fileHeader.MyId = os::Byteswap::byteswap(fileHeader.MyId);
	fileHeader.Ver = os::Byteswap::byteswap(fileHeader.Ver);
#endif

	if (fileHeader.MyId!=MY3D_ID || fileHeader.Ver!=MY3D_VER)
	{
		os::Printer::log("Bad MY3D file header, loading failed!", ELL_ERROR);
		return 0;
	}

	u16 id;

	file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
	id = os::Byteswap::byteswap(id);
#endif

	if (id!=MY3D_SCENE_HEADER_ID)
	{
		os::Printer::log("Cannot find MY3D_SCENE_HEADER_ID, loading failed!", ELL_ERROR);
		return 0;
	}

	SMySceneHeader sceneHeader;
	file->read(&sceneHeader, sizeof(SMySceneHeader));
#ifdef __BIG_ENDIAN__
	sceneHeader.MaterialCount = os::Byteswap::byteswap(sceneHeader.MaterialCount);
	sceneHeader.MeshCount = os::Byteswap::byteswap(sceneHeader.MeshCount);
#endif

	file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
	id = os::Byteswap::byteswap(id);
#endif

	if (id!=MY3D_MAT_LIST_ID)
	{
		os::Printer::log("Can not find MY3D_MAT_LIST_ID, loading failed!", ELL_ERROR);
		return 0;
	}

	core::stringc texturePath =
		SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH);

	file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
	id = os::Byteswap::byteswap(id);
#endif

	c8 namebuf[256];
	for (s32 m=0; m<sceneHeader.MaterialCount; ++m)
	{
		if (id != MY3D_MAT_HEADER_ID)
		{
			os::Printer::log("Cannot find MY3D_MAT_HEADER_ID, loading failed!", ELL_ERROR);
			return 0;
		}

		// read material header
		MaterialEntry.push_back(SMyMaterialEntry());
		SMyMaterialEntry& me=MaterialEntry.getLast();
		file->read(&(me.Header), sizeof(SMyMaterialHeader));

		// read next identificator
		file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
		id = os::Byteswap::byteswap(id);
#endif

		bool gotLightMap=false, gotMainMap=false;

		for (u32 t=0; t<me.Header.TextureCount; ++t)
		{
			if (id==MY3D_TEX_FNAME_ID)
				file->read(namebuf, 256);
			else
			{
				me.Texture2 = readEmbeddedLightmap(file, namebuf);
				if (!me.Texture2)
					return 0;
				gotLightMap = true;
			}

			const core::stringc name(namebuf);
			const s32 pos = name.findLast('.');
			const core::stringc LightingMapStr = "LightingMap";
			const s32 ls = LightingMapStr.size();
			const bool isSubString = (LightingMapStr == name.subString(core::max_(0, (pos - ls)), ls));
			if ((isSubString || (name[pos-1]=='m' &&
				name[pos-2]=='l' && name[pos-3]=='_')) &&
				!gotLightMap)
			{
				const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
				SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

				me.Texture2FileName = texturePath.size() ? texturePath : filepath;
				me.Texture2FileName.append("Lightmaps/");
				me.Texture2FileName.append(name);

				if (name.size())
					me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName);

				me.MaterialType = video::EMT_LIGHTMAP_M2;
				gotLightMap = true;

				SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
			}
			else
			if (!gotLightMap && gotMainMap)
			{
				me.Texture2FileName = texturePath.size() ? texturePath : filepath;
				me.Texture2FileName.append(name);

				if (name.size())
					me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName);

				me.MaterialType = video::EMT_REFLECTION_2_LAYER;
			}
			else
			if (!gotMainMap && !gotLightMap)
			{
				me.Texture1FileName = filepath;
				me.Texture1FileName.append(name);
				if (name.size())
					me.Texture1 = SceneManager->getVideoDriver()->getTexture(me.Texture1FileName);

				gotMainMap = true;
				me.MaterialType = video::EMT_SOLID;
			}
			else
			if (gotLightMap)
			{
				me.MaterialType = video::EMT_LIGHTMAP_M2;
			}

			file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
			id = os::Byteswap::byteswap(id);
#endif
		}

		// override material types based on their names
		if (!strncmp(me.Header.Name, "AlphaChannel-", 13))
			me.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
		else
		if (!strncmp(me.Header.Name, "SphereMap-", 10))
			me.MaterialType = video::EMT_SPHERE_MAP;
	}

	// loading meshes

	if (id!=MY3D_MESH_LIST_ID)
	{
		os::Printer::log("Can not find MY3D_MESH_LIST_ID, loading failed!", ELL_ERROR);
		return 0;
	}

	file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
	id = os::Byteswap::byteswap(id);
#endif

	for (s32 mesh_id=0; mesh_id<sceneHeader.MeshCount; mesh_id++)
	{
		// Warning!!! In some cases MY3D exporter uncorrectly calculates
		// MeshCount (it's a problem, has to be solved) thats why
		// i added this code line
		if (id!=MY3D_MESH_HEADER_ID)
			break;

		if (id!=MY3D_MESH_HEADER_ID)
		{
			os::Printer::log("Can not find MY3D_MESH_HEADER_ID, loading failed!", ELL_ERROR);
			return 0;
		}

		SMyMeshHeader meshHeader;
		file->read(&meshHeader, sizeof(SMyMeshHeader));

		core::array <SMyVertex> Vertex;
		core::array <SMyFace> Face;
		core::array <SMyTVertex> TVertex1, TVertex2;
		core::array <SMyFace> TFace1, TFace2;

		s32 vertsNum=0;
		s32 facesNum=0;

		// vertices
		file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
	id = os::Byteswap::byteswap(id);
#endif
		if (id!=MY3D_VERTS_ID)
		{
			os::Printer::log("Can not find MY3D_VERTS_ID, loading failed!", ELL_ERROR);
			return 0;
		}

		file->read(&vertsNum, sizeof(vertsNum));
		Vertex.set_used(vertsNum);
		file->read(Vertex.pointer(), sizeof(SMyVertex)*vertsNum);

		// faces
		file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
		id = os::Byteswap::byteswap(id);
#endif
		if (id!=MY3D_FACES_ID)
		{
			os::Printer::log("Can not find MY3D_FACES_ID, loading failed!", ELL_ERROR);
			return 0;
		}

		file->read(&facesNum, sizeof(facesNum));
		Face.set_used(facesNum);
		file->read(Face.pointer(), sizeof(SMyFace)*facesNum);

		// reading texture channels
		for (s32 tex=0; tex<(s32)meshHeader.TChannelCnt; tex++)
		{
			// Max 2 texture channels allowed (but in format .my3d can be more)
			s32 tVertsNum=0, tFacesNum=0;

			// reading texture coords
			file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
			id = os::Byteswap::byteswap(id);
#endif

			if (id!=MY3D_TVERTS_ID)
			{
				core::stringc msg="Can not find MY3D_TVERTS_ID (";
				msg.append(core::stringc(tex));
				msg.append("texture channel), loading failed!");
				os::Printer::log(msg.c_str(), ELL_ERROR);
				return 0;
			}

			file->read(&tVertsNum, sizeof(tVertsNum));

			if (tex==0)
			{
				// 1st texture channel
				TVertex1.set_used(tVertsNum);
				file->read(TVertex1.pointer(), sizeof(SMyTVertex)*tVertsNum);
			}
			else
			if (tex==1)
			{
				// 2nd texture channel
				TVertex2.set_used(tVertsNum);
				file->read(TVertex2.pointer(), sizeof(SMyTVertex)*tVertsNum);
			}
			else
			{
				// skip other texture channels
				file->seek(file->getPos()+sizeof(SMyTVertex)*tVertsNum);
			}

			// reading texture faces
			file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
			id = os::Byteswap::byteswap(id);
#endif

			if (id!=MY3D_TFACES_ID)
			{
				core::stringc msg="Can not find MY3D_TFACES_ID (";
				msg.append(core::stringc(tex));
				msg.append("texture channel), loading failed!");
				os::Printer::log(msg.c_str(), ELL_ERROR);
				return 0;
			}

			file->read(&tFacesNum, sizeof(tFacesNum));

			if (tex==0)
			{
				// 1st texture channel
				TFace1.set_used(tFacesNum);
				file->read(TFace1.pointer(), sizeof(SMyFace)*tFacesNum);
			}
			else if (tex==1)
			{
				// 2nd texture channel
				TFace2.set_used(tFacesNum);
				file->read(TFace2.pointer(), sizeof(SMyFace)*tFacesNum);
			}
			else
			{
				// skip other texture channels
				file->seek(file->getPos()+sizeof(SMyFace)*tFacesNum);
			}
		}

		// trying to find material

		SMyMaterialEntry* matEnt = getMaterialEntryByIndex(meshHeader.MatIndex);

		// creating geometry for the mesh

		// trying to find mesh buffer for this material
		CMeshBuffer<video::S3DVertex2TCoords>* buffer = getMeshBufferByMaterialIndex(meshHeader.MatIndex);

		if (!buffer ||
			(buffer->getVertexBuffer()->getVertexCount()+vertsNum) > SceneManager->getVideoDriver()->getMaximalPrimitiveCount())
		{
			// creating new mesh buffer for this material
			buffer = new CMeshBuffer<video::S3DVertex2TCoords>(SceneManager->getVideoDriver()->getVertexDescriptor(1));

			buffer->Material.MaterialType = video::EMT_LIGHTMAP_M2; // EMT_LIGHTMAP_M4 also possible
			buffer->Material.Wireframe = false;
			buffer->Material.Lighting = false;

			if (matEnt)
			{
				buffer->Material.MaterialType = matEnt->MaterialType;

				if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER)
				{
					buffer->Material.Lighting = true;
					buffer->Material.setTexture(1, matEnt->Texture1);
					buffer->Material.setTexture(0, matEnt->Texture2);
				}
				else
				{
					buffer->Material.setTexture(0, matEnt->Texture1);
					buffer->Material.setTexture(1, matEnt->Texture2);
				}

				if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
				{
					buffer->Material.BackfaceCulling = true;
					buffer->Material.Lighting  = true;
				}
				else
				if (buffer->Material.MaterialType == video::EMT_SPHERE_MAP)
				{
					buffer->Material.Lighting  = true;
				}

				buffer->Material.AmbientColor = video::SColor(
					matEnt->Header.AmbientColor.A, matEnt->Header.AmbientColor.R,
					matEnt->Header.AmbientColor.G, matEnt->Header.AmbientColor.B
					);
				buffer->Material.DiffuseColor =	video::SColor(
					matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R,
					matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B
					);
				buffer->Material.EmissiveColor = video::SColor(
					matEnt->Header.EmissiveColor.A, matEnt->Header.EmissiveColor.R,
					matEnt->Header.EmissiveColor.G, matEnt->Header.EmissiveColor.B
					);
				buffer->Material.SpecularColor = video::SColor(
					matEnt->Header.SpecularColor.A, matEnt->Header.SpecularColor.R,
					matEnt->Header.SpecularColor.G, matEnt->Header.SpecularColor.B
					);
			}
			else
			{
				buffer->Material.setTexture(0, 0);
				buffer->Material.setTexture(1, 0);

				buffer->Material.AmbientColor = video::SColor(255, 255, 255, 255);
				buffer->Material.DiffuseColor =	video::SColor(255, 255, 255, 255);
				buffer->Material.EmissiveColor = video::SColor(0, 0, 0, 0);
				buffer->Material.SpecularColor = video::SColor(0, 0, 0, 0);
			}

			if (matEnt && matEnt->Header.Transparency!=0)
			{
				if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER )
				{
					buffer->Material.MaterialType = video::EMT_TRANSPARENT_REFLECTION_2_LAYER;
					buffer->Material.Lighting  = true;
					buffer->Material.BackfaceCulling = true;
				}
				else
				{
					buffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
					buffer->Material.Lighting = false;
					buffer->Material.BackfaceCulling = false;
				}
			}
			else if (
				!buffer->Material.getTexture(1) &&
				buffer->Material.MaterialType != video::EMT_TRANSPARENT_ALPHA_CHANNEL &&
				buffer->Material.MaterialType != video::EMT_SPHERE_MAP)
			{
				buffer->Material.MaterialType = video::EMT_SOLID;
				buffer->Material.Lighting  = true;
			}

			MeshBufferEntry.push_back(
			SMyMeshBufferEntry(meshHeader.MatIndex, buffer));
		}

		video::S3DVertex2TCoords VertexA, VertexB, VertexC;

		// vertices (A, B, C) color
		video::SColor vert_color;
		if (matEnt &&
			(buffer->Material.MaterialType == video::EMT_TRANSPARENT_VERTEX_ALPHA ||
			buffer->Material.MaterialType == video::EMT_TRANSPARENT_REFLECTION_2_LAYER))
		{
			video::SColor color(
			matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R,
			matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B);

			vert_color = color.getInterpolated(video::SColor(0,0,0,0),
				1-matEnt->Header.Transparency);
		}
		else
		{
			vert_color = buffer->Material.DiffuseColor;
		}

		VertexA.Color = VertexB.Color = VertexC.Color = vert_color;

		if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
		{
			buffer->getIndexBuffer()->reallocate(buffer->getIndexBuffer()->getIndexCount()+6*facesNum);
			buffer->getVertexBuffer()->reallocate(buffer->getVertexBuffer()->getVertexCount()+6*facesNum);
		}
		else
		{
			buffer->getIndexBuffer()->reallocate(buffer->getIndexBuffer()->getIndexCount()+3*facesNum);
			buffer->getVertexBuffer()->reallocate(buffer->getVertexBuffer()->getVertexCount()+3*facesNum);
		}
		for (int f=0; f<facesNum; f++)
		{
			// vertex A

			VertexA.Pos.X = Vertex[Face[f].C].Coord.X;
			VertexA.Pos.Y = Vertex[Face[f].C].Coord.Y;
			VertexA.Pos.Z = Vertex[Face[f].C].Coord.Z;

			VertexA.Normal.X = Vertex[Face[f].C].Normal.X;
			VertexA.Normal.Y = Vertex[Face[f].C].Normal.Y;
			VertexA.Normal.Z = Vertex[Face[f].C].Normal.Z;

			if (meshHeader.TChannelCnt>0)
			{
				VertexA.TCoords.X  = TVertex1[TFace1[f].C].TCoord.X;
				VertexA.TCoords.Y  = TVertex1[TFace1[f].C].TCoord.Y;
			}

			if (meshHeader.TChannelCnt>1)
			{
				VertexA.TCoords2.X = TVertex2[TFace2[f].C].TCoord.X;
				VertexA.TCoords2.Y = TVertex2[TFace2[f].C].TCoord.Y;
			}

			// vertex B

			VertexB.Pos.X = Vertex[Face[f].B].Coord.X;
			VertexB.Pos.Y = Vertex[Face[f].B].Coord.Y;
			VertexB.Pos.Z = Vertex[Face[f].B].Coord.Z;

			VertexB.Normal.X = Vertex[Face[f].B].Normal.X;
			VertexB.Normal.Y = Vertex[Face[f].B].Normal.Y;
			VertexB.Normal.Z = Vertex[Face[f].B].Normal.Z;

			if (meshHeader.TChannelCnt>0)
			{
				VertexB.TCoords.X  = TVertex1[TFace1[f].B].TCoord.X;
				VertexB.TCoords.Y  = TVertex1[TFace1[f].B].TCoord.Y;
			}

			if (meshHeader.TChannelCnt>1)
			{
				VertexB.TCoords2.X = TVertex2[TFace2[f].B].TCoord.X;
				VertexB.TCoords2.Y = TVertex2[TFace2[f].B].TCoord.Y;
			}

			// vertex C

			VertexC.Pos.X = Vertex[Face[f].A].Coord.X;
			VertexC.Pos.Y = Vertex[Face[f].A].Coord.Y;
			VertexC.Pos.Z = Vertex[Face[f].A].Coord.Z;

			VertexC.Normal.X = Vertex[Face[f].A].Normal.X;
			VertexC.Normal.Y = Vertex[Face[f].A].Normal.Y;
			VertexC.Normal.Z = Vertex[Face[f].A].Normal.Z;

			if (meshHeader.TChannelCnt>0)
			{
				VertexC.TCoords.X  = TVertex1[TFace1[f].A].TCoord.X;
				VertexC.TCoords.Y  = TVertex1[TFace1[f].A].TCoord.Y;
			}
			if (meshHeader.TChannelCnt>1)
			{
				VertexC.TCoords2.X = TVertex2[TFace2[f].A].TCoord.X;
				VertexC.TCoords2.Y = TVertex2[TFace2[f].A].TCoord.Y;
			}

			// store 3d data in mesh buffer

			buffer->getIndexBuffer()->addIndex(buffer->getVertexBuffer()->getVertexCount());
			buffer->getVertexBuffer()->addVertex(&VertexA);

			buffer->getIndexBuffer()->addIndex(buffer->getVertexBuffer()->getVertexCount());
			buffer->getVertexBuffer()->addVertex(&VertexB);

			buffer->getIndexBuffer()->addIndex(buffer->getVertexBuffer()->getVertexCount());
			buffer->getVertexBuffer()->addVertex(&VertexC);

			//*****************************************************************
			//          !!!!!! W A R N I N G !!!!!!!
			//*****************************************************************
			// For materials with alpha channel we duplicate all faces.
			// This has be done for proper lighting calculation of the back faces.
			// So you must remember this while you creating your models !!!!!
			//*****************************************************************
			//          !!!!!! W A R N I N G !!!!!!!
			//*****************************************************************

			if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
			{
				VertexA.Normal = core::vector3df(-VertexA.Normal.X, -VertexA.Normal.Y, -VertexA.Normal.Z);
				VertexB.Normal = core::vector3df(-VertexB.Normal.X, -VertexB.Normal.Y, -VertexB.Normal.Z);
				VertexC.Normal = core::vector3df(-VertexC.Normal.X, -VertexC.Normal.Y, -VertexC.Normal.Z);

				buffer->getIndexBuffer()->addIndex(buffer->getVertexBuffer()->getVertexCount());
				buffer->getVertexBuffer()->addVertex(&VertexC);

				buffer->getIndexBuffer()->addIndex(buffer->getVertexBuffer()->getVertexCount());
				buffer->getVertexBuffer()->addVertex(&VertexB);

				buffer->getIndexBuffer()->addIndex(buffer->getVertexBuffer()->getVertexCount());
				buffer->getVertexBuffer()->addVertex(&VertexA);
			}
		}
		file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
		id = os::Byteswap::byteswap(id);
#endif
	}

	// creating mesh
	SMesh* mesh = new SMesh();

	for (u32 num=0; num<MeshBufferEntry.size(); ++num)
	{
		CMeshBuffer<video::S3DVertex2TCoords>* buffer = MeshBufferEntry[num].MeshBuffer;

		if (!buffer)
			continue;

		mesh->addMeshBuffer(buffer);

		buffer->recalculateBoundingBox();
		buffer->drop();
	}

	mesh->recalculateBoundingBox();

	if (id != MY3D_FILE_END_ID)
		os::Printer::log("Loading finished, but can not find MY3D_FILE_END_ID token.", ELL_WARNING);

	SAnimatedMesh* am = new SAnimatedMesh();

	am->addMesh(mesh);
	mesh->drop();
	am->recalculateBoundingBox();

	return am;
}
bool CSTLMeshWriter::writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	// write STL MESH header

	file->write("binary ",7);
	const core::stringc name(SceneManager->getMeshCache()->getMeshFilename(mesh));
	const s32 sizeleft = 73-name.size(); // 80 byte header
	if (sizeleft<0)
		file->write(name.c_str(),73);
	else
	{
		char* buf = new char[80];
		memset(buf, 0, 80);
		file->write(name.c_str(),name.size());
		file->write(buf,sizeleft);
		delete [] buf;
	}
	u32 facenum = 0;
	for (u32 j=0; j<mesh->getMeshBufferCount(); ++j)
		facenum += mesh->getMeshBuffer(j)->getIndexCount()/3;
	file->write(&facenum,4);

	// write mesh buffers

	for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
	{
		IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if (buffer)
		{
			const u16 indexCount = buffer->getIndexCount();

			switch(buffer->getVertexType())
			{
			case video::EVT_STANDARD:
				{
					video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
					const u16 attributes = 0;
					for (u32 j=0; j<indexCount; j+=3)
					{
						file->write(&core::plane3df(vtx[buffer->getIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos).Normal, 12);
						file->write(&vtx[buffer->getIndices()[j]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12);
						file->write(&attributes, 2);
					}
				}
				break;
			case video::EVT_2TCOORDS:
				{
					video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
					const u16 attributes = 0;
					for (u32 j=0; j<indexCount; j+=3)
					{
						file->write(&core::plane3df(vtx[buffer->getIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos).Normal, 12);
						file->write(&vtx[buffer->getIndices()[j]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12);
						file->write(&attributes, 2);
					}
				}
				break;
			case video::EVT_TANGENTS:
				{
					video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
					const u16 attributes = 0;
					for (u32 j=0; j<indexCount; j+=3)
					{
						file->write(&core::plane3df(vtx[buffer->getIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos).Normal, 12);
						file->write(&vtx[buffer->getIndices()[j]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12);
						file->write(&attributes, 2);
					}
				}
				break;
			}
		}
	}
	return true;
}
Exemple #20
0
//! PreProcesses a shader using Irrlicht's built-in shader preprocessor.
core::stringc CShaderPreprocessor::ppShader(core::stringc shaderProgram)
{
	core::array<SDefineExp> DefineArray = grabDefineExpressions(shaderProgram);

	// No need for this as its already inited at startup.
	//// If DefineMap is empty then initialize it.
	//if(DefineMap.isEmpty())
	//	initDefineMap();

	for(u32 i = 0; i < DefineArray.size();++i)
	{
		if(DefineArray[i].IfPos == -1)
			break;
	
		// Either it is true and not inversed, or it is false, but inversed. 
		// (Wish C++ had a built-in (logical) XOR operator sometimes. :P) 
		if((DefineMap.find(DefineArray[i].IfExp) && !DefineArray[i].Inverse) 
		|| (!DefineMap.find(DefineArray[i].IfExp) && DefineArray[i].Inverse))
		{
			if(DefineArray[i].ElsePos > -1)
			{
				// If there is an else statement then clear the else section.
				if(DefineArray[i].EndPos != -1)
				{
					for(int z = DefineArray[i].ElsePos;z <= DefineArray[i].EndPos + 6;++z)
						shaderProgram[z] = ' ';
				}
			}
		}
		else if(DefineArray[i].ElsePos != -1)
		{
			// If there is an else statement then clear the if section.
			for(int z = DefineArray[i].IfPos;z <= DefineArray[i].ElsePos + 5;++z)
				shaderProgram[z] = ' ';
		}
		else
		{
			// Else just clear the whole block.
			if(DefineArray[i].EndPos != -1)
			{
				for(int z = DefineArray[i].IfPos;z <= DefineArray[i].EndPos + 6;++z)
					shaderProgram[z] = ' ';
			}
		}
	}

	core::map<core::stringc,core::stringc>::ParentFirstIterator DefIter;
	s32 DefFinder = 1;

	// Replace all shader defines.
	for(DefIter = DefineMap.getParentFirstIterator();!DefIter.atEnd();DefIter++)
	{
		if(DefIter->getValue().size() == 0)
			continue;

		// Replace all occurances.
		while((DefFinder = shaderProgram.find(DefIter->getKey().c_str())) > -1)
		{
			// Clear the define from the code.
			for(u32 z = DefFinder;z < DefFinder + DefIter->getKey().size();++z)
				shaderProgram[z] = ' ';

			// Stitch value and shader program together. (Is there a faster way?)
			shaderProgram = shaderProgram.subString(0,DefFinder) + DefIter->getValue() 
					+ shaderProgram.subString(DefFinder,shaderProgram.size() - 1);
		}
	}

	return shaderProgram;
}
effectHandler::effectHandler(IrrlichtDevice* dev, dimension2d<u32> mapSize, core::stringc shaderFolder, irr::core::dimension2d<irr::u32> screenRTTSize)
: device(dev), smgr(dev->getSceneManager()), driver(dev->getVideoDriver()),
ScreenRTTSize((screenRTTSize == dimension2d<u32>(0,0)) ? dev->getVideoDriver()->getScreenSize() : screenRTTSize),
ClearColour(0x0), shadowsUnsupported(false), DepthRTT(0), DepthPass(false), depthMC(0), shadowMC(0),
AmbientColour(0x0)
{
	CShaderPreprocessor sPP(driver);
	sPP.addShaderDefine("MAPRES", core::stringc(mapSize.Height));
	
	bool tempTexFlagMipMaps = driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
	bool tempTexFlag32 = driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT);

	ShadowMapTex = driver->addRenderTargetTexture(mapSize);
	ScreenRTT = driver->addRenderTargetTexture(ScreenRTTSize);
	ScreenQuad.rt[0] = driver->addRenderTargetTexture(ScreenRTTSize);
	ScreenQuad.rt[1] = driver->addRenderTargetTexture(ScreenRTTSize);

	driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, tempTexFlagMipMaps);
	driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT, tempTexFlag32);

	stringc platformExt = (driver->getDriverType() == EDT_DIRECT3D9) ? ".hlsl" : ".glsl";

	if(shaderFolder.size() > 0 && shaderFolder[shaderFolder.size() - 1] != '/')
		shaderFolder += "/";

	// For shadows
	stringc DFNV = shaderFolder + stringc("ShadowPass1V") + platformExt;
	stringc DFNP = shaderFolder + stringc("ShadowPass1P") + platformExt;
	stringc WFNP = shaderFolder + stringc("WhiteWashP") + platformExt;

	stringc SDFNV = shaderFolder + stringc("ShadowPass2V") + platformExt;
	stringc SDFNP = shaderFolder + stringc("ShadowPass2P") + platformExt;
	
	stringc GOOCHV = shaderFolder + stringc("ShaderGoochPtV") + platformExt;
	stringc WIGGLEV = shaderFolder + stringc("ShaderMrWiggleV") + platformExt;
	stringc DEPTHWIGGLEV = shaderFolder + stringc("ShaderDepthWiggleV") + platformExt;
	stringc ANISOV = shaderFolder + stringc("ShaderAnisoV") + platformExt;
	stringc PHONGV = shaderFolder + stringc("ShaderPhongV") + platformExt;
	stringc BRDFV = shaderFolder + stringc("ShaderBRDFV") + platformExt;

	stringc GOOCHP = shaderFolder + stringc("ShaderGoochPtP") + platformExt;
	stringc WIGGLEP = shaderFolder + stringc("ShaderMrWiggleP") + platformExt;
	stringc ANISOP = shaderFolder + stringc("ShaderAnisoP") + platformExt;
	stringc PHONGP = shaderFolder + stringc("ShaderPhongP") + platformExt;
	stringc BRDFP = shaderFolder + stringc("ShaderBRDFP") + platformExt;

	video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
	
	if(gpu && ((driver->getDriverType() == EDT_OPENGL && driver->queryFeature(EVDF_ARB_GLSL)) ||
			   (driver->getDriverType() == EDT_DIRECT3D9 && driver->queryFeature(EVDF_PIXEL_SHADER_1_4))))
	{
			BRDFShaderCB* mc4 = new BRDFShaderCB(this);
			LightShaderCB* mc5 = new LightShaderCB(this);
			WiggleShaderCB* mc6 = new WiggleShaderCB(this);
			AnisoShaderCB* mc8 = new AnisoShaderCB(this);
			PhongShaderCB* mc9 = new PhongShaderCB(this);

			Effects[EET_BRDF] = gpu->addHighLevelShaderMaterialFromFiles(
				BRDFV.c_str(), "vertexMain", video::EVST_VS_1_1,
				BRDFP.c_str(), "pixelMain", video::EPST_PS_1_4,
				mc4, video::EMT_SOLID);

			Effects[EET_GOOCH] = gpu->addHighLevelShaderMaterialFromFiles(
				GOOCHV.c_str(),	"vertexMain", video::EVST_VS_1_1,
				GOOCHP.c_str(), "pixelMain", video::EPST_PS_1_4,
				mc5, video::EMT_SOLID);

			Effects[EET_MRWIGGLE] = gpu->addHighLevelShaderMaterialFromFiles(
				WIGGLEV.c_str(), "vertexMain", video::EVST_VS_1_1,
				WIGGLEP.c_str(), "pixelMain", video::EPST_PS_1_4,
				mc6, video::EMT_SOLID);

			Effects[EET_ANISO] = gpu->addHighLevelShaderMaterialFromFiles(
				ANISOV.c_str(),	"vertexMain", video::EVST_VS_1_1,
				ANISOP.c_str(), "pixelMain", video::EPST_PS_1_4,
				mc8, video::EMT_SOLID);

			Effects[EET_PHONG] = gpu->addHighLevelShaderMaterialFromFiles(
				PHONGV.c_str(),	"vertexMain", video::EVST_VS_1_1,
				PHONGP.c_str(), "pixelMain", video::EPST_PS_1_4,
				mc9, video::EMT_SOLID);

			if(driver->queryFeature(EVDF_PIXEL_SHADER_2_0) || driver->getDriverType() == EDT_OPENGL)
			{
				depthMC = new DepthShaderCB(this);
				shadowMC = new ShadowShaderCB(this);

				Depth = gpu->addHighLevelShaderMaterialFromFiles(
					DFNV.c_str(), "vertexMain", video::EVST_VS_2_0,
					DFNP.c_str(), "pixelMain", video::EPST_PS_2_0,
					depthMC, video::EMT_SOLID);
				
				DepthWiggle = gpu->addHighLevelShaderMaterialFromFiles(
					DEPTHWIGGLEV.c_str(), "vertexMain", video::EVST_VS_2_0,
					DFNP.c_str(), "pixelMain", video::EPST_PS_2_0,
					depthMC, video::EMT_SOLID);

				WhiteWash = gpu->addHighLevelShaderMaterialFromFiles(
					DFNV.c_str(), "vertexMain", video::EVST_VS_2_0,
					WFNP.c_str(), "pixelMain", video::EPST_PS_2_0,
					depthMC, video::EMT_SOLID);

				sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(1));
				Solid[EFT_NONE] = gpu->addHighLevelShaderMaterial(
					sPP.ppShaderFF(SDFNV).c_str(),	"vertexMain", video::EVST_VS_2_0,
					sPP.ppShaderFF(SDFNP).c_str(), "pixelMain", video::EPST_PS_2_0,
					shadowMC, video::EMT_SOLID);

				sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(4));
				Solid[EFT_4PCF] = gpu->addHighLevelShaderMaterial(
					sPP.ppShaderFF(SDFNV).c_str(),	"vertexMain", video::EVST_VS_2_0,
					sPP.ppShaderFF(SDFNP).c_str(), "pixelMain", video::EPST_PS_2_0,
					shadowMC, video::EMT_SOLID);

				sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(8));
				Solid[EFT_8PCF] = gpu->addHighLevelShaderMaterial(
					sPP.ppShaderFF(SDFNV).c_str(),	"vertexMain", video::EVST_VS_2_0,
					sPP.ppShaderFF(SDFNP).c_str(), "pixelMain", video::EPST_PS_2_0,
					shadowMC, video::EMT_SOLID);

				sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(12));
				if(driver->queryFeature(EVDF_PIXEL_SHADER_3_0) || driver->getDriverType() == EDT_OPENGL)
				Solid[EFT_12PCF] = gpu->addHighLevelShaderMaterial(
					sPP.ppShaderFF(SDFNV).c_str(),	"vertexMain", video::EVST_VS_3_0,
					sPP.ppShaderFF(SDFNP).c_str(), "pixelMain", video::EPST_PS_3_0,
					shadowMC, video::EMT_SOLID);
				else
					Solid[EFT_12PCF] = Solid[EFT_8PCF];

				sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(16));
				if(driver->queryFeature(EVDF_PIXEL_SHADER_3_0) || driver->getDriverType() == EDT_OPENGL)
				Solid[EFT_16PCF] = gpu->addHighLevelShaderMaterial(
					sPP.ppShaderFF(SDFNV).c_str(),	"vertexMain", video::EVST_VS_3_0,
					sPP.ppShaderFF(SDFNP).c_str(), "pixelMain", video::EPST_PS_3_0,
					shadowMC, video::EMT_SOLID);
				else
					Solid[EFT_16PCF] = Solid[EFT_8PCF];

				// Light modulate.
				LightModulate = obtainScreenQuadMaterialFromFile(
					shaderFolder + stringc("LightModulate") + platformExt);

				// Simple present.
				Simple = obtainScreenQuadMaterialFromFile(
					shaderFolder + stringc("SimpleP") + platformExt, EMT_TRANSPARENT_ADD_COLOR);
			}
			else
			{
				Depth = EMT_SOLID;
				DepthWiggle = EMT_SOLID;
				WhiteWash = EMT_SOLID;

				for(u32 i = 0;i < EFT_COUNT;++i)
					Solid[i] = EMT_SOLID;

				device->getLogger()->log("XEffects: Shadow maps not supported on this system.");
				shadowsUnsupported = true;
			}

			mc4->drop();
			mc5->drop();
			mc6->drop();
			mc8->drop();
			mc9->drop();
	}
	else
	{
		Depth = EMT_SOLID;
		DepthWiggle = EMT_SOLID;
		WhiteWash = EMT_SOLID;

		for(u32 i = 0;i < EFT_COUNT;++i)
			Solid[i] = EMT_SOLID;

		for(u32 i = 0;i < EET_COUNT;++i)
			Effects[i] = EMT_SOLID;
		
		device->getLogger()->log("XEffects: Shadow maps not supported on this system.");
		device->getLogger()->log("XEffects: Effects not supported on this system.");
	}
}
Exemple #22
0
//! writes a mesh
bool COBJMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	if (!file)
		return false;

	os::Printer::log("Writing mesh", file->getFileName());

	// write OBJ MESH header

	const core::stringc name(FileSystem->getFileBasename(SceneManager->getMeshCache()->getMeshName(mesh), false)+".mtl");
	file->write("# exported by Irrlicht\n",23);
	file->write("mtllib ",7);
	file->write(name.c_str(),name.size());
	file->write("\n\n",2);

	// write mesh buffers

	core::array<video::SMaterial*> mat;

	u32 allVertexCount=1; // count vertices over the whole file
	for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
	{
		core::stringc num(i+1);
		IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if (buffer && buffer->getVertexCount())
		{
			file->write("g grp", 5);
			file->write(num.c_str(), num.size());
			file->write("\n",1);

			u32 j;
			const u32 vertexCount = buffer->getVertexCount();
			for (j=0; j<vertexCount; ++j)
			{
				file->write("v ",2);
				getVectorAsStringLine(buffer->getPosition(j), num);
				file->write(num.c_str(), num.size());
			}

			for (j=0; j<vertexCount; ++j)
			{
				file->write("vt ",3);
				getVectorAsStringLine(buffer->getTCoords(j), num);
				file->write(num.c_str(), num.size());
			}

			for (j=0; j<vertexCount; ++j)
			{
				file->write("vn ",3);
				getVectorAsStringLine(buffer->getNormal(j), num);
				file->write(num.c_str(), num.size());
			}

			file->write("usemtl mat",10);
			num = "";
			for (j=0; j<mat.size(); ++j)
			{
				if (*mat[j]==buffer->getMaterial())
				{
					num = core::stringc(j);
					break;
				}
			}
			if (num == "")
			{
				num = core::stringc(mat.size());
				mat.push_back(&buffer->getMaterial());
			}
			file->write(num.c_str(), num.size());
			file->write("\n",1);

			const u32 indexCount = buffer->getIndexCount();
			for (j=0; j<indexCount; j+=3)
			{
				file->write("f ",2);
				num = core::stringc(buffer->getIndices()[j+2]+allVertexCount);
				file->write(num.c_str(), num.size());
				file->write("/",1);
				file->write(num.c_str(), num.size());
				file->write("/",1);
				file->write(num.c_str(), num.size());
				file->write(" ",1);

				num = core::stringc(buffer->getIndices()[j+1]+allVertexCount);
				file->write(num.c_str(), num.size());
				file->write("/",1);
				file->write(num.c_str(), num.size());
				file->write("/",1);
				file->write(num.c_str(), num.size());
				file->write(" ",1);

				num = core::stringc(buffer->getIndices()[j+0]+allVertexCount);
				file->write(num.c_str(), num.size());
				file->write("/",1);
				file->write(num.c_str(), num.size());
				file->write("/",1);
				file->write(num.c_str(), num.size());
				file->write(" ",1);

				file->write("\n",1);
			}
			file->write("\n",1);
			allVertexCount += vertexCount;
		}
	}

	if (mat.size() == 0)
		return true;

	file = FileSystem->createAndWriteFile( name );
	if (file)
	{
		os::Printer::log("Writing material", file->getFileName());

		file->write("# exported by Irrlicht\n\n",24);
		for (u32 i=0; i<mat.size(); ++i)
		{
			core::stringc num(i);
			file->write("newmtl mat",10);
			file->write(num.c_str(),num.size());
			file->write("\n",1);

			getColorAsStringLine(mat[i]->AmbientColor, "Ka", num);
			file->write(num.c_str(),num.size());
			getColorAsStringLine(mat[i]->DiffuseColor, "Kd", num);
			file->write(num.c_str(),num.size());
			getColorAsStringLine(mat[i]->SpecularColor, "Ks", num);
			file->write(num.c_str(),num.size());
			getColorAsStringLine(mat[i]->EmissiveColor, "Ke", num);
			file->write(num.c_str(),num.size());
			num = core::stringc(mat[i]->Shininess/0.128f);
			file->write("Ns ", 3);
			file->write(num.c_str(),num.size());
			file->write("\n", 1);
			if (mat[i]->getTexture(0))
			{
				file->write("map_Kd ", 7);
				file->write(mat[i]->getTexture(0)->getName().getPath().c_str(), mat[i]->getTexture(0)->getName().getPath().size());
				file->write("\n",1);
			}
			file->write("\n",1);
		}
		file->drop();
	}
	return true;
}