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; }
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; }