Index: trunk/nv/gl/gl_context.hh
===================================================================
--- trunk/nv/gl/gl_context.hh	(revision 491)
+++ trunk/nv/gl/gl_context.hh	(revision 492)
@@ -37,5 +37,5 @@
 
 		virtual vertex_array create_vertex_array( const vertex_array_desc& desc );
-		virtual framebuffer create_framebuffer();
+		virtual framebuffer create_framebuffer( uint32 temp_samples = 1 );
 		virtual void release( vertex_array va );
 		virtual void release( framebuffer f );
@@ -46,4 +46,5 @@
 		virtual void set_read_buffer( output_slot slot );
 		virtual void blit( framebuffer f, clear_state::buffers_type mask, ivec2 src1, ivec2 src2, ivec2 dst1, ivec2 dst2 );
+		virtual void blit( framebuffer from, framebuffer to, clear_state::buffers_type mask, ivec2 src1, ivec2 src2, ivec2 dst1, ivec2 dst2 );
 
 		virtual void attach( framebuffer f, output_slot slot, texture t );
@@ -88,4 +89,5 @@
 		void apply_depth_test( const depth_test& depth );
 		void apply_depth_mask( bool mask );
+		void apply_multisample( bool multisample );
 		void apply_depth_range( const depth_range& range );
 		void apply_color_mask( const color_mask& mask );
@@ -94,5 +96,8 @@
 		void apply_polygon_mode( const polygon_mode& mode );
 		void enable( unsigned int what, bool value );
+		void set_active_texture( texture_slot slot );
 	private:
+		texture_slot m_active_slot;
+		texture      m_bound_textures[ texture_slot::MAX_TEXTURES ];
 		vec4  m_clear_color;
 		float m_clear_depth;
Index: trunk/nv/gui/gui_element.hh
===================================================================
--- trunk/nv/gui/gui_element.hh	(revision 491)
+++ trunk/nv/gui/gui_element.hh	(revision 492)
@@ -18,4 +18,5 @@
 #include <nv/core/io_event.hh>
 #include <nv/stl/string.hh>
+#include <nv/stl/functional/function.hh>
 #include <nv/gui/gui_common.hh>
 
@@ -40,4 +41,5 @@
 			rectangle     m_relative;      ///< Position relative to parent.
 			rectangle     m_absolute;     ///< Position relative to window/screen.
+			function<void()> m_on_click;
 			render_data*  m_render_data; ///<   -?-
 		};
Index: trunk/nv/gui/gui_environment.hh
===================================================================
--- trunk/nv/gui/gui_environment.hh	(revision 491)
+++ trunk/nv/gui/gui_environment.hh	(revision 492)
@@ -36,4 +36,5 @@
 			void set_text( handle e, const string_twine& text );
 			void set_class( handle e, const string_view& text );
+			void set_on_click( handle e, const function< void() >& on_click );
 			void update();
 			void draw();
Index: trunk/nv/interface/context.hh
===================================================================
--- trunk/nv/interface/context.hh	(revision 491)
+++ trunk/nv/interface/context.hh	(revision 492)
@@ -61,4 +61,5 @@
 		uint32  color_attachment_count;
 		texture depth_attachment;
+		uint32  sample_count;
 	};
 
@@ -152,5 +153,5 @@
 
 		virtual vertex_array create_vertex_array( const vertex_array_desc& desc ) = 0;
-		virtual framebuffer create_framebuffer() = 0;
+		virtual framebuffer create_framebuffer( uint32 temp_samples = 1 ) = 0;
 		virtual void release( vertex_array ) = 0;
 		virtual void release( framebuffer ) = 0;
@@ -162,4 +163,5 @@
 		virtual void set_read_buffer( output_slot slot ) = 0;
 		virtual void blit( framebuffer f, clear_state::buffers_type mask, ivec2 src1, ivec2 src2, ivec2 dst1, ivec2 dst2 ) = 0;
+		virtual void blit( framebuffer from, framebuffer to, clear_state::buffers_type mask, ivec2 src1, ivec2 src2, ivec2 dst1, ivec2 dst2 ) = 0;
 
 		virtual void attach( framebuffer f, output_slot slot, texture t ) = 0;
Index: trunk/nv/interface/device.hh
===================================================================
--- trunk/nv/interface/device.hh	(revision 491)
+++ trunk/nv/interface/device.hh	(revision 492)
@@ -52,4 +52,5 @@
 		TEXTURE_2D_ARRAY,
 		TEXTURE_1D_BUFFER,
+		TEXTURE_2D_MULTISAMPLE,
 	};
 
@@ -79,4 +80,5 @@
 		TEXTURE_14    = 14,
 		TEXTURE_15    = 15,
+		MAX_TEXTURES  = 16,
 	};
 
@@ -233,5 +235,5 @@
 
 		template < typename T >
-		void set_uniform_array( program p, const string_view& name, const T* value, uint32 count, bool fatal = true )
+		bool set_uniform_array( program p, const string_view& name, const T* value, uint32 count, bool fatal = true )
 		{
 			uniform_base* base = get_uniform( p, name, fatal );
@@ -243,23 +245,25 @@
 					NV_ASSERT( static_cast<int>( count ) <= base->get_length(), "LENGTH CHECK FAIL" );
 					static_cast< uniform<T>* >( base )->set_value( value, count );
+					return true;
 				}
 			}
-		}
-
-		template < typename T >
-		void set_opt_uniform_array( program p, const string_view& name, const T* value, uint32 count )
-		{
-			set_uniform_array( p, name, value, count, false );
-		}
-
-		template < typename T >
-		void set_opt_uniform_array( program p, const string_view& name, const array_view<T>& value )
-		{
-			set_uniform_array( p, name, value.data(), value.size(), false );
-		}
-
-
-		template < typename T >
-		void set_uniform( program p, const string_view& name, const T& value, bool fatal = true )
+			return false;
+		}
+
+		template < typename T >
+		bool set_opt_uniform_array( program p, const string_view& name, const T* value, uint32 count )
+		{
+			return set_uniform_array( p, name, value, count, false );
+		}
+
+		template < typename T >
+		bool set_opt_uniform_array( program p, const string_view& name, const array_view<T>& value )
+		{
+			return set_uniform_array( p, name, value.data(), value.size(), false );
+		}
+
+
+		template < typename T >
+		bool set_uniform( program p, const string_view& name, const T& value, bool fatal = true )
 		{
 			uniform_base* base = get_uniform( p, name, fatal );
@@ -269,12 +273,14 @@
 				{
 					static_cast< uniform<T>* >( base )->set_value( value );
+					return true;
 				}
 			}
-		}
-
-		template < typename T >
-		void set_opt_uniform( program p, const string_view& name, const T& value )
-		{
-			set_uniform( p, name, value, false );
+			return false;
+		}
+
+		template < typename T >
+		bool set_opt_uniform( program p, const string_view& name, const T& value )
+		{
+			return set_uniform( p, name, value, false );
 		}
 
Index: trunk/nv/interface/render_state.hh
===================================================================
--- trunk/nv/interface/render_state.hh	(revision 491)
+++ trunk/nv/interface/render_state.hh	(revision 492)
@@ -199,6 +199,7 @@
 		nv::color_mask   color_mask;
 		nv::polygon_mode polygon_mode;
+		bool multisample;
 		bool depth_mask;
-		render_state() : depth_mask( true ) {}
+		render_state() : depth_mask( true ), multisample( false ) {}
 	};
 
Index: trunk/nv/lib/gl.hh
===================================================================
--- trunk/nv/lib/gl.hh	(revision 491)
+++ trunk/nv/lib/gl.hh	(revision 492)
@@ -53,5 +53,5 @@
 #define GL_GENERATE_MIPMAP                0x8191
 
-#include <nv/lib/detail/gl_core/gl_types_3_1.inc>
+#include <nv/lib/detail/gl_core/gl_types_3_2.inc>
 #if NV_PLATFORM == NV_WINDOWS
 #include <nv/lib/detail/wgl_types.inc>
@@ -67,5 +67,5 @@
 #define NV_GL_FUN_EXT NV_GL_FUN
 
-#include <nv/lib/detail/gl_core/gl_functions_3_1.inc>
+#include <nv/lib/detail/gl_core/gl_functions_3_2.inc>
 #if NV_PLATFORM == NV_WINDOWS
 #include <nv/lib/detail/wgl_functions.inc>
Index: trunk/src/gl/gl_context.cc
===================================================================
--- trunk/src/gl/gl_context.cc	(revision 491)
+++ trunk/src/gl/gl_context.cc	(revision 492)
@@ -74,8 +74,8 @@
 	}
 
-	for ( uint32 i = 0; i < info->count; ++i )
-	{
-		glDisableVertexAttribArray( static_cast<uint32>( info->attr[i].location ) );
-	}
+// 	for ( uint32 i = 0; i < info->count; ++i )
+// 	{
+// 		glDisableVertexAttribArray( static_cast<uint32>( info->attr[i].location ) );
+// 	}
 
 
@@ -83,5 +83,5 @@
 }
 
-nv::framebuffer nv::gl_context::create_framebuffer()
+nv::framebuffer nv::gl_context::create_framebuffer( uint32 temp_samples )
 {
 	unsigned glid   = 0;
@@ -92,4 +92,5 @@
 	info->depth_rb_glid = 0;
 	info->color_attachment_count = 0;
+	info->sample_count = temp_samples;
 	return result;
 }
@@ -192,5 +193,8 @@
 		glGenRenderbuffers( 1, &(info->depth_rb_glid) );
 		glBindRenderbuffer( GL_RENDERBUFFER, info->depth_rb_glid );
-		glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.x, size.y );
+		if ( info->sample_count > 1 )
+			glRenderbufferStorageMultisample( GL_RENDERBUFFER, info->sample_count, GL_DEPTH_COMPONENT16, size.x, size.y );
+		else
+			glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.x, size.y );
 		glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, info->depth_rb_glid );
 		glBindRenderbuffer( GL_RENDERBUFFER, 0 );
@@ -211,4 +215,21 @@
 
 
+void nv::gl_context::blit( framebuffer from, framebuffer to, clear_state::buffers_type mask, ivec2 src1, ivec2 src2, ivec2 dst1, ivec2 dst2 )
+{
+	gl_framebuffer_info* finfo = m_framebuffers.get( from );
+	gl_framebuffer_info* tinfo = m_framebuffers.get( to );
+	if ( finfo )
+	{
+		glBindFramebuffer( GL_READ_FRAMEBUFFER, finfo->glid );
+		glBindFramebuffer( GL_DRAW_FRAMEBUFFER, tinfo ? tinfo->glid : 0 );
+		unsigned filter = mask == clear_state::COLOR_BUFFER ? GL_LINEAR : GL_NEAREST;
+		int remove_below;
+		filter = GL_NEAREST;
+		glBlitFramebuffer( src1.x, src1.y, src2.x, src2.y, dst1.x, dst1.y, dst2.x, dst2.y, clear_state_buffers_to_mask( mask ), filter );
+		glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
+		if ( tinfo ) glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
+	}
+}
+
 bool nv::gl_context::check( framebuffer_slot ft )
 {
@@ -220,4 +241,7 @@
 	switch ( result )
 	{
+	case GL_FRAMEBUFFER_UNDEFINED                     : NV_LOG_ERROR( "gl_context::check : Framebuffer undefined!" ); break;
+	case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE        : NV_LOG_ERROR( "gl_context::check : Incomplete multisample!" ); break;
+	case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS      : NV_LOG_ERROR( "gl_context::check : Incomplete layer targets!" ); break;
 	case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT         : NV_LOG_ERROR( "gl_context::check : Framebuffer incomplete attachment!" ); break;
 	case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : NV_LOG_ERROR( "gl_context::check : Framebuffer missing attachment!" ); break;
@@ -255,8 +279,6 @@
 	{
 		NV_ASSERT_ALWAYS( binfo->type == TEXTURE_BUFFER && tinfo->type == TEXTURE_1D_BUFFER, "bad texture or buffer type!" );
-		glActiveTexture( GL_TEXTURE0 );
-		glBindTexture( GL_TEXTURE_BUFFER, tinfo->glid );
+		bind( t, TEXTURE_0 );
 		glTexBuffer( GL_TEXTURE_BUFFER, image_format_to_internal_enum( tinfo->format.format ), binfo->glid );
-		glBindTexture( GL_TEXTURE_BUFFER, 0 );
 	}
 }
@@ -276,9 +298,12 @@
 void gl_context::bind( texture t, texture_slot slot )
 {
-	const gl_texture_info* info = static_cast< const gl_texture_info* >( m_device->get_texture_info( t ) );
-	if ( info )
-	{
-		glActiveTexture( GL_TEXTURE0 + static_cast< GLenum >( slot ) );
-		glBindTexture( texture_type_to_enum( info->type ), info->glid );
+	if ( m_bound_textures[ slot ] != t )
+	{
+		const gl_texture_info* info = static_cast< const gl_texture_info* >( m_device->get_texture_info( t ) );
+		if ( info )
+		{
+			set_active_texture( slot );
+			glBindTexture( texture_type_to_enum( info->type ), info->glid );
+		}
 	}
 }
@@ -318,4 +343,10 @@
 }
 
+void nv::gl_context::set_active_texture( texture_slot slot )
+{
+	if ( slot != m_active_slot )
+		glActiveTexture( GL_TEXTURE0 + static_cast<GLenum>( slot ) );
+}
+
 // void nv::gl_context::unbind( buffer b )
 // {
@@ -352,4 +383,5 @@
 	const gl_texture_info* info = static_cast< const gl_texture_info* >( m_device->get_texture_info( t ) );
 	NV_ASSERT_ALWAYS( info->type != TEXTURE_1D_BUFFER, "Buffer texture passed to update!" );
+	NV_ASSERT_ALWAYS( info->type != TEXTURE_2D_MULTISAMPLE, "Multisample texture passed to update!" );
 	if ( info )
 	{
@@ -358,5 +390,6 @@
 		unsigned     gl_type = texture_type_to_enum( info->type );
 
-		glBindTexture( gl_type, info->glid );
+		if ( m_bound_textures[ m_active_slot ] != t )
+			glBindTexture( gl_type, info->glid );
 		int this_should_be_subTexImage;
 		if ( info->type == TEXTURE_3D || info->type == TEXTURE_2D_ARRAY )
@@ -543,4 +576,13 @@
 		glDepthMask( mask );
 		m_render_state.depth_mask = mask;
+	}
+}
+
+void gl_context::apply_multisample( bool multisample )
+{
+	if ( m_render_state.multisample != multisample )
+	{
+		glDepthMask( multisample );
+		m_render_state.multisample = multisample;
 	}
 }
@@ -727,4 +769,5 @@
 	apply_color_mask( state.color_mask );
 	apply_depth_mask( state.depth_mask );
+	apply_multisample( state.multisample );
 	apply_polygon_mode( state.polygon_mode );
 }
@@ -736,4 +779,5 @@
 	// TODO: configurable:
 //	load_gl_extensions( GL_EXT_FRAMEBUFFER_BLIT | GL_EXT_FRAMEBUFFER_OBJECT | GL_EXT_TEXTURE_ARRAY );
+	m_active_slot = texture_slot( -1 );
 	force_apply_render_state( m_render_state );
 }
Index: trunk/src/gl/gl_device.cc
===================================================================
--- trunk/src/gl/gl_device.cc	(revision 491)
+++ trunk/src/gl/gl_device.cc	(revision 492)
@@ -98,5 +98,5 @@
 	unsigned glid = 0;
 	unsigned gl_type = texture_type_to_enum( type );
-	GLint gl_internal = GLint( nv::image_format_to_internal_enum( aformat.format ) );
+	GLenum gl_internal = GLenum( nv::image_format_to_internal_enum( aformat.format ) );
 	unsigned gl_enum = nv::image_format_to_enum( aformat.format );
 
@@ -119,8 +119,11 @@
 	}
 
-	glTexParameteri( gl_type, GL_TEXTURE_MIN_FILTER, GLint( nv::sampler_filter_to_enum( asampler.filter_min ) ) );
-	glTexParameteri( gl_type, GL_TEXTURE_MAG_FILTER, GLint( nv::sampler_filter_to_enum( asampler.filter_max ) ) );
+	if ( gl_type != GL_TEXTURE_2D_MULTISAMPLE )
+	{
+		glTexParameteri( gl_type, GL_TEXTURE_MIN_FILTER, GLint( nv::sampler_filter_to_enum( asampler.filter_min ) ) );
+		glTexParameteri( gl_type, GL_TEXTURE_MAG_FILTER, GLint( nv::sampler_filter_to_enum( asampler.filter_max ) ) );
+	}
 	
-	if ( gl_enum != GL_RED_INTEGER )
+	if ( gl_type != GL_TEXTURE_2D_MULTISAMPLE && gl_enum != GL_RED_INTEGER )
 	{
 		glTexParameteri( gl_type, GL_TEXTURE_WRAP_S, GLint( nv::sampler_wrap_to_enum( asampler.wrap_s ) ) );
@@ -130,6 +133,6 @@
 	if ( is_depth )
 	{
-		glTexParameteri( gl_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
-		glTexParameteri( gl_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+//		glTexParameteri( gl_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+//		glTexParameteri( gl_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
 
 		// This is to allow usage of shadow2DProj function in the shader
@@ -146,5 +149,8 @@
 // 	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso );
 
-	glTexImage2D( gl_type, 0, gl_internal, size.x, size.y, 0, gl_enum, nv::datatype_to_gl_enum(aformat.type), data );
+	if ( gl_type != GL_TEXTURE_2D_MULTISAMPLE )
+		glTexImage2D( gl_type, 0, gl_internal, size.x, size.y, 0, gl_enum, nv::datatype_to_gl_enum(aformat.type), data );
+	else
+		glTexImage2DMultisample( gl_type, 4, gl_internal, size.x, size.y, 1 );
 
 	glBindTexture( gl_type, 0 );
@@ -163,7 +169,6 @@
 nv::texture nv::gl_device::create_texture( texture_type type, pixel_format format )
 {
-	NV_ASSERT_ALWAYS( type == TEXTURE_1D_BUFFER );
+	NV_ASSERT_ALWAYS( type == TEXTURE_1D_BUFFER, "create_texture not texture buffer!" );
 	unsigned glid = 0;
-	unsigned gl_type = texture_type_to_enum( type );
 
 	glGenTextures( 1, &glid );
@@ -552,4 +557,6 @@
 		NV_ASSERT( u, "Unknown uniform type!" );
 		(*p->m_uniform_map)[ name ] = u;
+		//NV_LOG_DEBUG( "Uniform : ", name, " - ", utype, "/", uni_len );
+
 	}
 
Index: trunk/src/gl/gl_enum.cc
===================================================================
--- trunk/src/gl/gl_enum.cc	(revision 491)
+++ trunk/src/gl/gl_enum.cc	(revision 492)
@@ -15,12 +15,13 @@
 	switch( type )
 	{
-	case TEXTURE_1D       : return GL_TEXTURE_1D;
-	case TEXTURE_2D       : return GL_TEXTURE_2D;
-	case TEXTURE_RECT     : return GL_TEXTURE_RECTANGLE;
-	case TEXTURE_3D       : return GL_TEXTURE_3D;
-	case TEXTURE_CUBE     : return GL_TEXTURE_CUBE_MAP;
- 	case TEXTURE_1D_ARRAY : return GL_TEXTURE_1D_ARRAY;
- 	case TEXTURE_2D_ARRAY : return GL_TEXTURE_2D_ARRAY;
-	case TEXTURE_1D_BUFFER: return GL_TEXTURE_BUFFER;
+	case TEXTURE_1D             : return GL_TEXTURE_1D;
+	case TEXTURE_2D             : return GL_TEXTURE_2D;
+	case TEXTURE_RECT           : return GL_TEXTURE_RECTANGLE;
+	case TEXTURE_3D             : return GL_TEXTURE_3D;
+	case TEXTURE_CUBE           : return GL_TEXTURE_CUBE_MAP;
+ 	case TEXTURE_1D_ARRAY       : return GL_TEXTURE_1D_ARRAY;
+ 	case TEXTURE_2D_ARRAY       : return GL_TEXTURE_2D_ARRAY;
+	case TEXTURE_1D_BUFFER      : return GL_TEXTURE_BUFFER;
+	case TEXTURE_2D_MULTISAMPLE : return GL_TEXTURE_2D_MULTISAMPLE;
 	NV_RETURN_COVERED_DEFAULT( 0 );
 	}
Index: trunk/src/gui/gui_environment.cc
===================================================================
--- trunk/src/gui/gui_environment.cc	(revision 491)
+++ trunk/src/gui/gui_environment.cc	(revision 492)
@@ -182,4 +182,7 @@
 		{ 
 			handle h = get_element( position( ev.mbutton.x, ev.mbutton.y ) );
+			element* e = m_elements.get( h );
+			if ( e->m_on_click ) e->m_on_click();
+
 			set_selected( h );
 			return true;
@@ -312,4 +315,13 @@
 }
 
+void nv::gui::environment::set_on_click( handle e, const function< void() >& on_click )
+{
+	element* ep = m_elements.get( e );
+	if ( ep != nullptr )
+	{
+		ep->m_on_click = on_click;
+	}
+}
+
 void nv::gui::environment::set_text( handle e, const string_twine& text )
 {
Index: trunk/src/gui/gui_gfx_renderer.cc
===================================================================
--- trunk/src/gui/gui_gfx_renderer.cc	(revision 491)
+++ trunk/src/gui/gui_gfx_renderer.cc	(revision 492)
@@ -249,6 +249,6 @@
 		const char* stext[] = { "", "selected", "hover" };
 		const char* selector = stext[border];
-		if ( e->m_flags[HOVER] )    selector = stext[2];
-		if ( e->m_flags[SELECTED] ) selector = stext[1];
+		if ( e->m_flags[HOVER] && e->m_flags[DIRTY_HOVER] )    selector = stext[2];
+		if ( e->m_flags[SELECTED] && e->m_flags[DIRTY_SELECT] ) selector = stext[1];
 
 		if ( m_style.get( e, "skin", selector, path ) )
Index: trunk/src/lib/gl.cc
===================================================================
--- trunk/src/lib/gl.cc	(revision 491)
+++ trunk/src/lib/gl.cc	(revision 492)
@@ -26,5 +26,5 @@
 #define NV_GL_FUN_REN( rtype, fname, rname, fparams ) rtype (NV_GL_APIENTRY *rname) fparams = nullptr;
 #define NV_GL_FUN_EXT NV_GL_FUN
-#include <nv/lib/detail/gl_core/gl_functions_3_1.inc>
+#include <nv/lib/detail/gl_core/gl_functions_3_2.inc>
 #if NV_PLATFORM == NV_WINDOWS
 #include <nv/lib/detail/wgl_functions.inc>
@@ -106,5 +106,5 @@
 #	define NV_GL_FUN( rtype, fname, fparams ) NV_GL_LOAD( fname )
 #	define NV_GL_FUN_EXT( rtype, fname, fparams ) NV_GL_LOAD_EXT( fname )
-#	include <nv/lib/detail/gl_core/gl_functions_3_1.inc>
+#	include <nv/lib/detail/gl_core/gl_functions_3_2.inc>
 #	undef NV_GL_FUN_EXT
 #	undef NV_GL_FUN
Index: trunk/src/sdl/sdl_window.cc
===================================================================
--- trunk/src/sdl/sdl_window.cc	(revision 491)
+++ trunk/src/sdl/sdl_window.cc	(revision 492)
@@ -30,6 +30,6 @@
 	//	SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 4 );
 
- 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
- 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+ 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
+ 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
 
 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
