示例#1
0
void FShaderManager::CompileShaders()
{
	mActiveShader = NULL;

	mTextureEffects.Clear();
	mTextureEffectsNAT.Clear();
	for (int i = 0; i < MAX_EFFECTS; i++)
	{
		mEffectShaders[i] = NULL;
	}

	for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
	{
		FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true);
		mTextureEffects.Push(shc);
		if (i <= 3)
		{
			FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false);
			mTextureEffectsNAT.Push(shc);
		}
	}

	for(unsigned i = 0; i < usershaders.Size(); i++)
	{
		FString name = ExtractFileBase(usershaders[i]);
		FName sfn = name;

		FShader *shc = Compile(sfn, usershaders[i], true);
		mTextureEffects.Push(shc);
	}

	for(int i=0;i<MAX_EFFECTS;i++)
	{
		FShader *eff = new FShader(effectshaders[i].ShaderName);
		if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
						effectshaders[i].fp2, effectshaders[i].defines))
		{
			delete eff;
		}
		else mEffectShaders[i] = eff;
	}
}
示例#2
0
void FShaderManager::CompileShaders()
{
	mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL;
	if (gl.shadermodel > 0)
	{
		for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
		{
			FShaderContainer * shc = new FShaderContainer(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc);
			mTextureEffects.Push(shc);
			if (gl.shadermodel <= 2) return;	// SM2 will only initialize the default shader
		}

		for(unsigned i = 0; i < usershaders.Size(); i++)
		{
			FString name = ExtractFileBase(usershaders[i]);
			FName sfn = name;

			if (gl.shadermodel > 2)
			{
				FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]);
				mTextureEffects.Push(shc);
			}
		}

		if (gl.shadermodel > 2)
		{
			for(int i=0;i<NUM_EFFECTS;i++)
			{
				FShader *eff = new FShader();
				if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
								effectshaders[i].fp2, effectshaders[i].defines))
				{
					delete eff;
				}
				else mEffectShaders[i] = eff;
			}
		}
	}
}
示例#3
0
void FShaderCache::Save(FArchive& Ar, const map<FGuid, FShader*>& InShaders)
{
	Ar << m_nPlatform;

	// serialize the global shader crc
	UINT NumShaderBuilderCRC = m_mapShaderBuilderCRC.size();
	Ar << NumShaderBuilderCRC;
	map<FShaderBuilder*, DWORD>::iterator it;
	for( it = m_mapShaderBuilderCRC.begin(); it != m_mapShaderBuilderCRC.end(); ++it )
	{
		FShaderBuilder* ShaderBuilder = it->first;
		Ar << ShaderBuilder;
		Ar << it->second;
	}

	// serialize the global shaders
	UINT NumShaders = InShaders.size();
	Ar << NumShaders;
	for( map<FGuid, FShader*>::const_iterator it = InShaders.begin(); it != InShaders.end(); ++it )
	{
		FShader* Shader = it->second;

		// shader builder的序列化,在加载时可用于检测此类型的shader是否仍存在
		FShaderBuilder* ShaderBuilder = Shader->GetShaderBuilder();
		FGuid ShaderId = Shader->GetId();
		Ar << ShaderBuilder << ShaderId;

		// 占个位先。。。应该记录序列化此shader的结束位置
		INT SkipOffset = Ar.Tell();
		Ar << SkipOffset;

		Shader->Serialize(Ar);

		INT EndOffset = Ar.Tell();
		Ar.Seek(SkipOffset);		// 定位回之前位置
		Ar << EndOffset;			// 记录此shader的结束位置
		Ar.Seek(EndOffset);			// 定位结束位置,继续下一个shader的序列化
	}
}
void Program::create(VShader& vs, FShader& fs) {
  auto program = glCreateProgram();

  // attach both shaders
  glAttachShader(program, vs.getHandle());
  glAttachShader(program, fs.getHandle());

  // link program
  glLinkProgram(program);

  // check for errors
  GLint linkStatus;
  glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
  if(linkStatus != GL_TRUE) {
    // obtain error message
    GLint logLength;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
    vector<char> compileLog(logLength);
    glGetShaderInfoLog(program, logLength, nullptr, compileLog.data());
    logError("[Program] Could not link shaders <", vs.getFilename(),
             ", ", fs.getFilename(), "> ->");
    logError("[Program] ", compileLog.data());
    throw GLException("Could not link shaders");
  }
  log("[Program] Shaders <", vs.getFilename(), ", ", fs.getFilename(),
      "> were successfully linked.");

  // detach shaders (TODO: is this a good idea?)
  glDetachShader(program, vs.getHandle());
  glDetachShader(program, fs.getHandle());

  // check for any error
  checkGLError("[Program] GL error while linking program <", GLERR, ">!");

  // linking was successful: commit changes
  m_handle = program;
}
FSlateMaterialShaderPS* FSlateRHIRenderingPolicy::GetMaterialPixelShader( const FMaterial* Material, ESlateShader::Type ShaderType, ESlateDrawEffect::Type DrawEffects )
{
	const FMaterialShaderMap* MaterialShaderMap = Material->GetRenderingThreadShaderMap();

	const bool bDrawDisabled = (DrawEffects & ESlateDrawEffect::DisabledEffect) != 0;
	const bool bUseTextureAlpha = (DrawEffects & ESlateDrawEffect::IgnoreTextureAlpha) == 0;

	FShader* FoundShader = nullptr;
	switch (ShaderType)
	{
	case ESlateShader::Default:
		if (bDrawDisabled)
		{
			FoundShader = MaterialShaderMap->GetShader(&TSlateMaterialShaderPS<0, true>::StaticType);
		}
		else
		{
			FoundShader = MaterialShaderMap->GetShader(&TSlateMaterialShaderPS<0, false>::StaticType);
		}
		break;
	case ESlateShader::Border:
		if (bDrawDisabled)
		{
			FoundShader = MaterialShaderMap->GetShader(&TSlateMaterialShaderPS<1, true>::StaticType);
		}
		else
		{
			FoundShader = MaterialShaderMap->GetShader(&TSlateMaterialShaderPS<1, false>::StaticType);
		}
		break;
	default:
		checkf(false, TEXT("Unsupported Slate shader type for use with materials"));
		break;
	}

	return FoundShader ? (FSlateMaterialShaderPS*)FoundShader->GetShaderChecked() : nullptr;
}
示例#6
0
void FShaderType::GetOutdatedTypes(TArray<FShaderType*>& OutdatedShaderTypes, TArray<const FVertexFactoryType*>& OutdatedFactoryTypes)
{
	for(TLinkedList<FShaderType*>::TIterator It(GetTypeList()); It; It.Next())
	{
		FShaderType* Type = *It;
		for(TMap<FShaderId,FShader*>::TConstIterator ShaderIt(Type->ShaderIdMap);ShaderIt;++ShaderIt)
		{
			FShader* Shader = ShaderIt.Value();
			const FVertexFactoryParameterRef* VFParameterRef = Shader->GetVertexFactoryParameterRef();
			const FSHAHash& SavedHash = Shader->GetHash();
			const FSHAHash& CurrentHash = Type->GetSourceHash();
			const bool bOutdatedShader = SavedHash != CurrentHash;
			const bool bOutdatedVertexFactory =
				VFParameterRef && VFParameterRef->GetVertexFactoryType() && VFParameterRef->GetVertexFactoryType()->GetSourceHash() != VFParameterRef->GetHash();

			if (bOutdatedShader)
			{
				OutdatedShaderTypes.AddUnique(Shader->Type);
			}

			if (bOutdatedVertexFactory)
			{
				OutdatedFactoryTypes.AddUnique(VFParameterRef->GetVertexFactoryType());
			}
		}
	}

	for (int32 TypeIndex = 0; TypeIndex < OutdatedShaderTypes.Num(); TypeIndex++)
	{
		UE_LOG(LogShaders, Warning, TEXT("		Recompiling %s"), OutdatedShaderTypes[TypeIndex]->GetName());
	}
	for (int32 TypeIndex = 0; TypeIndex < OutdatedFactoryTypes.Num(); TypeIndex++)
	{
		UE_LOG(LogShaders, Warning, TEXT("		Recompiling %s"), OutdatedFactoryTypes[TypeIndex]->GetName());
	}
}
FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard)
{
	FString defines;
	// this can't be in the shader code due to ATI strangeness.
	if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n";
	if (!usediscard) defines += "#define NO_ALPHATEST\n";

	FShader *shader = NULL;
	try
	{
		shader = new FShader(ShaderName);
		if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, defines.GetChars()))
		{
			I_FatalError("Unable to load shader %s\n", ShaderName);
		}
	}
	catch(CRecoverableError &err)
	{
		if (shader != NULL) delete shader;
		shader = NULL;
		I_FatalError("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage());
	}
	return shader;
}
示例#8
0
TShaderMap<FGlobalShaderType>* GetGlobalShaderMap(EShaderPlatform Platform, bool bRefreshShaderMap)
{
	// No global shaders needed on dedicated server
	if (FPlatformProperties::IsServerOnly())
	{
		if (!GGlobalShaderMap[Platform])
		{
			GGlobalShaderMap[Platform] = new TShaderMap<FGlobalShaderType>();
			return GGlobalShaderMap[Platform];
		}
		return NULL;
	}

	if (bRefreshShaderMap)
	{
		// delete the current global shader map
		delete GGlobalShaderMap[Platform];
		GGlobalShaderMap[Platform] = NULL;

		// make sure we look for updated shader source files
		FlushShaderFileCache();
	}

	// If the global shader map hasn't been created yet, create it.
	if(!GGlobalShaderMap[Platform])
	{
		// GetGlobalShaderMap is called the first time during startup in the main thread.
		check(IsInGameThread());

		FScopedSlowTask SlowTask(70);

		// verify that all shader source files are intact
		SlowTask.EnterProgressFrame(20);
		VerifyShaderSourceFiles();

		GGlobalShaderMap[Platform] = new TShaderMap<FGlobalShaderType>();

		bool bLoadedFromCacheFile = false;

		// Try to load the global shaders from a local cache file if it exists
		// This method is used exclusively with cooked content, since the DDC is not present
		if (FPlatformProperties::RequiresCookedData())
		{
			SlowTask.EnterProgressFrame(50);

			TArray<uint8> GlobalShaderData;
			FString GlobalShaderCacheFilename = FPaths::GetRelativePathToRoot() / GetGlobalShaderCacheFilename(Platform);
			FPaths::MakeStandardFilename(GlobalShaderCacheFilename);
			bLoadedFromCacheFile = FFileHelper::LoadFileToArray(GlobalShaderData, *GlobalShaderCacheFilename, FILEREAD_Silent);

			if (!bLoadedFromCacheFile)
			{
				// Handle this gracefully and exit.
				FString SandboxPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForWrite(*GlobalShaderCacheFilename);				
				// This can be too early to localize in some situations.
				const FText Message = FText::Format( NSLOCTEXT("Engine", "GlobalShaderCacheFileMissing", "The global shader cache file '{0}' is missing.\n\nYou're running a version of the application built to load COOKED content only, however no COOKED content was found. Consider cooking content for this build, or build and run the UNCOOKED version of the application instead."), FText::FromString( SandboxPath ) );
				if (FPlatformProperties::SupportsWindowedMode())
				{
					UE_LOG(LogMaterial, Error, TEXT("%s"), *Message.ToString());
					FMessageDialog::Open(EAppMsgType::Ok, Message);
					FPlatformMisc::RequestExit(false);
					return NULL;
				}
				else
				{
					UE_LOG(LogMaterial, Fatal, TEXT("%s"), *Message.ToString());
				}
			}

			FMemoryReader MemoryReader(GlobalShaderData);
			SerializeGlobalShaders(MemoryReader, GGlobalShaderMap[Platform]);
		}
		// Uncooked platform
		else
		{
			FGlobalShaderMapId ShaderMapId(Platform);

			TArray<uint8> CachedData;
			SlowTask.EnterProgressFrame(40);
			const FString DataKey = GetGlobalShaderMapKeyString(ShaderMapId, Platform);

			// Find the shader map in the derived data cache
			SlowTask.EnterProgressFrame(10);
			if (GetDerivedDataCacheRef().GetSynchronous(*DataKey, CachedData))
			{
				FMemoryReader Ar(CachedData, true);

				// Deserialize from the cached data
				SerializeGlobalShaders(Ar, GGlobalShaderMap[Platform]);
			}
		}

		// If any shaders weren't loaded, compile them now.
		VerifyGlobalShaders(Platform, bLoadedFromCacheFile);

		extern int32 GCreateShadersOnLoad;
		if (GCreateShadersOnLoad && Platform == GMaxRHIShaderPlatform)
		{
			for (TMap<FShaderType*, TRefCountPtr<FShader> >::TConstIterator ShaderIt(GGlobalShaderMap[Platform]->GetShaders()); ShaderIt; ++ShaderIt)
			{
				FShader* Shader = ShaderIt.Value();

				if (Shader)
				{
					Shader->InitializeResource();
				}
			}
		}
	}
	return GGlobalShaderMap[Platform];
}
示例#9
0
void FShaderCache::Load(FArchive& Ar)
{
	Ar << m_nPlatform;

	UINT NumShaderBuilderCRC = 0;
	Ar << NumShaderBuilderCRC;
	for(UINT IndexBuilder = 0; IndexBuilder < NumShaderBuilderCRC; ++IndexBuilder)
	{
		FShaderBuilder* ShaderBuilder = NULL;
		Ar << ShaderBuilder;
		DWORD CRC = 0;
		Ar << CRC;

		if( ShaderBuilder )
		{
			m_mapShaderBuilderCRC[ShaderBuilder] = CRC;
		}
	}

	// serialize the global shaders
	UINT NumShaders = 0;
	UINT NumDesertedShaders = 0; 
	UINT NumRedundantShaders = 0;
	vector<FString> OutdatedShaderBuilders;

	Ar << NumShaders;
	for(UINT IndexShader = 0; IndexShader < NumShaders; ++IndexShader)
	{
		FShaderBuilder* ShaderBuilder = NULL;
		FGuid ShaderId;
		Ar << ShaderBuilder << ShaderId;

		INT SkipOffset = 0;
		Ar << SkipOffset;

		if( !ShaderBuilder )
		{
			++NumDesertedShaders;
			Ar.Seek(SkipOffset);		// this shader builder doesn't exist any more, skip the shader
		}
		else
		{
			DWORD CurrentCRC = 0;
			DWORD SavedCRC = 0;

			// 比较当前与之前版本的CRC,检测是否有改动
			CurrentCRC = ShaderBuilder->GetSourceCRC();
			map<FShaderBuilder*, DWORD>::const_iterator it = m_mapShaderBuilderCRC.find(ShaderBuilder);
			if( it != m_mapShaderBuilderCRC.end() )
			{
				SavedCRC = it->second;
			}

			FShader* Shader = ShaderBuilder->FindShaderById(ShaderId);
			if( Shader )
			{
				++NumRedundantShaders;
				Ar.Seek(SkipOffset);		// has already exist, skip it		
			}
			else if( SavedCRC != CurrentCRC )
			{
				++NumDesertedShaders;
				Ar.Seek(SkipOffset);
				if( SavedCRC != 0 )			// denote SHADER BUILDER exists, but it has changed
				{
					OutdatedShaderBuilders.push_back(ShaderBuilder->GetShaderName());
				}
			}
			else
			{
				// the shader is compatiable, create it
				Shader = ShaderBuilder->ConstructSerialization();

				UBOOL bShaderHasOutdatedParameters = Shader->Serialize(Ar);
				if( bShaderHasOutdatedParameters )
				{
					ShaderBuilder->UnregisterShader(Shader);
					delete Shader;
				}
				check(Ar.Tell() == SkipOffset);
			}
		}
	}

	if( OutdatedShaderBuilders.size() > 0 )
	{
		debugf(TEXT("Skip %d outdated FShaderBuilder"), OutdatedShaderBuilders.size());
		for(UINT IndexBuilder = 0; IndexBuilder < OutdatedShaderBuilders.size(); ++IndexBuilder)
		{
			debugf(TEXT("	%s"), OutdatedShaderBuilders.at(IndexBuilder).c_str());
		}
	}

	if( NumShaders > 0 )
	{
		debugf(TEXT("Loaded %d shaders (%d deserted, %d redundant)"), NumShaders, NumDesertedShaders, NumRedundantShaders);
	}
}