//-----------------------------------------------------------------------------
    String Technique::_compile(bool autoManageTextureUnits)
    {
		StringUtil::StrStreamType errors;

		mIsSupported = checkGPURules(errors);
		if (mIsSupported)
		{
			mIsSupported = checkHardwareSupport(autoManageTextureUnits, errors);
		}

        // Compile for categorised illumination on demand
        clearIlluminationPasses();
        mIlluminationPassesCompilationPhase = IPS_NOT_COMPILED;

		return errors.str();

    }
    SimpleRenderable::SimpleRenderable()
    {
        m_matWorldTransform = Matrix4::IDENTITY;

        m_strMatName = "BaseWhite"; 
        m_pMaterial = MaterialManager::getSingleton().getByName("BaseWhite");

        m_pParentSceneManager = NULL;

        mParentNode = NULL;
        m_pCamera = NULL;

        // Generate name
		StringUtil::StrStreamType name;
		name << _TO_CHAR("SimpleRenderable") << ms_uGenNameCount++;
		mName = name.str();
    }
	//-----------------------------------------------------------------------
	String ParticleScriptSerializer::toString(vector<Real> vector, bool applySqrt)
	{
        StringUtil::StrStreamType stream;
		if (!vector.empty())
		{
			for (size_t i = 0; i < vector.size(); ++i)
			{
				if (applySqrt)
				{
					stream << Math::Sqrt(vector[i]) << " ";
				}
				else
				{
					stream << vector[i] << " ";
				}
			}
		}
        return stream.str();
	}
	//---------------------------------------------------------------------
	HighLevelGpuProgramPtr 
	TerrainMaterialGeneratorC::SM2Profile::ShaderHelper::generateFragmentProgram(
		const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
	{
		HighLevelGpuProgramPtr ret = createFragmentProgram(prof, terrain, tt);
 
		StringUtil::StrStreamType sourceStr;
		generateFragmentProgramSource(prof, terrain, tt, sourceStr);
		ret->setSource(sourceStr.str());
		ret->load();
		defaultFpParams(prof, terrain, tt, ret);
 
#if 1
		LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Fragment Program: " 
			<< ret->getName() << " ***\n" << ret->getSource() << "\n***   ***";
#endif
 
		return ret;
	}
	//-----------------------------------------------------------------------
	SceneManager* SceneManagerEnumerator::createSceneManager(
		SceneTypeMask typeMask, const String& instanceName)
	{
		if (mInstances.find(instanceName) != mInstances.end())
		{
			OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, 
				"SceneManager instance called '" + instanceName + "' already exists",
				"SceneManagerEnumerator::createSceneManager");
		}

		SceneManager* inst = 0;
		String name = instanceName;
		if (name.empty())
		{
			// generate a name
			StringUtil::StrStreamType s;
			s << "SceneManagerInstance" << ++mInstanceCreateCount;
			name = s.str();
		}

		// Iterate backwards to find the matching factory registered last
		for(Factories::reverse_iterator i = mFactories.rbegin(); i != mFactories.rend(); ++i)
		{
			if ((*i)->getMetaData().sceneTypeMask & typeMask)
			{
				inst = (*i)->createInstance(name);
				break;
			}
		}

		// use default factory if none
		if (!inst)
			inst = mDefaultFactory.createInstance(name);

		/// assign rs if already configured
		if (mCurrentRenderSystem)
			inst->_setDestinationRenderSystem(mCurrentRenderSystem);
		
		mInstances[inst->getName()] = inst;

		return inst;

	}
Beispiel #6
0
Animation::RotationInterpolationMode OgreMaxUtilities::ParseAnimationRotationInterpolationMode(const String& mode)
{
    String modeLower = mode;
    StringUtil::toLowerCase(modeLower);

    if (modeLower == "linear")
        return Animation::RIM_LINEAR;
    else if (modeLower == "spherical")
        return Animation::RIM_SPHERICAL;

    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid animation rotation interpolation mode specified: " << mode;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseAnimationRotationInterpolationMode"
        );
}
Beispiel #7
0
UpAxis OgreMaxUtilities::ParseUpAxis(const String& upAxis)
{
    String upAxisLower = upAxis;
    StringUtil::toLowerCase(upAxisLower);

    if (upAxisLower == "y")
        return UP_AXIS_Y;
    else if (upAxisLower == "z")
        return UP_AXIS_Z;

    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid up axis specified: " << upAxis;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseUpAxis"
        );
}
//---------------------------------------------------------------------
StreamSerialiser* PageManager::_readPageStream(PageID pageID, PagedWorldSection* section)
{
    StreamSerialiser* ser = 0;
    if (mPageProvider)
        ser = mPageProvider->readPageStream(pageID, section);
    if (!ser)
    {
        // use default implementation
        StringUtil::StrStreamType nameStr;
        nameStr << section->getWorld()->getName() << "_" << section->getName()
                << "_" << pageID << ".page";
        DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(nameStr.str());

        ser = OGRE_NEW StreamSerialiser(stream);

    }

    return ser;

}
Beispiel #9
0
BillboardRotationType OgreMaxUtilities::ParseBillboardRotationType(const String& rotationType)
{
    String rotationTypeLower = rotationType;
    StringUtil::toLowerCase(rotationTypeLower);

    if (rotationTypeLower == "vertex")
        return BBR_VERTEX;
    else if (rotationTypeLower == "texcoord")
        return BBR_TEXCOORD;
    
    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid billboard rotation type specified: " << rotationType;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseBillboardRotationType"
        );
}
Beispiel #10
0
ProjectionType OgreMaxUtilities::ParseProjectionType(const String& type)
{
    String typeLower = type;
    StringUtil::toLowerCase(typeLower);

    if (typeLower == "perspective")
        return PT_PERSPECTIVE;
    else if (typeLower == "orthographic")
        return PT_ORTHOGRAPHIC;
    
    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid projection type specified: " << type;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseProjectionType"
        );
}
Beispiel #11
0
    RenderTarget::~RenderTarget()
    {
        // Delete viewports
        for (ViewportList::iterator i = mViewportList.begin();
            i != mViewportList.end(); ++i)
        {
            fireViewportRemoved(i->second);
            delete (*i).second;
        }


        // Write closing message
		StringUtil::StrStreamType msg;
		msg << "Render Target '" << mName << "' "
			<< "Average FPS: " << mStats.avgFPS << " "
			<< "Best FPS: " << mStats.bestFPS << " "
			<< "Worst FPS: " << mStats.worstFPS; 
        LogManager::getSingleton().logMessage(msg.str());

    }
Beispiel #12
0
    //-----------------------------------------------------------------------
    void Material::compile(bool autoManageTextureUnits)
    {
        // Compile each technique, then add it to the list of supported techniques
        mSupportedTechniques.clear();
		clearBestTechniqueList();
		mUnsupportedReasons.clear();


        Techniques::iterator i, iend;
        iend = mTechniques.end();
		size_t techNo = 0;
        for (i = mTechniques.begin(); i != iend; ++i, ++techNo)
        {
            String compileMessages = (*i)->_compile(autoManageTextureUnits);
            if ( (*i)->isSupported() )
            {
				insertSupportedTechnique(*i);
            }
			else
			{
				// Log informational
				StringUtil::StrStreamType str;
				str << "Material " << mName << " Technique " << techNo;
				if (!(*i)->getName().empty())
					str << "(" << (*i)->getName() << ")";
				str << " is not supported. " << compileMessages;
				LogManager::getSingleton().logMessage(str.str(), LML_TRIVIAL);
				mUnsupportedReasons += compileMessages;
			}
        }

        mCompilationRequired = false;

        // Did we find any?
        if (mSupportedTechniques.empty())
        {
			LogManager::getSingleton().stream()
				<< "WARNING: material " << mName << " has no supportable "
				<< "Techniques and will be blank. Explanation: \n" << mUnsupportedReasons;
        }
    }
	const String& Exception::getFullDescription(void) const
	{
		if (fullDesc.empty())
		{

			StringUtil::StrStreamType desc;    //字符串流

			desc << "SAPPHIRE EXCEPTION(" << number << ":" << typeName << "): "
				<< description
				<< " in " << source;

			if (line > 0)
			{
				desc << " at " << file << " (line " << line << ")";
			}

			fullDesc = desc.str();
		}

		return fullDesc;
	}
//-----------------------------------------------------------------------
String StringConverter::toString(const Matrix4& val)
{
    StringUtil::StrStreamType stream;
    stream << val[0][0] << " "
           << val[0][1] << " "
           << val[0][2] << " "
           << val[0][3] << " "
           << val[1][0] << " "
           << val[1][1] << " "
           << val[1][2] << " "
           << val[1][3] << " "
           << val[2][0] << " "
           << val[2][1] << " "
           << val[2][2] << " "
           << val[2][3] << " "
           << val[3][0] << " "
           << val[3][1] << " "
           << val[3][2] << " "
           << val[3][3];
    return stream.str();
}
	//------------------------------------------------------
	Ogre::MaterialPtr MaterialService::getWorldMaterialInstance(unsigned int idx, int tag) {
		if (tag < 0) {
			MaterialPtr mat = getWorldMaterialTemplate(idx);
			return mat;
		} else {
			MaterialPtr tmat = getWorldMaterialTemplate(idx);
			MaterialPtr imat;


			// have to look for it and clone
			WorldMaterialInstanceMap::iterator it = mWorldMaterials.find(idx);

			if (it == mWorldMaterials.end()) {
				// no slot for the idx. have to clone
				std::pair<WorldMaterialInstanceMap::iterator, bool> res = mWorldMaterials.insert(make_pair(idx,
				        SlotMaterialMap()));

				it = res.first;
			}

			// now search
			SlotMaterialMap::iterator sit = it->second.find(tag);

			if (sit == it->second.end()) {
				StringUtil::StrStreamType tmp;

				tmp << "Shader" << idx << "#" << tag;

				imat = tmat->clone(tmp.str());

				prepareMaterialInstance(imat, idx, tag);

				it->second.insert(make_pair(tag, imat));
			} else {
				imat = sit->second;
			}

			return imat;
		}
	}
Beispiel #16
0
    //-----------------------------------------------------------------------
    void TextureUnitState::setAnimatedTextureName( const String& name, unsigned int numFrames, Real duration)
    {
		setContentType(CONTENT_NAMED);
		mTextureLoadFailed = false;

		String ext;
        String baseName;

        size_t pos = name.find_last_of(".");
        baseName = name.substr(0, pos);
        ext = name.substr(pos);

        mFrames.resize(numFrames);
		// resize pointers, but don't populate until needed
        mFramePtrs.resize(numFrames);
        mAnimDuration = duration;
        mCurrentFrame = 0;
        mCubic = false;

        for (unsigned int i = 0; i < mFrames.size(); ++i)
        {
			StringUtil::StrStreamType str;
            str << baseName << "_" << i << ext;
            mFrames[i] = str.str();
			mFramePtrs[i].setNull();
        }

        // Load immediately if Material loaded
        if (isLoaded())
        {
            _load();
        }
		// Tell parent to recalculate hash
		if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) )
		{
			mParent->_dirtyHash();
		}

    }
Beispiel #17
0
Light::LightTypes OgreMaxUtilities::ParseLightType(const String& type)
{
    String typeLower = type;
    StringUtil::toLowerCase(typeLower);

    if (typeLower == "point")
        return Light::LT_POINT;
    else if (typeLower == "directional")
        return Light::LT_DIRECTIONAL;
    else if (typeLower == "spot")
        return Light::LT_SPOTLIGHT;

    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid light type specified: " << type;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseLightType"
        );
}
Beispiel #18
0
Node::TransformSpace OgreMaxUtilities::ParseTransformSpace(const String& space)
{
    String spaceLower = space;
    StringUtil::toLowerCase(spaceLower);

    if (spaceLower == "local")
        return Node::TS_LOCAL;
    else if (spaceLower == "parent")
        return Node::TS_PARENT;
    else if (spaceLower == "world")
        return Node::TS_WORLD;
    
    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid transform space specified: " << space;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseTransformSpace"
        );
}
Beispiel #19
0
BoundingVolume::Type OgreMaxUtilities::ParseBoundingVolumeType(const String& type)
{
    String typeLower = type;
    StringUtil::toLowerCase(typeLower);

    if (typeLower == "sphere")
        return BoundingVolume::SPHERE;
    else if (typeLower == "box")
        return BoundingVolume::BOX;
    else if (typeLower == "mesh")
        return BoundingVolume::MESH;
    
    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid bounding volume type specified: " << type;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseBoundingVolumeType"
        );
}
//---------------------------------------------------------------------
StreamSerialiser* PageManager::_writePageStream(PageID pageID, PagedWorldSection* section)
{
    StreamSerialiser* ser = 0;
    if (mPageProvider)
        ser = mPageProvider->writePageStream(pageID, section);
    if (!ser)
    {
        // use default implementation
        StringUtil::StrStreamType nameStr;
        nameStr << section->getWorld()->getName() << "_" << section->getName()
                << "_" << pageID << ".page";

        // create file, overwrite if necessary
        DataStreamPtr stream = ResourceGroupManager::getSingleton().createResource(
                                   nameStr.str(), mPageResourceGroup, true);

        ser = OGRE_NEW StreamSerialiser(stream);

    }

    return ser;

}
Beispiel #21
0
void PixelFormatTests::testCase(PixelFormat srcFormat, PixelFormat dstFormat)
{
    setupBoxes(srcFormat, dstFormat);
    // Check end of buffer
    unsigned int eob = dst1.getWidth()*PixelUtil::getNumElemBytes(dstFormat);
    temp[eob] = (unsigned char)0x56;
    temp[eob+1] = (unsigned char)0x23;

    //std::cerr << "["+PixelUtil::getFormatName(srcFormat)+"->"+PixelUtil::getFormatName(dstFormat)+"]" << " " << eob << std::endl;

    // Do pack/unpacking with both naive and optimized version
    PixelUtil::bulkPixelConversion(src, dst1);
    naiveBulkPixelConversion(src, dst2);

    CPPUNIT_ASSERT_EQUAL(temp[eob], (unsigned char)0x56);
    CPPUNIT_ASSERT_EQUAL(temp[eob+1], (unsigned char)0x23);

    std::stringstream s;
    int x;
    s << "src=";
    for(x=0; x<16; x++)
        s << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) randomData[x];
    s << " dst=";
    for(x=0; x<16; x++)
        s << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) temp[x];
    s << " dstRef=";
    for(x=0; x<16; x++)
        s << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) temp2[x];
    s << " ";

    // Compare result
	StringUtil::StrStreamType msg;
	msg << "Conversion mismatch [" << PixelUtil::getFormatName(srcFormat) << 
		"->" << PixelUtil::getFormatName(dstFormat) << "] " << s.str();
    CPPUNIT_ASSERT_MESSAGE(msg.str().c_str(),
		memcmp(dst1.data, dst2.data, eob) == 0);
}
Beispiel #22
0
FogMode OgreMaxUtilities::ParseFogMode(const String& mode)
{
    String modeLower = mode;
    StringUtil::toLowerCase(modeLower);

    if (modeLower == "exp")
        return FOG_EXP;
    else if (modeLower == "exp2")
        return FOG_EXP2;
    else if (modeLower == "linear")
        return FOG_LINEAR;
    else
        return FOG_NONE;

    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid fog mode specified: " << mode;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseFogMode"
        );
}
Beispiel #23
0
TextureType OgreMaxUtilities::ParseTextureType(const String& textureType)
{
    String textureTypeLower = textureType;
    StringUtil::toLowerCase(textureTypeLower);

    if (textureTypeLower == "1d")
        return TEX_TYPE_1D;
    else if (textureTypeLower == "2d")
        return TEX_TYPE_2D;
    else if (textureTypeLower == "3d")
        return TEX_TYPE_3D;
    else if (textureTypeLower == "cubic")
        return TEX_TYPE_CUBE_MAP;

    StringUtil::StrStreamType errorMessage;
    errorMessage << "Invalid texture type specified: " << textureType;

    OGRE_EXCEPT
        (
        Exception::ERR_INVALIDPARAMS,
	    errorMessage.str(), 
	    "OgreMaxUtilities::ParseTextureType"
        );
}
	//-----------------------------------------------------------------------------
	void XsiSkeletonExporter::createAnimations(Skeleton* pSkel, 
		DeformerMap& deformers, float fps, AnimationList& animList, AxisAlignedBox& AABBPadding)
	{
		for (AnimationList::iterator ai = animList.begin(); ai != animList.end(); ++ai)
		{
			AnimationEntry& animEntry = *ai;

			// Note that we don't know if this time period includes bone animation
			// but we sample it anyway just in case; animation optimisation will
			// eliminate anything that's redundant
			// A little wasteful perhaps, but it's the only guaranteed way to pick
			// up all the potentially derived effects on deformers

			float animLength = (float)(animEntry.endFrame - animEntry.startFrame) / fps;
			StringUtil::StrStreamType str;
			str << "Creating animation " << animEntry.animationName << 
				" with length " << animLength << " seconds";
			LogOgreAndXSI(str.str());
			Animation* anim = pSkel->createAnimation(animEntry.animationName, animLength);

			createAnimationTracksSampled(anim, animEntry, deformers, fps, AABBPadding);
			
		}
	}
Beispiel #25
0
    Viewport* RenderTarget::addViewport(Camera* cam, int ZOrder, float left, float top ,
        float width , float height)
    {
        // Check no existing viewport with this Z-order
        ViewportList::iterator it = mViewportList.find(ZOrder);

        if (it != mViewportList.end())
        {
			StringUtil::StrStreamType str;
			str << "Can't create another viewport for "
				<< mName << " with Z-Order " << ZOrder
				<< " because a viewport exists with this Z-Order already.";
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, str.str(), "RenderTarget::addViewport");
        }
        // Add viewport to list
        // Order based on Z-Order
        Viewport* vp = new Viewport(cam, this, left, top, width, height, ZOrder);

        mViewportList.insert(ViewportList::value_type(ZOrder, vp));

		fireViewportAdded(vp);

        return vp;
    }
Beispiel #26
0
    //---------------------------------------------------------------------
    void Skeleton::loadImpl(void)
    {
        SkeletonSerializer serializer;
		StringUtil::StrStreamType msg;
		msg << "Skeleton: Loading " << mName;
        LogManager::getSingleton().logMessage(msg.str());

        DataStreamPtr stream = 
            ResourceGroupManager::getSingleton().openResource(
				mName, mGroup, true, this);

        serializer.importSkeleton(stream, this);

		// Load any linked skeletons
		LinkedSkeletonAnimSourceList::iterator i;
		for (i = mLinkedSkeletonAnimSourceList.begin(); 
			i != mLinkedSkeletonAnimSourceList.end(); ++i)
		{
			i->pSkeleton = SkeletonManager::getSingleton().load(
				i->skeletonName, mGroup);
		}


    }
	//---------------------------------------------------------------------
	bool Technique::checkGPURules(StringUtil::StrStreamType& errors)
	{
		const RenderSystemCapabilities* caps =
			Root::getSingleton().getRenderSystem()->getCapabilities();

		StringUtil::StrStreamType includeRules;
		bool includeRulesPresent = false;
		bool includeRuleMatched = false;

		// Check vendors first
		for (GPUVendorRuleList::const_iterator i = mGPUVendorRules.begin();
			i != mGPUVendorRules.end(); ++i)
		{
			if (i->includeOrExclude == INCLUDE)
			{
				includeRulesPresent = true;
				includeRules << caps->vendorToString(i->vendor) << " ";
				if (i->vendor == caps->getVendor())
					includeRuleMatched = true;
			}
			else // EXCLUDE
			{
				if (i->vendor == caps->getVendor())
				{
					errors << "Excluded GPU vendor: " << caps->vendorToString(i->vendor)
						<< std::endl;
					return false;
				}
					
			}
		}

		if (includeRulesPresent && !includeRuleMatched)
		{
			errors << "Failed to match GPU vendor: " << includeRules.str( )
				<< std::endl;
			return false;
		}

		// now check device names
		includeRules.str(StringUtil::BLANK);
		includeRulesPresent = false;
		includeRuleMatched = false;

		for (GPUDeviceNameRuleList::const_iterator i = mGPUDeviceNameRules.begin();
			i != mGPUDeviceNameRules.end(); ++i)
		{
			if (i->includeOrExclude == INCLUDE)
			{
				includeRulesPresent = true;
				includeRules << i->devicePattern << " ";
				if (StringUtil::match(caps->getDeviceName(), i->devicePattern, i->caseSensitive))
					includeRuleMatched = true;
			}
			else // EXCLUDE
			{
				if (StringUtil::match(caps->getDeviceName(), i->devicePattern, i->caseSensitive))
				{
					errors << "Excluded GPU device: " << i->devicePattern
						<< std::endl;
					return false;
				}

			}
		}

		if (includeRulesPresent && !includeRuleMatched)
		{
			errors << "Failed to match GPU device: " << includeRules.str( )
				<< std::endl;
			return false;
		}

		// passed
		return true;
	}
Beispiel #28
0
void GrassLayerBase::_updateShaders()
{
  if (shaderNeedsUpdate) {
    shaderNeedsUpdate = false;

    //Proceed only if there is no custom vertex shader and the user's computer supports vertex shaders
    const RenderSystemCapabilities *caps = Root::getSingleton().getRenderSystem()->getCapabilities();
    if (caps->hasCapability(RSC_VERTEX_PROGRAM) && geom->getShadersEnabled()) {
      //Calculate fade range
      float farViewDist = geom->getDetailLevels().front()->getFarRange();
      float fadeRange = farViewDist / 1.2247449f;
      //Note: 1.2247449 ~= sqrt(1.5), which is necessary since the far view distance is measured from the centers
      //of pages, while the vertex shader needs to fade grass completely out (including the closest corner)
      //before the page center is out of range.

      //Generate a string ID that identifies the current set of vertex shader options
      StringUtil::StrStreamType tmpName;
      tmpName << "GrassVS_";
      if (animate)
        tmpName << "anim_";
      if (blend)
        tmpName << "blend_";
      if (lighting)
        tmpName << "lighting_";
      tmpName << renderTechnique << "_";
      tmpName << fadeTechnique << "_";
      if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW)
        tmpName << maxHeight << "_";
      tmpName << farViewDist << "_";
      tmpName << "vp";
      const String vsName = tmpName.str();

      //Generate a string ID that identifies the material combined with the vertex shader
      const String matName = material->getName() + "_" + vsName;

      //Check if the desired material already exists (if not, create it)
      MaterialPtr tmpMat = MaterialManager::getSingleton().getByName(matName);
      if (tmpMat.isNull()) {
        //Clone the original material
        tmpMat = material->clone(matName);

        //Disable lighting
        tmpMat->setLightingEnabled(false);
        //tmpMat->setReceiveShadows(false);

        //Check if the desired shader already exists (if not, compile it)
        String shaderLanguage = ShaderHelper::getShaderLanguage();
        HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().getByName(vsName);
        if (vertexShader.isNull()) {

          //Generate the grass shader
          String vertexProgSource;

          if (!shaderLanguage.compare("hlsl") || !shaderLanguage.compare("cg")) {

            vertexProgSource = "void main( \n"
                "	float4 iPosition : POSITION, \n"
                "	float4 iColor : COLOR, \n"
                "	float2 iUV       : TEXCOORD0,	\n"
                "	out float4 oPosition : POSITION, \n"
                "	out float4 oColor : COLOR, \n"
                "	out float2 oUV       : TEXCOORD0,	\n";

            if (lighting)
              vertexProgSource += "   uniform float4   objSpaceLight,   \n"
                  "   uniform float4   lightDiffuse,   \n"
                  "   uniform float4   lightAmbient,   \n";

            if (animate)
              vertexProgSource += "	uniform float time,	\n"
                  "	uniform float frequency,	\n"
                  "	uniform float4 direction,	\n";

            if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW)
              vertexProgSource += "	uniform float grassHeight,	\n";

            if (renderTechnique == GRASSTECH_SPRITE || lighting)
              vertexProgSource += "   float4 iNormal : NORMAL, \n";

            vertexProgSource += "	uniform float4x4 worldViewProj,	\n"
                "	uniform float3 camPos, \n"
                "	uniform float fadeRange ) \n"
                "{	\n"
                "	oColor.rgb = iColor.rgb;   \n"
                "	float4 position = iPosition;	\n"
                "	float dist = distance(camPos.xz, position.xz);	\n";

            if (lighting) {
              vertexProgSource += "   float3 light = normalize(objSpaceLight.xyz - (iPosition.xyz * objSpaceLight.w)); \n"
                  "   float diffuseFactor = max(dot(float4(0,1,0,0), light), 0); \n"
                  "   oColor = (lightAmbient + diffuseFactor * lightDiffuse) * iColor; \n";
            } else {
              vertexProgSource += "   oColor.rgb = iColor.rgb;               \n";
            }

            if (fadeTechnique == FADETECH_ALPHA || fadeTechnique == FADETECH_ALPHAGROW)
              vertexProgSource +=
              //Fade out in the distance
                  "	oColor.a = 2.0f - (2.0f * dist / fadeRange);   \n";
            else
              vertexProgSource += "	oColor.a = 1.0f;   \n";

            vertexProgSource += "	float oldposx = position.x;	\n";

            if (renderTechnique == GRASSTECH_SPRITE)
              vertexProgSource +=
              //Face the camera
                  "	float3 dirVec = (float3)position - (float3)camPos;		\n"
                      "	float3 p = normalize(cross(float4(0,1,0,0), dirVec));	\n"
                      "	position += float4(p.x * iNormal.x, iNormal.y, p.z * iNormal.x, 0);	\n";

            if (animate)
              vertexProgSource += "	if (iUV.y == 0.0f){	\n"
              //Wave grass in breeze
                      "		float offset = sin(time + oldposx * frequency);	\n"
                      "		position += direction * offset;	\n"
                      "	}	\n";

            if (blend && animate)
              vertexProgSource += "	else {	\n";
            else if (blend)
              vertexProgSource += "	if (iUV.y != 0.0f){	\n";

            if (blend)
              vertexProgSource +=
              //Blend the base of nearby grass into the terrain
                  "		oColor.a = clamp(oColor.a, 0, 1) * 4.0f * ((dist / fadeRange) - 0.1f);	\n"
                      "	}	\n";

            if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW)
              vertexProgSource += "	float offset = (2.0f * dist / fadeRange) - 1.0f; \n"
                  "	position.y -= grassHeight * clamp(offset, 0, 1); ";

            vertexProgSource += "	oPosition = mul(worldViewProj, position);  \n";

            vertexProgSource += "	oUV = iUV;\n"
                "}";
          } else {
            //Must be glsl
            if (lighting) {
              vertexProgSource = "uniform vec4 objSpaceLight; \n"
                  "uniform vec4 lightDiffuse; \n"
                  "uniform vec4 lightAmbient; \n";
            }

            if (animate) {
              vertexProgSource += "uniform float time; \n"
                  "uniform float frequency; \n"
                  "uniform vec4 direction; \n";
            }

            if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) {
              vertexProgSource += "uniform float grassHeight;	\n";
            }

            vertexProgSource += "uniform vec3 camPos; \n"
                "uniform float fadeRange; \n"
                "\n"
                "void main()"
                "{ \n"
                "    vec4 color = gl_Color; \n"
                "    vec4 position = gl_Vertex;	\n"
                "    float dist = distance(camPos.xz, position.xz);	\n";

            if (lighting) {
              vertexProgSource += "    vec3 light = normalize(objSpaceLight.xyz - (gl_Vertex.xyz * objSpaceLight.w)); \n"
                  "    float diffuseFactor = max( dot( vec3(0.0,1.0,0.0), light), 0.0); \n"
                  "    color = (lightAmbient + diffuseFactor * lightDiffuse) * gl_Color; \n";
            } else {
              vertexProgSource += "    color.xyz = gl_Color.xyz; \n";
            }

            if (fadeTechnique == FADETECH_ALPHA || fadeTechnique == FADETECH_ALPHAGROW) {
              vertexProgSource +=
              //Fade out in the distance
                  "    color.w = 2.0 - (2.0 * dist / fadeRange); \n";
            } else {
              vertexProgSource += "    color.w = 1.0; \n";
            }

            if (renderTechnique == GRASSTECH_SPRITE) {
              vertexProgSource +=
              //Face the camera
                  "    vec3 dirVec = position.xyz - camPos.xyz; \n"
                      "    vec3 p = normalize(cross(vec3(0.0,1.0,0.0), dirVec)); \n"
                      "    position += vec4(p.x * gl_Normal.x, gl_Normal.y, p.z * gl_Normal.x, 0.0); \n";
            }

            if (animate) {
              vertexProgSource += "    if (gl_MultiTexCoord0.y == 0.0) \n"
                  "    { \n"
                  //Wave grass in breeze
                  "        position += direction * sin(time + gl_Vertex.x * frequency); \n"
                  "    } \n";
            }

            if (blend && animate) {
              vertexProgSource += "    else \n"
                  "    { \n";
            } else if (blend) {
              vertexProgSource += "    if (gl_MultiTexCoord0.y != 0.0) \n"
                  "    { \n";
            }

            if (blend) {
              vertexProgSource +=
              //Blend the base of nearby grass into the terrain
                  "        color.w = clamp(color.w, 0.0, 1.0) * 4.0 * ((dist / fadeRange) - 0.1); \n"
                      "    } \n";
            }

            if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) {
              vertexProgSource += "    position.y -= grassHeight * clamp((2.0 * dist / fadeRange) - 1.0, 0.0, 1.0); \n";
            }

            vertexProgSource += "    gl_Position = gl_ModelViewProjectionMatrix * position; \n"
                "    gl_FrontColor = color; \n"
                "    gl_TexCoord[0] = gl_MultiTexCoord0; \n";
            if (geom->getSceneManager()->getFogMode() == Ogre::FOG_EXP2) {
              vertexProgSource += "	gl_FogFragCoord = clamp(exp(- gl_Fog.density * gl_Fog.density * gl_Position.z * gl_Position.z), 0.0, 1.0); \n";
            } else {
              vertexProgSource += "	gl_FogFragCoord = gl_Position.z; \n";
            }

            vertexProgSource += "}";
          }

          vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram(vsName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, shaderLanguage, GPT_VERTEX_PROGRAM);

          vertexShader->setSource(vertexProgSource);

          if (shaderLanguage == "hlsl") {
            vertexShader->setParameter("target", "vs_1_1");
            vertexShader->setParameter("entry_point", "main");
          } else if (shaderLanguage == "cg") {
            vertexShader->setParameter("profiles", "vs_1_1 arbvp1");
            vertexShader->setParameter("entry_point", "main");
          }
          // GLSL can only have one entry point "main".

          vertexShader->load();
        }
        //Now the vertex shader (vertexShader) has either been found or just generated
        //(depending on whether or not it was already generated).

        tmpMat->load();
        Ogre::Material::TechniqueIterator techIterator = tmpMat->getSupportedTechniqueIterator();
        while (techIterator.hasMoreElements()) {
          Ogre::Technique* tech = techIterator.getNext();
          //Apply the shader to the material
          Pass *pass = tech->getPass(0);
          pass->setVertexProgram(vsName);
          GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();

          if (shaderLanguage.compare("glsl"))
            //glsl can use the built in gl_ModelViewProjectionMatrix
            params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
          params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
          params->setNamedAutoConstant("fadeRange", GpuProgramParameters::ACT_CUSTOM, 1);

          if (animate) {
            params->setNamedConstant("time", 1.0f);
            params->setNamedConstant("frequency", 1.0f);
            params->setNamedConstant("direction", Ogre::Vector4::ZERO);
          }

          if (lighting) {
            params->setNamedAutoConstant("objSpaceLight", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE);
            params->setNamedAutoConstant("lightDiffuse", GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR);
            params->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR);
          }

          if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) {
            params->setNamedConstant("grassHeight", maxHeight * 1.05f);
          }

          pass->getVertexProgramParameters()->setNamedConstant("fadeRange", fadeRange);
        }
      }
      //Now the material (tmpMat) has either been found or just created (depending on whether or not it was already
      //created). The appropriate vertex shader should be applied and the material is ready for use.

      //Apply the new material
      material = tmpMat;
    }

    Ogre::Technique* tech = material->getBestTechnique();
    if (tech && tech->getNumPasses()) {
      Ogre::Pass* pass = tech->getPass(0);
      if (pass->hasVertexProgram()) {
        Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();
        if (!params.isNull()) {
          params->setIgnoreMissingParams(true);
        }
      }
    }
  }
}
    //-----------------------------------------------------------------------
    MaterialPtr Quake3Shader::createAsMaterial(int lightmapNumber)
    {
		String matName;
		StringUtil::StrStreamType str;
        String resourceGroup = ResourceGroupManager::getSingleton().getWorldResourceGroupName();

        str << mName << "#" << lightmapNumber;
		matName = str.str();

        MaterialPtr mat = MaterialManager::getSingleton().create(matName, 
            resourceGroup);
		Ogre::Pass* ogrePass = mat->getTechnique(0)->getPass(0);

        LogManager::getSingleton().logMessage("Using Q3 shader " + mName, LML_CRITICAL);
        for (int p = 0; p < numPasses; ++p)
        {
            TextureUnitState* t;
            // Create basic texture
            if (pass[p].textureName == "$lightmap")
            {
                StringUtil::StrStreamType str2;
				str2 << "@lightmap" << lightmapNumber;
                t = ogrePass->createTextureUnitState(str2.str());
            }
            // Animated texture support
            else if (pass[p].animNumFrames > 0)
            {
                Real sequenceTime = pass[p].animNumFrames / pass[p].animFps;
                /* Pre-load textures
                   We need to know if each one was loaded OK since extensions may change for each
                   Quake3 can still include alternate extension filenames e.g. jpg instead of tga
                   Pain in the arse - have to check for each frame as letters<n>.tga for example
                   is different per frame!
                */
                for (unsigned int alt = 0; alt < pass[p].animNumFrames; ++alt)
                {
                    if (!ResourceGroupManager::getSingleton().resourceExists(
                        resourceGroup, pass[p].frames[alt]))
                    {
                        // Try alternate extension
                        pass[p].frames[alt] = getAlternateName(pass[p].frames[alt]);
                        if (!ResourceGroupManager::getSingleton().resourceExists(
                            resourceGroup, pass[p].frames[alt]))
                        { 
                            // stuffed - no texture
                            continue;
                        }
                    }

                }

                t = ogrePass->createTextureUnitState("");
                t->setAnimatedTextureName(pass[p].frames, pass[p].animNumFrames, sequenceTime);

            }
            else
            {
                // Quake3 can still include alternate extension filenames e.g. jpg instead of tga
                // Pain in the arse - have to check for failure
                if (!ResourceGroupManager::getSingleton().resourceExists(
                    resourceGroup, pass[p].textureName))
                {
                    // Try alternate extension
                    pass[p].textureName = getAlternateName(pass[p].textureName);
                    if (!ResourceGroupManager::getSingleton().resourceExists(
                        resourceGroup, pass[p].textureName))
                    { 
                        // stuffed - no texture
                        continue;
                    }
                }
                t = ogrePass->createTextureUnitState(pass[p].textureName);
            }
            // Blending
            if (p == 0)
            {
                // scene blend
                mat->setSceneBlending(pass[p].blendSrc, pass[p].blendDest);
                if (mat->isTransparent())
                    mat->setDepthWriteEnabled(false);

                t->setColourOperation(LBO_REPLACE);
				// Alpha mode
				ogrePass->setAlphaRejectSettings(
					pass[p].alphaFunc, pass[p].alphaVal);
            }
            else
            {
                if (pass[p].customBlend)
                {
                    // Fallback for now
                    t->setColourOperation(LBO_MODULATE);
                }
                else
                {
                    // simple layer blend
                    t->setColourOperation(pass[p].blend);
                }
				// Alpha mode, prefer 'most alphary'
				CompareFunction currFunc = ogrePass->getAlphaRejectFunction();
				unsigned char currVal = ogrePass->getAlphaRejectValue();
				if (pass[p].alphaFunc > currFunc ||
					(pass[p].alphaFunc == currFunc && pass[p].alphaVal < currVal))
				{
					ogrePass->setAlphaRejectSettings(
						pass[p].alphaFunc, pass[p].alphaVal);
				}
            }
            // Tex coords
            if (pass[p].texGen == TEXGEN_BASE)
            {
                t->setTextureCoordSet(0);
            }
            else if (pass[p].texGen == TEXGEN_LIGHTMAP)
            {
                t->setTextureCoordSet(1);
            }
            else if (pass[p].texGen == TEXGEN_ENVIRONMENT)
            {
                t->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR);
            }
            // Tex mod
            // Scale
            t->setTextureUScale(pass[p].tcModScale[0]);
            t->setTextureVScale(pass[p].tcModScale[1]);
            // Procedural mods
            // Custom - don't use mod if generating environment
            // Because I do env a different way it look horrible
            if (pass[p].texGen != TEXGEN_ENVIRONMENT)
            {
                if (pass[p].tcModRotate)
                {
                    t->setRotateAnimation(pass[p].tcModRotate);
                }
                if (pass[p].tcModScroll[0] || pass[p].tcModScroll[1])
                {
                    if (pass[p].tcModTurbOn)
                    {
                        // Turbulent scroll
                        if (pass[p].tcModScroll[0])
                        {
                            t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_U, WFT_SINE,
                                pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
                        }
                        if (pass[p].tcModScroll[1])
                        {
                            t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_V, WFT_SINE,
                                pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
                        }
                    }
                    else
                    {
                        // Constant scroll
                        t->setScrollAnimation(pass[p].tcModScroll[0], pass[p].tcModScroll[1]);
                    }
                }
                if (pass[p].tcModStretchWave != SHADER_FUNC_NONE)
                {
                    WaveformType wft;
                    switch(pass[p].tcModStretchWave)
                    {
                    case SHADER_FUNC_SIN:
                        wft = WFT_SINE;
                        break;
                    case SHADER_FUNC_TRIANGLE:
                        wft = WFT_TRIANGLE;
                        break;
                    case SHADER_FUNC_SQUARE:
                        wft = WFT_SQUARE;
                        break;
                    case SHADER_FUNC_SAWTOOTH:
                        wft = WFT_SAWTOOTH;
                        break;
                    case SHADER_FUNC_INVERSESAWTOOTH:
                        wft = WFT_INVERSE_SAWTOOTH;
                        break;
                    default:
                        break;
                    }
                    // Create wave-based stretcher
                    t->setTransformAnimation(TextureUnitState::TT_SCALE_U, wft, pass[p].tcModStretchParams[3],
                        pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
                    t->setTransformAnimation(TextureUnitState::TT_SCALE_V, wft, pass[p].tcModStretchParams[3],
                        pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
                }
            }
            // Address mode
            t->setTextureAddressingMode(pass[p].addressMode);

            //assert(!t->isBlank());


        }
        // Do farbox (create new material)

        // Set culling mode and lighting to defaults
        mat->setCullingMode(CULL_NONE);
        mat->setManualCullingMode(cullMode);
        mat->setLightingEnabled(false);
        mat->load();
        return mat;
    }
Beispiel #30
0
void ReloadMaterial(const std::string& materialName, const std::string& groupName, const std::string& filename, bool parseMaterialScript)
{
    if (materialName.empty())
    {
        Ogre::LogManager::getSingleton().logMessage("Material name is empty.");
        return;
    }
 
    if (groupName.empty())
    {
        Ogre::LogManager::getSingleton().logMessage("Group name is empty.");
        return;
    }
 
    if (filename.empty())
    {
        Ogre::LogManager::getSingleton().logMessage("Filename is empty.");
        return;
    }
 
    UnloadMaterials(filename);
    UnloadVertexPrograms(filename);
    UnloadFragmentPrograms(filename);
 
    if (parseMaterialScript)
    {
        Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename);
        if(!stream.isNull())
        {
            try
            {
                Ogre::MaterialManager::getSingleton().parseScript(stream, groupName);
                Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().getByName(materialName);
                if (!materialPtr.isNull())
                {
                    materialPtr->compile();
                    materialPtr->load();
                }
            }
            catch (Ogre::Exception &e)
            {
                StringUtil::StrStreamType msg;
                msg << "Exception: FILE: " << __FILE__ << " LINE: " << __LINE__ << " DESC: " << e.getFullDescription() << std::endl;
                Ogre::LogManager::getSingleton().logMessage(msg.str());
            }
        }
        stream->close();
 
        ///
        /// RELOAD MATERIAL SCRIPT CONTENTS
        ///
        stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename);
        if(!stream.isNull())
        {
            try
            {
                ///
                /// RELOAD ALL MATERIAL CONTENTS IN FILE
                ///
                while(!stream->eof())
                {
                    std::string line = stream->getLine();
                    StringUtil::trim(line);
                    ///
                    /// RELOAD MATERIALS
                    ///
                    if (StringUtil::startsWith(line, "material"))
                    {
                        Ogre::vector<Ogre::String>::type vec = StringUtil::split(line," \t:");
                        bool skipFirst = true;
                        for (Ogre::vector<Ogre::String>::type::iterator it = vec.begin(); it < vec.end(); ++it)
                        {
                            if (skipFirst)
                            {
                                skipFirst = false;
                                continue;
                            }
                            std::string match = (*it);
                            StringUtil::trim(match);
                            if (!match.empty())
                            {
                                LoadResource(Ogre::MaterialManager::getSingletonPtr(), match, groupName);
                                break;
                            }
                        }
                    }
                    ///
                    /// RELOAD VERTEX PROGRAMS
                    ///
                    if (StringUtil::startsWith(line, "vertex_program") && !StringUtil::startsWith(line, "vertex_program_ref"))
                    {
                        Ogre::vector<Ogre::String>::type vec = StringUtil::split(line," \t");
                        bool skipFirst = true;
                        for (Ogre::vector<Ogre::String>::type::iterator it = vec.begin(); it < vec.end(); ++it)
                        {
                            if (skipFirst)
                            {
                                skipFirst = false;
                                continue;
                            }
                            std::string match = (*it);
                            StringUtil::trim(match);
                            if (!match.empty())
                            {
                                LoadResource(Ogre::HighLevelGpuProgramManager::getSingletonPtr(), match, groupName);
                                break;
                            }
                        }
                    }
                    ///
                    /// RELOAD FRAGMENT PROGRAMS
                    ///
                    if (StringUtil::startsWith(line, "fragment_program") && !StringUtil::startsWith(line, "fragment_program_ref"))
                    {
                        Ogre::vector<Ogre::String>::type vec = StringUtil::split(line," \t");
                        bool skipFirst = true;
                        for (Ogre::vector<Ogre::String>::type::iterator it = vec.begin(); it < vec.end(); ++it)
                        {
                            if (skipFirst)
                            {
                                skipFirst = false;
                                continue;
                            }
                            std::string match = (*it);
                            StringUtil::trim(match);
                            if (!match.empty())
                            {
                                LoadResource(Ogre::HighLevelGpuProgramManager::getSingletonPtr(), match, groupName);
                                break;
                            }
                        }
                    }
                }
            }
            catch (Ogre::Exception &e)
            {
                StringUtil::StrStreamType msg;
                msg << "Exception: FILE: " << __FILE__ << " LINE: " << __LINE__ << " DESC: " << e.getFullDescription() << std::endl;
                Ogre::LogManager::getSingleton().logMessage(msg.str());
            }
        }
        stream->close();
 
        try
        {
            // Do a render test if it fails, leave materials unloaded
            Ogre::Root::getSingleton().renderOneFrame();
            return;
        }
        catch (Ogre::Exception &e)
        {
            UnloadVertexPrograms(filename);
 
            StringUtil::StrStreamType msg;
            msg << "Render test failed. Unloading vertex programs." << std::endl;
            msg << "Exception: FILE: " << __FILE__ << " LINE: " << __LINE__ << " DESC: " << e.getFullDescription() << std::endl;
            Ogre::LogManager::getSingleton().logMessage(msg.str());
        }
 
        try
        {
            // Do a render test if it fails, leave materials unloaded
            Ogre::Root::getSingleton().renderOneFrame();
        }
        catch (Ogre::Exception &e)
        {
            // Don't load the script this time
            ReloadMaterial(materialName, groupName, filename, false);
 
            StringUtil::StrStreamType msg;
            msg << "Render test failed. Unloading materials." << std::endl;
            msg << "Exception: FILE: " << __FILE__ << " LINE: " << __LINE__ << " DESC: " << e.getFullDescription() << std::endl;
            Ogre::LogManager::getSingleton().logMessage(msg.str());
        }
    }
}