@@ -375,8 +375,7 @@ struct Program {
375375impl Program {
376376 fn attach_and_bind_shaders ( & mut self ,
377377 vs_id : gl:: GLuint ,
378- fs_id : gl:: GLuint ,
379- panic_on_fail : bool ) -> bool {
378+ fs_id : gl:: GLuint ) -> Result < ( ) , ShaderError > {
380379 gl:: attach_shader ( self . id , vs_id) ;
381380 gl:: attach_shader ( self . id , fs_id) ;
382381
@@ -406,17 +405,14 @@ impl Program {
406405
407406 gl:: link_program ( self . id ) ;
408407 if gl:: get_program_iv ( self . id , gl:: LINK_STATUS ) == ( 0 as gl:: GLint ) {
409- println ! ( "Failed to link shader program: {}" , gl:: get_program_info_log( self . id) ) ;
408+ let error_log = gl:: get_program_info_log ( self . id ) ;
409+ println ! ( "Failed to link shader program: {}" , error_log) ;
410410 gl:: detach_shader ( self . id , vs_id) ;
411411 gl:: detach_shader ( self . id , fs_id) ;
412- if panic_on_fail {
413- panic ! ( "-- Program link failed - exiting --" ) ;
414- }
415- false
416- } else {
417- //println!("{}", gl::get_program_info_log(self.id));
418- true
412+ return Err ( ShaderError :: Link ( error_log) ) ;
419413 }
414+
415+ Ok ( ( ) )
420416 }
421417}
422418
@@ -782,6 +778,12 @@ pub struct Capabilities {
782778 pub supports_multisampling : bool ,
783779}
784780
781+ #[ derive( Clone , Debug ) ]
782+ pub enum ShaderError {
783+ Compilation ( String , String ) , // name, error mssage
784+ Link ( String ) , // error message
785+ }
786+
785787pub struct Device {
786788 // device state
787789 bound_textures : [ TextureId ; 16 ] ,
@@ -860,9 +862,8 @@ impl Device {
860862 pub fn compile_shader ( name : & str ,
861863 source_str : & str ,
862864 shader_type : gl:: GLenum ,
863- shader_preamble : & [ String ] ,
864- panic_on_fail : bool )
865- -> Option < gl:: GLuint > {
865+ shader_preamble : & [ String ] )
866+ -> Result < gl:: GLuint , ShaderError > {
866867 debug ! ( "compile {:?}" , name) ;
867868
868869 let mut s = String :: new ( ) ;
@@ -880,16 +881,12 @@ impl Device {
880881 let log = gl:: get_shader_info_log ( id) ;
881882 if gl:: get_shader_iv ( id, gl:: COMPILE_STATUS ) == ( 0 as gl:: GLint ) {
882883 println ! ( "Failed to compile shader: {:?}\n {}" , name, log) ;
883- if panic_on_fail {
884- panic ! ( "-- Shader compile failed - exiting --" ) ;
885- }
886-
887- None
884+ Err ( ShaderError :: Compilation ( name. to_string ( ) , log) )
888885 } else {
889886 if !log. is_empty ( ) {
890887 println ! ( "Warnings detected on shader: {:?}\n {}" , name, log) ;
891888 }
892- Some ( id)
889+ Ok ( id)
893890 }
894891 }
895892
@@ -1313,14 +1310,14 @@ impl Device {
13131310
13141311 pub fn create_program ( & mut self ,
13151312 base_filename : & str ,
1316- include_filename : & str ) -> ProgramId {
1313+ include_filename : & str ) -> Result < ProgramId , ShaderError > {
13171314 self . create_program_with_prefix ( base_filename, & [ include_filename] , None )
13181315 }
13191316
13201317 pub fn create_program_with_prefix ( & mut self ,
13211318 base_filename : & str ,
13221319 include_filenames : & [ & str ] ,
1323- prefix : Option < String > ) -> ProgramId {
1320+ prefix : Option < String > ) -> Result < ProgramId , ShaderError > {
13241321 debug_assert ! ( self . inside_frame) ;
13251322
13261323 let pid = gl:: create_program ( ) ;
@@ -1357,15 +1354,14 @@ impl Device {
13571354 debug_assert ! ( self . programs. contains_key( & program_id) == false ) ;
13581355 self . programs . insert ( program_id, program) ;
13591356
1360- self . load_program ( program_id, include, true ) ;
1357+ try! { self . load_program ( program_id, include) } ;
13611358
1362- program_id
1359+ Ok ( program_id)
13631360 }
13641361
13651362 fn load_program ( & mut self ,
13661363 program_id : ProgramId ,
1367- include : String ,
1368- panic_on_fail : bool ) {
1364+ include : String ) -> Result < ( ) , ShaderError > {
13691365 debug_assert ! ( self . inside_frame) ;
13701366
13711367 let program = self . programs . get_mut ( & program_id) . unwrap ( ) ;
@@ -1391,27 +1387,28 @@ impl Device {
13911387 let vs_id = Device :: compile_shader ( & program. name ,
13921388 & program. vs_source ,
13931389 gl:: VERTEX_SHADER ,
1394- & vs_preamble,
1395- panic_on_fail) ;
1390+ & vs_preamble) ;
13961391 let fs_id = Device :: compile_shader ( & program. name ,
13971392 & program. fs_source ,
13981393 gl:: FRAGMENT_SHADER ,
1399- & fs_preamble,
1400- panic_on_fail) ;
1394+ & fs_preamble) ;
14011395
14021396 match ( vs_id, fs_id) {
1403- ( Some ( vs_id) , None ) => {
1397+ ( Ok ( vs_id) , Err ( e ) ) => {
14041398 println ! ( "FAILED to load fs - falling back to previous!" ) ;
14051399 gl:: delete_shader ( vs_id) ;
1400+ return Err ( e) ;
14061401 }
1407- ( None , Some ( fs_id) ) => {
1402+ ( Err ( e ) , Ok ( fs_id) ) => {
14081403 println ! ( "FAILED to load vs - falling back to previous!" ) ;
14091404 gl:: delete_shader ( fs_id) ;
1405+ return Err ( e) ;
14101406 }
1411- ( None , None ) => {
1407+ ( Err ( e1 ) , Err ( _ ) ) => {
14121408 println ! ( "FAILED to load vs/fs - falling back to previous!" ) ;
1409+ return Err ( e1) ;
14131410 }
1414- ( Some ( vs_id) , Some ( fs_id) ) => {
1411+ ( Ok ( vs_id) , Ok ( fs_id) ) => {
14151412 if let Some ( vs_id) = program. vs_id {
14161413 gl:: detach_shader ( program. id , vs_id) ;
14171414 }
@@ -1420,7 +1417,13 @@ impl Device {
14201417 gl:: detach_shader ( program. id , fs_id) ;
14211418 }
14221419
1423- if program. attach_and_bind_shaders ( vs_id, fs_id, panic_on_fail) {
1420+ if let Err ( bind_error) = program. attach_and_bind_shaders ( vs_id, fs_id) {
1421+ if let ( Some ( vs_id) , Some ( fs_id) ) = ( program. vs_id , program. fs_id ) {
1422+ try! { program. attach_and_bind_shaders ( vs_id, fs_id) } ;
1423+ } else {
1424+ return Err ( bind_error) ;
1425+ }
1426+ } else {
14241427 if let Some ( vs_id) = program. vs_id {
14251428 gl:: delete_shader ( vs_id) ;
14261429 }
@@ -1431,10 +1434,6 @@ impl Device {
14311434
14321435 program. vs_id = Some ( vs_id) ;
14331436 program. fs_id = Some ( fs_id) ;
1434- } else {
1435- let vs_id = program. vs_id . unwrap ( ) ;
1436- let fs_id = program. fs_id . unwrap ( ) ;
1437- program. attach_and_bind_shaders ( vs_id, fs_id, true ) ;
14381437 }
14391438
14401439 program. u_transform = gl:: get_uniform_location ( program. id , "uTransform" ) ;
@@ -1504,6 +1503,8 @@ impl Device {
15041503 }
15051504 }
15061505 }
1506+
1507+ Ok ( ( ) )
15071508 }
15081509
15091510/*
0 commit comments