Esempio n. 1
0
	AUR_UINT32 Material::CreateFromFile( const std::string &p_FileName )
	{
		if( p_FileName.size( ) == 0 )
		{
			std::cout << "[Aura::Material::CreateFromFile] <ERROR> "
				"File path is of zero length" << std::endl;

			return AUR_FAIL;
		}

		FILE *pFile = fopen( p_FileName.c_str( ), "r" );

		if( pFile == AUR_NULL )
		{
			std::cout << "[Aura::Material::CreateFromFile] <ERROR> "
				"Failed to open file: \"" << p_FileName << "\"" << std::endl;

			return AUR_FAIL;
		}

		fseek( pFile, 0L, SEEK_END );
		AUR_MEMSIZE FileSize = ftell( pFile );
		rewind( pFile );

		char *pSource = new char[ FileSize + 1 ];
		fread( pSource, 1, FileSize, pFile );

		pSource[ FileSize ] = '\0';

		fclose( pFile );
		pFile = AUR_NULL;

		rapidjson::Document MaterialJSON;
		MaterialJSON.Parse( pSource );

		AUR_UINT32 MaterialHash = HashStringFNV1a( pSource );

		SafeDeleteArray< char >( pSource );

		MATERIAL_SHADER MaterialShader;

		if( MaterialJSON.HasMember( "name" ) )
		{
			m_Name = MaterialJSON[ "name" ].GetString( );
		}
		else
		{
			std::cout << "[Aura::Material::CreateFromFile] <ERROR> "
				"No name available for material" << std::endl;

			return AUR_FAIL;
		}

		if( MaterialJSON.HasMember( "shader" ) )
		{
			rapidjson::Value &ShaderRoot = MaterialJSON[ "shader" ];

			if( ShaderRoot.HasMember( "source" ) )
			{
				if( ShaderRoot[ "source" ].IsArray( ) == false )
				{
					std::cout << "[Aura::Material::CreateFromFile] <ERROR> "
						"Failed to load shader source, it is not recognised "
						"as being an array of values" << std::endl;

					return AUR_FAIL;
				}

				rapidjson::Value &ShaderSourceRoot = ShaderRoot[ "source" ];

				for( rapidjson::SizeType i = 0; i < ShaderSourceRoot.Size( );
					++i )
				{
					std::string ShaderSource;
					SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN;

					if( ShaderSourceRoot[ i ].HasMember( "type" ) )
					{
						std::string ShaderTypeString =
							ShaderSourceRoot[ i ][ "type" ].GetString( );

						if( ShaderTypeString.compare( "vertex" ) == 0 )
						{
							ShaderType = SHADER_TYPE_VERTEX;
						}
						else if( ShaderTypeString.compare( "fragment" ) == 0 )
						{
							ShaderType = SHADER_TYPE_FRAGMENT;
						}
						else
						{
							std::cout << "[Aura::Material::CreateFromFile] "
								"<ERROR> Unknown shader type: \"" <<
								ShaderTypeString << "\"" << std::endl;

							return AUR_FAIL;
						}
					}
					else
					{
						std::cout << "[Aura::Material::CreateFromFile] "
							"<ERROR> Could not find a \"type\" member" <<
							std::endl;

						return AUR_FAIL;
					}

					if( ShaderSourceRoot[ i ].HasMember( "path" ) )
					{
						FILE *pShaderFile = fopen(
							ShaderSourceRoot[ i ][ "path" ].GetString( ),
							"r" );

						if( pShaderFile == AUR_NULL )
						{
							std::cout << "[Aura::Material::CreateFromFile] "
								"<ERROR> Failed to open shader file: \"" <<
								ShaderSourceRoot[ i ][ "path" ].GetString( ) <<
								std::endl;

							return AUR_FAIL;
						}

						fseek( pShaderFile, 0L, SEEK_END );
						AUR_MEMSIZE ShaderLength = ftell( pShaderFile );
						rewind( pShaderFile );

						char *pShaderSource = new char[ ShaderLength + 1 ];
						pShaderSource[ ShaderLength ] = '\0';

						fread( pShaderSource, 1, ShaderLength, pShaderFile );

						fclose( pShaderFile );
						pShaderFile = AUR_NULL;

						ShaderSource.assign( pShaderSource );

						SafeDeleteArray< char >( pShaderSource );
					}
					else if( ShaderSourceRoot[ i ].HasMember( "code" ) )
					{
						ShaderSource =
							ShaderSourceRoot[ i ][ "code" ].GetString( );
					}
					else
					{
						std::cout << "[Aura::Material::CreateFromFile] "
							"<ERROR> Failed to find the shader path or code" <<
							std::endl;

						return AUR_FAIL;
					}

					switch( ShaderType )
					{
						case SHADER_TYPE_VERTEX:
						{
							MaterialShader.VertexSource = ShaderSource;
							break;
						}
						case SHADER_TYPE_FRAGMENT:
						{
							MaterialShader.FragmentSource = ShaderSource;
							break;
						}
						case SHADER_TYPE_UNKNOWN:
						default:
						{
							std::cout << "[Aura::Material::CreateFromFile] "
								"<ERROR> Unknown shader type" << std::endl;

							return AUR_FAIL;
						}
					}
				}
			}
			else
			{
				std::cout << "[Aura::Material::CreateFromFile] <ERROR> "
					"Failed to find a \"source\" member for the shader" <<
					std::endl;

				return AUR_FAIL;
			}
		}
		else
		{
			std::cout << "[Aura::Material::CreateFromFile] <ERROR> "
				"Failed to find a shader" << std::endl;

			return AUR_FAIL;
		}

		if( MaterialJSON.HasMember( "texture" ) )
		{
			rapidjson::Value &TextureRoot = MaterialJSON[ "texture" ];

			if( TextureRoot.IsArray( ) )
			{
				for( rapidjson::SizeType i = 0; i < TextureRoot.Size( ); ++i )
				{
					std::string TextureFile;

					if( TextureRoot[ i ].HasMember( "type" ) )
					{
						std::string TypeString =
							TextureRoot[ i ][ "type" ].GetString( );

						if( TypeString.compare( "albedo" ) == 0 )
						{
						}
						else
						{
							std::cout << "[Aura::Material::CreateFromFile] "
								"<WARN> Unknown texture type: \"" <<
								TypeString << "\"" << std::endl;
						}
					}
					else
					{
						std::cout << "[Aura::Material::CreateFromFile] "
							"<ERROR> No \"type\" member found for texture" <<
							std::endl;

						return AUR_FAIL;
					}

					if( TextureRoot[ i ].HasMember( "path" ) )
					{
						TextureFile = TextureRoot[ i ][ "path" ].GetString( );
					}
					else
					{
						std::cout << "[Aura::Material::CreateFromFile] " <<
							"<ERROR> No path for texture" << std::endl;

						return AUR_FAIL;
					}

					AUR_UINT32 TextureHash;

					if( m_pMaterialManager->LoadTextureFromFile( TextureFile,
						TextureHash ) != AUR_OK )
					{
						std::cout << "[Aura::Material::CreateFromFile] "
							"<ERROR> Could not load texture: \"" <<
							TextureFile << "\"" << std::endl;

						return AUR_FAIL;
					}

					m_TextureHashes.push_back( TextureHash );
				}
			}
			else
			{
				std::cout << "[Aura::Material::CreateFromFile] <ERROR> "
					"Textures are not in an array, aborting" << std::endl;

				return AUR_FAIL;
			}
		}

		m_pMaterialManager->CreateShader( MaterialShader, m_ShaderHash );

		m_Hash = MaterialHash;

		return AUR_OK;
	}
Esempio n. 2
0
	KIL_UINT32 Shader::AddShaderSource( const SHADER_TYPE p_Type,
		const char *p_pSource )
	{
		std::string ShaderTypeName;
		GLenum ShaderTypeGL;
		GLuint *pShader;

		switch( p_Type )
		{
			case SHADER_TYPE_VERTEX:
			{
				ShaderTypeName = "vertex";
				ShaderTypeGL = GL_VERTEX_SHADER;
				pShader = &m_VertexShader;

				break;
			}
			case SHADER_TYPE_FRAGMENT:
			{
				ShaderTypeName = "fragment";
				ShaderTypeGL = GL_FRAGMENT_SHADER;
				pShader = &m_FragmentShader;

				break;
			}
		}

		( *pShader ) = glCreateShader( ShaderTypeGL );

		glShaderSource( ( *pShader ), 1, &p_pSource, KIL_NULL );

		glCompileShader( ( *pShader ) );

		GLint Compile;
		glGetShaderiv( ( *pShader ), GL_COMPILE_STATUS, &Compile );

		if( Compile == GL_FALSE )
		{
			GLint LogLength;
			glGetShaderiv( ( *pShader ), GL_INFO_LOG_LENGTH, &LogLength );

			if( LogLength > 1 )
			{
				char *pLog = new char[ LogLength ];
				glGetShaderInfoLog( ( *pShader ), LogLength, KIL_NULL, pLog );
				std::cout << "[Killer::Shader::AddShaderSource] <ERROR> "
					"Failed to compile " << ShaderTypeName << " shader:" <<
					std::endl << pLog << std::endl;
				delete [ ] pLog;
			}

			glDeleteShader( ( *pShader ) );

			return KIL_FAIL;
		}

		// Some more processing is required to extract the attributes and
		// manually set their locations in the shader
		if( p_Type == SHADER_TYPE_VERTEX )
		{
			this->ExtractAttributesFromSource( p_pSource );
		}

		m_Hash = HashStringFNV1a( p_pSource, m_Hash );

		return KIL_OK;
	}