예제 #1
0
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size )
{
	ai_assert(!mSurfaces->empty());
	LWO::Surface& surf = mSurfaces->back();
	LWO::Texture tex;

	// load the texture header
	LoadLWO2TextureHeader(head->length,tex);
	size -= head->length + 6;

	// now get the exact type of the texture
	switch (head->type)
	{
	case AI_LWO_PROC:
		LoadLWO2Procedural(size,tex);
		break;
	case AI_LWO_GRAD:
		LoadLWO2Gradient(size,tex); 
		break;
	case AI_LWO_IMAP:
		LoadLWO2ImageMap(size,tex);
	}

	// get the destination channel
	TextureList* listRef = NULL;
	switch (tex.type)
	{
	case AI_LWO_COLR:
		listRef = &surf.mColorTextures;break;
	case AI_LWO_DIFF:
		listRef = &surf.mDiffuseTextures;break;
	case AI_LWO_SPEC:
		listRef = &surf.mSpecularTextures;break;
	case AI_LWO_GLOS:
		listRef = &surf.mGlossinessTextures;break;
	case AI_LWO_BUMP:
		listRef = &surf.mBumpTextures;break;
	case AI_LWO_TRAN:
		listRef = &surf.mOpacityTextures;break;
	case AI_LWO_REFL:
		listRef = &surf.mReflectionTextures;break;
	default:
		DefaultLogger::get()->warn("LWO2: Encountered unknown texture type");
		return;
	}

	// now attach the texture to the parent surface - sort by ordinal string
	for (TextureList::iterator it = listRef->begin();it != listRef->end(); ++it)	{
		if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0)	{
			listRef->insert(it,tex);
			return;
		}
	}
	listRef->push_back(tex);
}
예제 #2
0
//---------------------------------------------------------------------
void CompositorManager::freePooledTextures(bool onlyIfUnreferenced)
{
    if (onlyIfUnreferenced)
    {
        for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i)
        {
            TextureList* texList = i->second;
            for (TextureList::iterator j = texList->begin(); j != texList->end();)
            {
                // if the resource system, plus this class, are the only ones to have a reference..
                // NOTE: any material references will stop this texture getting freed (e.g. compositor demo)
                // until this routine is called again after the material no longer references the texture
                if (j->useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1)
                {
                    TextureManager::getSingleton().remove((*j)->getHandle());
                    j = texList->erase(j);
                }
                else
                    ++j;
            }
        }
        for (ChainTexturesByDef::iterator i = mChainTexturesByDef.begin(); i != mChainTexturesByDef.end(); ++i)
        {
            TextureDefMap& texMap = i->second;
            for (TextureDefMap::iterator j = texMap.begin(); j != texMap.end();) 
            {
                const TexturePtr& tex = j->second;
                if (tex.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1)
                {
                    TextureManager::getSingleton().remove(tex->getHandle());
                    texMap.erase(j++);
                }
                else
                    ++j;
            }
        }
    }
    else
    {
        // destroy all
        for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i)
        {
            OGRE_DELETE_T(i->second, TextureList, MEMCATEGORY_GENERAL);
        }
        mTexturesByDef.clear();
        mChainTexturesByDef.clear();
    }

}
예제 #3
0
//---------------------------------------------------------------------
TexturePtr CompositorManager::getPooledTexture(const String& name, 
    const String& localName,
    size_t w, size_t h, PixelFormat f, uint aa, const String& aaHint, bool srgb, 
    CompositorManager::UniqueTextureSet& texturesAssigned, 
    CompositorInstance* inst, CompositionTechnique::TextureScope scope)
{
    if (scope == CompositionTechnique::TS_GLOBAL) 
    {
        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
            "Global scope texture can not be pooled.",
            "CompositorManager::getPooledTexture");
    }

    TextureDef def(w, h, f, aa, aaHint, srgb);

    if (scope == CompositionTechnique::TS_CHAIN)
    {
        StringPair pair = std::make_pair(inst->getCompositor()->getName(), localName);
        TextureDefMap& defMap = mChainTexturesByDef[pair];
        TextureDefMap::iterator it = defMap.find(def);
        if (it != defMap.end())
        {
            return it->second;
        }
        // ok, we need to create a new one
        TexturePtr newTex = TextureManager::getSingleton().createManual(
            name, 
            ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 
            (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0,
            srgb, aa, aaHint);
        defMap.insert(TextureDefMap::value_type(def, newTex));
        return newTex;
    }

    TexturesByDef::iterator i = mTexturesByDef.find(def);
    if (i == mTexturesByDef.end())
    {
        TextureList* texList = OGRE_NEW_T(TextureList, MEMCATEGORY_GENERAL);
        i = mTexturesByDef.insert(TexturesByDef::value_type(def, texList)).first;
    }
    CompositorInstance* previous = inst->getChain()->getPreviousInstance(inst);
    CompositorInstance* next = inst->getChain()->getNextInstance(inst);

    TexturePtr ret;
    TextureList* texList = i->second;
    // iterate over the existing textures and check if we can re-use
    for (TextureList::iterator t = texList->begin(); t != texList->end(); ++t)
    {
        TexturePtr& tex = *t;
        // check not already used
        if (texturesAssigned.find(tex.get()) == texturesAssigned.end())
        {
            bool allowReuse = true;
            // ok, we didn't use this one already
            // however, there is an edge case where if we re-use a texture
            // which has an 'input previous' pass, and it is chained from another
            // compositor, we can end up trying to use the same texture for both
            // so, never allow a texture with an input previous pass to be 
            // shared with its immediate predecessor in the chain
            if (isInputPreviousTarget(inst, localName))
            {
                // Check whether this is also an input to the output target of previous
                // can't use CompositorInstance::mPreviousInstance, only set up
                // during compile
                if (previous && isInputToOutputTarget(previous, tex))
                    allowReuse = false;
            }
            // now check the other way around since we don't know what order they're bound in
            if (isInputToOutputTarget(inst, localName))
            {
                
                if (next && isInputPreviousTarget(next, tex))
                    allowReuse = false;
            }
            
            if (allowReuse)
            {
                ret = tex;
                break;
            }

        }
    }

    if (ret.isNull())
    {
        // ok, we need to create a new one
        ret = TextureManager::getSingleton().createManual(
            name, 
            ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 
            (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0,
            srgb, aa, aaHint); 

        texList->push_back(ret);

    }

    // record that we used this one in the requester's list
    texturesAssigned.insert(ret.get());


    return ret;
}
예제 #4
0
// ------------------------------------------------------------------------------------------------
bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type)
{
	ai_assert(NULL != pcMat);

	unsigned int cur = 0, temp = 0;
	aiString s;
	bool ret = false;

	for (TextureList::const_iterator it = in.begin(), end = in.end();it != end;++it)	{
		if (!(*it).enabled || !(*it).bCanUse)
			continue;
		ret = true;

		// Convert lightwave's mapping modes to ours. We let them
		// as they are, the GenUVcoords step will compute UV 
		// channels if they're not there.

		aiTextureMapping mapping;
		switch ((*it).mapMode)
		{
			case LWO::Texture::Planar:
				mapping = aiTextureMapping_PLANE;
				break;
			case LWO::Texture::Cylindrical:
				mapping = aiTextureMapping_CYLINDER;
				break;
			case LWO::Texture::Spherical:
				mapping = aiTextureMapping_SPHERE;
				break;
			case LWO::Texture::Cubic:
				mapping = aiTextureMapping_BOX;
				break;
			case LWO::Texture::FrontProjection:
				DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection");
				mapping = aiTextureMapping_OTHER;
				break;
			case LWO::Texture::UV:
				{
					if( UINT_MAX == (*it).mRealUVIndex )	{
						// We have no UV index for this texture, so we can't display it
						continue;
					}

					// add the UV source index
					temp = (*it).mRealUVIndex;
					pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_UVWSRC(type,cur));

					mapping = aiTextureMapping_UV;
				}
				break;
			default:
				ai_assert(false);
		};

		if (mapping != aiTextureMapping_UV)	{
			// Setup the main axis 
			aiVector3D v;
			switch ((*it).majorAxis)	{
				case Texture::AXIS_X:
					v = aiVector3D(1.f,0.f,0.f);
					break;
				case Texture::AXIS_Y:
					v = aiVector3D(0.f,1.f,0.f);
					break;
				default: // case Texture::AXIS_Z:
					v = aiVector3D(0.f,0.f,1.f);
					break;
			}

			pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur));

			// Setup UV scalings for cylindric and spherical projections
			if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE)	{
				aiUVTransform trafo;
				trafo.mScaling.x = (*it).wrapAmountW;
				trafo.mScaling.y = (*it).wrapAmountH;

				BOOST_STATIC_ASSERT(sizeof(aiUVTransform)/sizeof(float) == 5);
				pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur));
			}
			DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping");
		}

		// The older LWOB format does not use indirect references to clips.
		// The file name of a texture is directly specified in the tex chunk.
		if (mIsLWO2)	{
			// find the corresponding clip (take the last one if multiple
			// share the same index)
			ClipList::iterator end = mClips.end(), candidate = end;
			temp = (*it).mClipIdx;
			for (ClipList::iterator clip = mClips.begin(); clip != end; ++clip)	{
				if ((*clip).idx == temp) {
					candidate = clip;
				}
				
			}
			if (candidate == end)	{
				DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
				temp = 0;

				// fixme: apparently some LWO files shipping with Doom3 don't
				// have clips at all ... check whether that's true or whether
				// it's a bug in the loader.

				s.Set("$texture.png");

				//continue;
			}
			else {
				if (Clip::UNSUPPORTED == (*candidate).type)	{
					DefaultLogger::get()->error("LWO2: Clip type is not supported");
					continue;
				}
				AdjustTexturePath((*candidate).path);
				s.Set((*candidate).path);

				// Additional image settings
				int flags = 0;
				if ((*candidate).negate) {
					flags |= aiTextureFlags_Invert;
				}
				pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
			}
		}
		else 
		{
			std::string ss = (*it).mFileName;
			if (!ss.length()) {
				DefaultLogger::get()->error("LWOB: Empty file name");
				continue;
			}
			AdjustTexturePath(ss);
			s.Set(ss);
		}
		pcMat->AddProperty(&s,AI_MATKEY_TEXTURE(type,cur));

		// add the blend factor
		pcMat->AddProperty<float>(&(*it).mStrength,1,AI_MATKEY_TEXBLEND(type,cur));

		// add the blend operation
		switch ((*it).blendType)
		{
			case LWO::Texture::Normal:
			case LWO::Texture::Multiply:
				temp = (unsigned int)aiTextureOp_Multiply;
				break;

			case LWO::Texture::Subtractive:
			case LWO::Texture::Difference:
				temp = (unsigned int)aiTextureOp_Subtract;
				break;

			case LWO::Texture::Divide:
				temp = (unsigned int)aiTextureOp_Divide;
				break;

			case LWO::Texture::Additive:
				temp = (unsigned int)aiTextureOp_Add;
				break;

			default:
				temp = (unsigned int)aiTextureOp_Multiply;
				DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement");

		}
		// Setup texture operation
		pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));

		// setup the mapping mode
		pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));

		// add the u-wrapping
		temp = (unsigned int)GetMapMode((*it).wrapModeWidth);
		pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_U(type,cur));

		// add the v-wrapping
		temp = (unsigned int)GetMapMode((*it).wrapModeHeight);
		pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_V(type,cur));

		++cur;
	}
	return ret;
}