/** MCPP callback for retrieving file contents. */
	static int GetFileContents(void* InUserData, const ANSICHAR* InFilename, const ANSICHAR** OutContents, size_t* OutContentSize)
	{
		FMcppFileLoader* This = (FMcppFileLoader*)InUserData;
		FString Filename = GetRelativeShaderFilename(ANSI_TO_TCHAR(InFilename));

		FShaderContents* CachedContents = This->CachedFileContents.Find(Filename);
		if (!CachedContents)
		{
			FString FileContents;
			if (This->ShaderInput.Environment.IncludeFileNameToContentsMap.Contains(Filename))
			{
				FileContents = This->ShaderInput.Environment.IncludeFileNameToContentsMap.FindRef(Filename);
			}
			else
			{
				LoadShaderSourceFile(*Filename,FileContents);
			}

			if (FileContents.Len() > 0)
			{
				CachedContents = &This->CachedFileContents.Add(Filename,StringToArray<ANSICHAR>(*FileContents, FileContents.Len()));
			}
		}

		if (OutContents)
		{
			*OutContents = CachedContents ? CachedContents->GetTypedData() : NULL;
		}
		if (OutContentSize)
		{
			*OutContentSize = CachedContents ? CachedContents->Num() : 0;
		}

		return !!CachedContents;
	}
GLuint ShaderCompiler::LoadShader(GLenum eShaderType, char* cFilename)
{
	GLuint uiShader;
	const char* cShaderBuffer;

	if (!(cShaderBuffer = LoadShaderSourceFile(cFilename)))
		return false;

	this->m_OpenGL->CreateShader(uiShader, eShaderType, cShaderBuffer);

	delete[] cShaderBuffer;
	cShaderBuffer = 0;

	return uiShader;
}
	/** Initialization constructor. */
	explicit FMcppFileLoader(const FShaderCompilerInput& InShaderInput)
		: ShaderInput(InShaderInput)
	{
		FString ShaderDir = FPlatformProcess::ShaderDir();

		InputShaderFile = ShaderDir / FPaths::GetCleanFilename(ShaderInput.SourceFilename);
		if (FPaths::GetExtension(InputShaderFile) != TEXT("usf"))
		{
			InputShaderFile += TEXT(".usf");
		}

		FString InputShaderSource;
		if (LoadShaderSourceFile(*ShaderInput.SourceFilename,InputShaderSource))
		{
			InputShaderSource = FString::Printf(TEXT("%s\n#line 1\n%s"), *ShaderInput.SourceFilePrefix, *InputShaderSource);
			CachedFileContents.Add(GetRelativeShaderFilename(InputShaderFile),StringToArray<ANSICHAR>(*InputShaderSource, InputShaderSource.Len()));
		}
	}
示例#4
0
	STDMETHOD(Open)(D3DXINCLUDE_TYPE Type, LPCSTR Name, LPCVOID ParentData, LPCVOID* Data, UINT* NumBytes)
	{
		FString Filename(ANSI_TO_TCHAR(Name));
		FString ShaderCode;

		map<FString, FString>::iterator it = _Environment.IncludeFiles.find(Filename);
		if( it != _Environment.IncludeFiles.end() )
		{
			ShaderCode = it->second;
		}
		else
		{
			ShaderCode = LoadShaderSourceFile(Filename.c_str());
		}

		ANSICHAR* Code = new ANSICHAR[ShaderCode.length() + 1];
		appStrncpyANSI(Code, TCHAR_TO_ANSI(ShaderCode.c_str()), ShaderCode.length() + 1);

		*Data = (LPCVOID)Code;
		*NumBytes = ShaderCode.length();

		return D3D_OK;
	}
示例#5
0
bool RenderShader::InitializeShader(char* vsFilename, char* fsFilename)
{
	const char* vertexShaderBuffer;
	const char* fragmentShaderBuffer;
	int status;

	// Load the vertex shader source file into a text buffer.
	vertexShaderBuffer = LoadShaderSourceFile(vsFilename);
	if(!vertexShaderBuffer)
	{
		return false;
	}

	// Load the fragment shader source file into a text buffer.
	fragmentShaderBuffer = LoadShaderSourceFile(fsFilename);
	if(!fragmentShaderBuffer)
	{
		return false;
	}

	// Create a vertex and fragment shader object.
	m_vertexShader = g_openGL->glCreateShader(GL_VERTEX_SHADER);
	m_fragmentShader = g_openGL->glCreateShader(GL_FRAGMENT_SHADER);

	// Copy the shader source code strings into the vertex and fragment shader objects.
	g_openGL->glShaderSource(m_vertexShader, 1, &vertexShaderBuffer, NULL);
	g_openGL->glShaderSource(m_fragmentShader, 1, &fragmentShaderBuffer, NULL);

	// Release the vertex and fragment shader buffers.
	delete [] vertexShaderBuffer;
	vertexShaderBuffer = 0;
	
	delete [] fragmentShaderBuffer;
	fragmentShaderBuffer = 0;

	// Compile the shaders.
	g_openGL->glCompileShader(m_vertexShader);
	g_openGL->glCompileShader(m_fragmentShader);

	// Check to see if the vertex shader compiled successfully.
	g_openGL->glGetShaderiv(m_vertexShader, GL_COMPILE_STATUS, &status);
	if(status != 1)
	{
		// If it did not compile then write the syntax error message out to a text file for review.
		OutputShaderErrorMessage(m_vertexShader, vsFilename);
		return false;
	}

	// Check to see if the fragment shader compiled successfully.
	g_openGL->glGetShaderiv(m_fragmentShader, GL_COMPILE_STATUS, &status);
	if(status != 1)
	{
		// If it did not compile then write the syntax error message out to a text file for review.
		OutputShaderErrorMessage(m_fragmentShader, fsFilename);
		return false;
	}

	// Create a shader program object.
	m_shaderProgram = g_openGL->glCreateProgram();

	// Attach the vertex and fragment shader to the program object.
	g_openGL->glAttachShader(m_shaderProgram, m_vertexShader);
	g_openGL->glAttachShader(m_shaderProgram, m_fragmentShader);

	// Bind the shader input variables.
	g_openGL->glBindAttribLocation(m_shaderProgram, 0, "inputPosition");
	g_openGL->glBindAttribLocation(m_shaderProgram, 1, "inputNormal");
	g_openGL->glBindAttribLocation(m_shaderProgram, 2, "inputColor");
	g_openGL->glBindAttribLocation(m_shaderProgram, 3, "inputUV");

	// Link the shader program.
	g_openGL->glLinkProgram(m_shaderProgram);

	// Check the status of the link.
	g_openGL->glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &status);
	if(status != 1)
	{
		// If it did not link then write the syntax error message out to a text file for review.
		OutputLinkerErrorMessage(m_shaderProgram);
		return false;
	}

	return true;
}
示例#6
0
static UBOOL D3D9CompileShaderWrapper(
	const TCHAR* ShaderFilename,
	const TCHAR* FunctionName,
	const TCHAR* ShaderProfile,
	DWORD CompileFlags,
	const FShaderCompilerEnvironment& InEnvironment,
	const vector<D3DXMACRO>& Macros,
	FShaderCompilerOutput& Output,
	vector<FD3D9ConstantDesc>& Constants,
	FString& DisassemblyString,
	FString& ErrorString
	)
{
	const FString& SourceFile = LoadShaderSourceFile(ShaderFilename);

	TRefCountPtr<ID3DXBuffer> Shader;
	TRefCountPtr<ID3DXBuffer> Errors;
	FD3DIncludeEnvironment Environment(InEnvironment);
	TRefCountPtr<ID3DXConstantTable> ConstantTable;
	FTCHARToANSI AnsiSourceFile(SourceFile.c_str());
	HRESULT Result = D3DXCompileShader(
						AnsiSourceFile, 
						SourceFile.size(), 
						&Macros[0], 
						&Environment, 
						TCHAR_TO_ANSI(FunctionName), 
						TCHAR_TO_ANSI(ShaderProfile),
						CompileFlags, 
						Shader.GetInitReference(),
						Errors.GetInitReference(), 
						ConstantTable.GetInitReference());

	if( FAILED(Result) )
	{
		ErrorString = TEXT("Compile Failed without warnings!");
		void* ErrorBuffer = Errors ? Errors->GetBufferPointer() : NULL;
		if( ErrorBuffer )
		{
			FANSIToTCHAR Convert((ANSICHAR*)ErrorBuffer);
			ErrorString = Convert;
		}
	}
	else
	{
		// get the ShaderCode
		INT NumShaderBytes = Shader->GetBufferSize();
		Output.ShaderCode.resize(NumShaderBytes);
		appMemcpy(&Output.ShaderCode[0], Shader->GetBufferPointer(), NumShaderBytes);

		// collect the constant table
		D3DXCONSTANTTABLE_DESC ConstantTableDesc;
		VERIFYD3DRESULT(ConstantTable->GetDesc(&ConstantTableDesc));
		for(UINT ConstantIndex = 0; ConstantIndex < ConstantTableDesc.Constants; ++ConstantIndex)
		{
			D3DXHANDLE ConstantHandle = ConstantTable->GetConstant(NULL, ConstantIndex);

			D3DXCONSTANT_DESC ConstantDesc;
			UINT NumConstants = 1;
			VERIFYD3DRESULT(ConstantTable->GetConstantDesc(ConstantHandle, &ConstantDesc, &NumConstants));

			FD3D9ConstantDesc NamedConstantDesc;
			appStrcpyANSI(NamedConstantDesc.Name, ConstantDesc.Name);
			NamedConstantDesc.bIsSampler = ConstantDesc.RegisterSet == D3DXRS_SAMPLER;
			NamedConstantDesc.RegisterIndex = ConstantDesc.RegisterIndex;
			NamedConstantDesc.RegisterCount = ConstantDesc.RegisterCount;
			Constants.push_back(NamedConstantDesc);
		}

		// disassemble a shader
		TRefCountPtr<ID3DXBuffer> DisassemblyBuffer;
		VERIFYD3DRESULT(D3DXDisassembleShader((const DWORD*)Shader->GetBufferPointer(), FALSE, NULL, DisassemblyBuffer.GetInitReference()));
		DisassemblyString = ANSI_TO_TCHAR((ANSICHAR*)DisassemblyBuffer->GetBufferPointer());
	}

	return TRUE;
}
示例#7
0
// vps编译接口
UBOOL D3D9CompileShader(
	const TCHAR* ShaderFilename,
	const TCHAR* FunctionName,
	FShaderTarget Target,
	const FShaderCompilerEnvironment& Environment,
	FShaderCompilerOutput& Output,
	UBOOL bDebugDump = FALSE
	)
{
	// translate the input Environment's defines to D3DXMACROs
	vector<D3DXMACRO> Macros;
	for( map<FString, FString>::const_iterator it = Environment.Definitions.begin(); it != Environment.Definitions.end(); ++it )
	{
		FString Name = it->first;
		FString Definition = it->second;

		D3DXMACRO Macro;
		Macro.Name = new ANSICHAR[Name.size()+1];
		appStrncpyANSI((ANSICHAR*)Macro.Name, TCHAR_TO_ANSI(Name.c_str()), Name.size()+1);
		Macro.Definition = new ANSICHAR[Definition.size()+1];
		appStrncpyANSI((ANSICHAR*)Macro.Definition, TCHAR_TO_ANSI(Definition.c_str()), Definition.size()+1);

		Macros.push_back(Macro);
	}

	DWORD CompileFlags = D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY;
	const TCHAR* ShaderPath = appShaderDir();

	TCHAR Profile[32];
	if( Target.Platform == SP_SM3 )
	{
		if( Target.Frequency == SF_Pixel )
		{
			appStrcpy(Profile, TEXT("ps_3_0"));
		}
		else if( Target.Frequency == SF_Vertex )
		{
			appStrcpy(Profile, TEXT("vs_3_0"));
		}
	}
	else if( Target.Platform == SP_SM2 )
	{
		if( Target.Frequency == SF_Pixel )
		{
			appStrcpy(Profile, TEXT("ps_2_0"));
		}
		else if( Target.Frequency == SF_Vertex )
		{
			appStrcpy(Profile, TEXT("vs_2_0"));
		}
	}

	vector<FD3D9ConstantDesc> Constants;
	FString DisassemblyString;
	FString ErrorString;
	UBOOL bCompileFailed = TRUE;
	bCompileFailed = !D3D9CompileShaderWrapper(
		ShaderFilename,
		FunctionName,
		Profile,
		CompileFlags,
		Environment,
		Macros,
		Output,
		Constants,
		DisassemblyString,
		ErrorString
		);

	if( bCompileFailed )
	{
		FString ErrorShaderFile = FStringUtil::Sprintf(TEXT("%sErrorShader-%s.vps"), ShaderPath, ShaderFilename);
		appSaveStringToFile(ErrorString, ErrorShaderFile.c_str());
	}

	if( bCompileFailed || bDebugDump )
	{
		const FString SourceFile = LoadShaderSourceFile(ShaderFilename);
		D3D9PreProcessShader(ShaderFilename, SourceFile, Macros, Environment, ShaderPath);
	}

	for(UINT i = 0; i < Macros.size(); ++i)
	{
		delete Macros[i].Name;
		delete Macros[i].Definition;
	}
	Macros.clear();

	UINT NumInstructions = 0;
	if( !bCompileFailed )
	{
		// fetch the number of instruction
		Parse(DisassemblyString.c_str(), TEXT("// approximately"), (DWORD&)NumInstructions);

		// 在ShaderModel3.0下支持的指令数,最少为512,最多至D3DCAPS9.MaxVertexShader30InstructionSlots
		// 因指令数在运行时刻检查,所以在编译器给出提示
		if( NumInstructions > 512 && Target.Platform == SP_SM3 )
		{
			bCompileFailed = TRUE;
			debugf(NAME_Warning, TEXT("Shader use too many instructions for Shader Model 3.0 (Used %u, Minimum guaranteed in SM3.0 is 512)"), NumInstructions);
		}
	}

	if( bCompileFailed )
	{
		return FALSE;
	}

	check(Output.ShaderCode.size() > 0);

	for(UINT ConstantIndex = 0; ConstantIndex < Constants.size(); ++ConstantIndex)
	{
		const FD3D9ConstantDesc& Desc = Constants.at(ConstantIndex);
		if( Desc.bIsSampler )
		{
			Output.ParameterMap.AddParameter(
				ANSI_TO_TCHAR(Desc.Name),
				Desc.RegisterIndex,
				Desc.RegisterCount,
				1
				);
		}
		else
		{
			Output.ParameterMap.AddParameter(
				ANSI_TO_TCHAR(Desc.Name),
				Desc.RegisterIndex * sizeof(FLOAT) * 4,
				Desc.RegisterCount * sizeof(FLOAT) * 4,
				0
				);
		}
	}

	Output.Target = Target;
	Output.NumInstructions = NumInstructions;

	if( bDebugDump )
	{
		FString ASMShaderFile = FStringUtil::Sprintf(TEXT("%s%s.asm"), ShaderPath, ShaderFilename);

		appSaveStringToFile(DisassemblyString, ASMShaderFile.c_str());
	}

	return TRUE;
}
示例#8
0
bool Shader::InitializeShader(string shaderVSFileName, string shaderPSFileName)
{
	const char* shaderBuffer_VS = LoadShaderSourceFile("Shaders/" + shaderVSFileName);
	const char* shaderBuffer_PS = LoadShaderSourceFile("Shaders/" + shaderPSFileName);

	if (!shaderBuffer_VS)
	{
		cout << "Shader: " << shaderVSFileName << " could not be loaded" << endl;
		return false;
	}

	if (!shaderBuffer_PS)
	{
		cout << "Shader: " << shaderVSFileName << " could not be loaded" << endl;
		return false;
	}

	m_vertexID = glCreateShader(GL_VERTEX_SHADER);
	m_fragID = glCreateShader(GL_FRAGMENT_SHADER);

	glShaderSource(m_vertexID, 1, &shaderBuffer_VS, NULL);
	glShaderSource(m_fragID, 1, &shaderBuffer_PS, NULL);

	delete[] shaderBuffer_VS;
	delete[] shaderBuffer_PS;

	glCompileShader(m_vertexID);
	glCompileShader(m_fragID);
	
	int status;

	glGetShaderiv(m_vertexID, GL_COMPILE_STATUS, &status);

	if (status != 1)
	{
		OutputShaderErrorMessage(m_vertexID, (char*)shaderVSFileName.c_str());
		return false;
	}

	glGetShaderiv(m_fragID, GL_COMPILE_STATUS, &status);

	if (status != 1)
	{
		OutputShaderErrorMessage(m_fragID, (char*)shaderPSFileName.c_str());
		return false;
	}

	m_programID = glCreateProgram();//set the Program ID to the first element by default

	glAttachShader(m_programID, m_vertexID);
	glAttachShader(m_programID, m_fragID);

	glLinkProgram(m_programID);
	glGetProgramiv(m_programID, GL_LINK_STATUS, &status);

	if(status != 1)
	{
		// If it did not link then write the syntax error message out to a text file for review.
		OutputLinkerErrorMessage(m_programID);

		DeleteProgram();

		return false;
	}

	return true;
}