indexing description: " The main programm of a shader. Vertex and Fregment shaders are added to this program and linked here. " date: "$Date$" revision: "$Revision$" class GL_SHADER_PROGRAM inherit MEMORY export {NONE} all redefine dispose end EM_CONSTANTS export {NONE} all end GL_FUNCTIONS export {NONE} all end GLEXT_FUNCTIONS export {NONE} all end create make feature -- Access id: INTEGER vertex_shaders: HASH_TABLE[ GL_VERTEX_SHADER, INTEGER ] fragment_shaders: HASH_TABLE[ GL_FRAGMENT_SHADER, INTEGER ] feature {NONE}-- Initialization make is -- Create a new shader program require extension_is_avialbe: is_extension_supported ( "GL_ARB_shader_objects" ) do id := gl_create_program_object_arb create vertex_shaders.make (100) create fragment_shaders.make(100) end feature -- Commands add_vertex_shader( a_shader: GL_VERTEX_SHADER ) is -- Add a vertex shader to the program require shader_comiled: a_shader.is_compiled -- This is not needed for OpenGL, but it improves safty -- and does not restrict the user to much do gl_attach_object_arb( id, a_shader.id ) vertex_shaders.force( a_shader, a_shader.id ) end remove_vertex_shader( a_shader: GL_VERTEX_SHADER ) is -- Remove a vertex shader from the program do gl_detach_object_arb( id, a_shader.id ) vertex_shaders.remove ( a_shader.id ) end add_fragment_shader( a_shader: GL_FRAGMENT_SHADER ) is -- Add a fragment shader to the program require shader_comiled: a_shader.is_compiled -- This is not needed for OpenGL, but it improves safty -- and does not restrict the user to much do gl_attach_object_arb( id, a_shader.id ) fragment_shaders.force( a_shader, a_shader.id ) end remove_fragment_shader( a_shader: GL_FRAGMENT_SHADER ) is -- Remove a fragment shader from the program do gl_detach_object_arb( id, a_shader.id ) fragment_shaders.remove ( a_shader.id ) end link is -- Link the shader program local linked: INTEGER do gl_link_program_arb( id ) gl_get_object_parameteriv_arb ( id, em_gl_object_link_status_arb, $linked) is_linked := linked/=0 if not is_linked then print(log) end ensure program_linked: is_linked end use is -- Use the current shader program require program_linked: is_linked do -- The ATI Driver crashes or runns very slow with antialiasing enabled -- Disable antialiasing gl_get_booleanv_external (em_gl_line_smooth, $old_antialiasing) gl_disable_external (Em_gl_line_smooth) gl_use_program_object_arb ( id ) in_use := true ensure program_in_use: in_use end unuse is -- Use no shader program require program_linked: is_linked program_in_use: in_use do gl_use_program_object_arb ( 0 ) in_use := false if old_antialiasing then gl_enable_external ( em_gl_line_smooth ) end end feature -- Argument get_uniform_location( a_name: STRING ): INTEGER is -- Get the opengl-location of a argument do result := gl_get_uniform_location_arb ( id, a_name ) end get_attrib_location( a_name: STRING ): INTEGER is -- Get the opengl-location of a argument do result := gl_get_attrib_location_arb ( id, a_name ) end vertex_attrib1d( a_name: STRING; x: DOUBLE ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib1d_arb ( get_attrib_location(a_name), x ) end vertex_attrib1f( a_name: STRING; x: REAL ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib1f_arb ( get_attrib_location(a_name), x ) end vertex_attrib2d( a_name: STRING; x,y: DOUBLE ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib2d_arb ( get_attrib_location(a_name), x, y ) end vertex_attrib2f( a_name: STRING; x,y: REAL ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib2f_arb ( get_attrib_location(a_name), x, y ) end vertex_attrib3d( a_name: STRING; x,y,z: DOUBLE ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib3d_arb ( get_attrib_location(a_name), x, y, z ) end vertex_attrib3f( a_name: STRING; x,y,z: REAL ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib3f_arb ( get_attrib_location(a_name), x, y, z ) end vertex_attrib4d( a_name: STRING; x,y,z,w: DOUBLE ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib4d_arb ( get_attrib_location(a_name), x, y, z, w ) end vertex_attrib4f( a_name: STRING; x,y,z,w: REAL ) is -- Pass an attribute to opengl require program_in_use: in_use do gl_vertex_attrib4f_arb ( get_attrib_location(a_name), x, y, z, w ) end uniform1i( a_name: STRING; x: INTEGER ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform1i_arb ( get_uniform_location(a_name), x ) end uniform1f( a_name: STRING; x: REAL ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform1f_arb ( get_uniform_location(a_name), x ) end uniform2i( a_name: STRING; x,y: INTEGER ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform2i_arb ( get_uniform_location(a_name), x, y ) end uniform2f( a_name: STRING; x,y: REAL ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform2f_arb ( get_uniform_location(a_name), x, y ) end uniform3i( a_name: STRING; x,y,z: INTEGER ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform3i_arb ( get_uniform_location(a_name), x, y, z ) end uniform3f( a_name: STRING; x,y,z: REAL ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform3f_arb ( get_uniform_location(a_name), x, y, z ) end uniform4i( a_name: STRING; x,y,z,w: INTEGER ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform4i_arb ( get_uniform_location(a_name), x, y, z, w ) end uniform4f( a_name: STRING; x,y,z,w: REAL ) is -- Pass a uniform to opengl require program_in_use: in_use do gl_uniform4f_arb ( get_uniform_location(a_name), x, y, z, w ) end feature{NONE} -- Clean up dispose is -- clean up the opengl memory do gl_delete_object_arb (id) Precursor end feature{NONE} -- Status old_antialiasing: BOOLEAN feature -- Status in_use: BOOLEAN is_linked: BOOLEAN log:STRING is -- Return the error log local tmp_str: STRING tmp: ANY length: INTEGER do gl_get_object_parameteriv_arb ( id, em_gl_info_log_length, $length) create tmp_str.make ( length ) tmp := tmp_str.to_c gl_get_info_log_arb_external ( id, length, $length , $tmp ) create result.make_from_c ( $tmp ) end end