Index: trunk/src/gl/gl_context.cc
===================================================================
--- trunk/src/gl/gl_context.cc	(revision 487)
+++ trunk/src/gl/gl_context.cc	(revision 491)
@@ -14,12 +14,70 @@
 using namespace nv;
 
-nv::vertex_array nv::gl_context::create_vertex_array()
+nv::vertex_array nv::gl_context::create_vertex_array( const vertex_array_desc& desc )
 {
 	vertex_array result = m_vertex_arrays.create();
-	vertex_array_info* info = m_vertex_arrays.get( result );
-	info->count       = 0;
-	info->index       = buffer();
-	info->index_owner = false;
-	info->index_type  = USHORT;
+	gl_vertex_array_info* info = m_vertex_arrays.get( result );
+
+	glGenVertexArrays( 1, &info->glid );
+	info->count       = desc.count;
+	info->index       = desc.index;
+	info->index_owner = desc.index_owner;
+	info->index_type  = desc.index_type;
+
+	for ( uint32 i = 0; i < desc.count; ++i )
+		info->attr[i] = desc.attr[i];
+
+	glBindVertexArray( info->glid );
+
+	for ( uint32 i = 0; i < info->count; ++i )
+	{
+		const vertex_buffer_attribute& vba = info->attr[i];
+		uint32 location = static_cast<uint32>( vba.location );
+		glEnableVertexAttribArray( location );
+		const gl_buffer_info* vinfo = static_cast<const gl_buffer_info*>( m_device->get_buffer_info( vba.vbuffer ) );
+		if ( vinfo && vinfo->type == VERTEX_BUFFER )
+			glBindBuffer( GL_ARRAY_BUFFER, vinfo->glid );
+		else
+		{
+			// TODO: report error
+		}
+
+		glVertexAttribPointer(
+			location,
+			static_cast<GLint>( vba.components ),
+			nv::datatype_to_gl_enum( vba.dtype ),
+			GL_FALSE,
+			static_cast<GLsizei>( vba.stride ),
+			reinterpret_cast<void*>( vba.offset )
+			);
+	}
+	glBindBuffer( GL_ARRAY_BUFFER, 0 );
+
+	if ( info->index.is_valid() )
+	{
+		const gl_buffer_info* iinfo = static_cast<const gl_buffer_info*>( m_device->get_buffer_info( info->index ) );
+		if ( iinfo && iinfo->type == INDEX_BUFFER )
+		{
+			glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, iinfo->glid );
+		}
+		else
+		{
+			// TODO: report error
+		}
+	}
+	glBindBuffer( GL_ARRAY_BUFFER, 0 );
+	glBindVertexArray( 0 );
+
+	if ( info->index.is_valid() )
+	{
+		glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
+	}
+
+	for ( uint32 i = 0; i < info->count; ++i )
+	{
+		glDisableVertexAttribArray( static_cast<uint32>( info->attr[i].location ) );
+	}
+
+
 	return result;
 }
@@ -27,21 +85,17 @@
 nv::framebuffer nv::gl_context::create_framebuffer()
 {
-	if ( is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_OBJECT ) && is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_BLIT ) )
-	{
-		unsigned glid   = 0;
-		glGenFramebuffers( 1, &glid );
-		framebuffer result = m_framebuffers.create();
-		gl_framebuffer_info* info = m_framebuffers.get( result );
-		info->glid = glid;
-		info->depth_rb_glid = 0;
-		info->color_attachment_count = 0;
-		return result;
-	}
-	else return framebuffer();
+	unsigned glid   = 0;
+	glGenFramebuffers( 1, &glid );
+	framebuffer result = m_framebuffers.create();
+	gl_framebuffer_info* info = m_framebuffers.get( result );
+	info->glid = glid;
+	info->depth_rb_glid = 0;
+	info->color_attachment_count = 0;
+	return result;
 }
 
 void nv::gl_context::release( vertex_array va )
 {
-	vertex_array_info* info = m_vertex_arrays.get( va );
+	gl_vertex_array_info* info = m_vertex_arrays.get( va );
 	if ( info )
 	{
@@ -52,4 +106,5 @@
 		}
 		if ( info->index.is_valid() && info->index_owner) m_device->release( info->index );
+		glDeleteVertexArrays( 1, &info->glid );
 		m_vertex_arrays.destroy( va );
 	}
@@ -71,17 +126,7 @@
 }
 
-const vertex_array_info* nv::gl_context::get_vertex_array_info( vertex_array va ) const 
-{
-	return m_vertex_arrays.get( va );
-}
-
 const framebuffer_info* nv::gl_context::get_framebuffer_info( framebuffer f ) const
 {
 	return m_framebuffers.get( f );
-}
-
-vertex_array_info* nv::gl_context::get_vertex_array_info_mutable( vertex_array va ) 
-{
-	return m_vertex_arrays.get( va );
 }
 
@@ -170,23 +215,17 @@
  	glDrawBuffer( 0 );
  	glReadBuffer( 0 );
-	if ( is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_OBJECT ) && is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_BLIT ) )
-	{
-		unsigned result = glCheckFramebufferStatus( framebuffer_slot_to_enum(ft) );
-		if ( result == GL_FRAMEBUFFER_COMPLETE ) return true;
-		switch ( result )
-		{
-		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;
+
+	unsigned result = glCheckFramebufferStatus( framebuffer_slot_to_enum(ft) );
+	if ( result == GL_FRAMEBUFFER_COMPLETE ) return true;
+	switch ( result )
+	{
+	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;
 //		case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS         : NV_LOG_ERROR( "gl_context::check : Framebuffer incomplete dimensions!" ); break;
 //		case GL_FRAMEBUFFER_INCOMPLETE_FORMATS            : NV_LOG_ERROR( "gl_context::check : Framebuffer incomplete formats!" ); break;
-		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        : NV_LOG_ERROR( "gl_context::check : Framebuffer incomplete draw buffer!" ); break;
-		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER        : NV_LOG_ERROR( "gl_context::check : Framebuffer incomplete read buffer!" ); break;
-		case GL_FRAMEBUFFER_UNSUPPORTED                   : NV_LOG_ERROR( "gl_context::check : Framebuffer format combination unsupported!" ); break;
-		default: NV_LOG_ERROR( "gl_context::check : Unknown Framebuffer error! (", result, ")" ); break;
-		}
-	}
-	else
-	{
-		NV_LOG_ERROR( "gl_context::check : Framebuffer extensions not loaded!" );
+	case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        : NV_LOG_ERROR( "gl_context::check : Framebuffer incomplete draw buffer!" ); break;
+	case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER        : NV_LOG_ERROR( "gl_context::check : Framebuffer incomplete read buffer!" ); break;
+	case GL_FRAMEBUFFER_UNSUPPORTED                   : NV_LOG_ERROR( "gl_context::check : Framebuffer format combination unsupported!" ); break;
+	default: NV_LOG_ERROR( "gl_context::check : Unknown Framebuffer error! (", result, ")" ); break;
 	}
 	glDrawBuffer( GL_BACK );
@@ -205,4 +244,19 @@
 	{
 		glBindFramebuffer( framebuffer_slot_to_enum(ft), 0 );
+	}
+}
+
+void nv::gl_context::bind( buffer b, texture t )
+{
+	const gl_buffer_info*  binfo = static_cast< const gl_buffer_info* >( m_device->get_buffer_info( b ) );
+	const gl_texture_info* tinfo = static_cast< const gl_texture_info* >( m_device->get_texture_info( t ) );
+	NV_ASSERT( binfo && tinfo, "Bad buffer or texture passed to create_texture" );
+	if ( binfo && tinfo )
+	{
+		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 );
+		glTexBuffer( GL_TEXTURE_BUFFER, image_format_to_internal_enum( tinfo->format.format ), binfo->glid );
+		glBindTexture( GL_TEXTURE_BUFFER, 0 );
 	}
 }
@@ -252,43 +306,8 @@
 void nv::gl_context::bind( vertex_array va )
 {
-	const vertex_array_info* info = m_vertex_arrays.get( va );
-	if ( info )
-	{
-		for ( uint32 i = 0; i < info->count; ++i ) 
-		{
-			const vertex_buffer_attribute& vba = info->attr[i];
-			uint32 location                    = static_cast<uint32>( vba.location );
-			glEnableVertexAttribArray( location );
-			const gl_buffer_info* vinfo = static_cast< const gl_buffer_info* >( m_device->get_buffer_info( vba.vbuffer ) );
-			if ( vinfo && vinfo->type == VERTEX_BUFFER )
-				glBindBuffer( GL_ARRAY_BUFFER, vinfo->glid );
-			else
-			{
-				// TODO: report error
-			}
-
-			glVertexAttribPointer(
-				location,
-				static_cast<GLint>( vba.components ),
-				nv::datatype_to_gl_enum( vba.dtype ),
-				GL_FALSE,
-				static_cast<GLsizei>( vba.stride ),
-				reinterpret_cast<void*>( vba.offset )
-				);
-		}
-		glBindBuffer( GL_ARRAY_BUFFER, 0 );
-
-		if ( info->index.is_valid() )
-		{
-			const gl_buffer_info* iinfo = static_cast< const gl_buffer_info* >( m_device->get_buffer_info( info->index ) );
-			if ( iinfo && iinfo->type == INDEX_BUFFER )
-			{
-				glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, iinfo->glid );
-			}
-			else
-			{
-				// TODO: report error
-			}
-		}
+	gl_vertex_array_info* info = m_vertex_arrays.get( va );
+	if ( info )
+	{
+		glBindVertexArray( info->glid );
 	}
 }
@@ -313,13 +332,5 @@
 	if ( info )
 	{
-		if ( info->index.is_valid() )
-		{
-			glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
-		}
-
-		for ( uint32 i = 0; i < info->count; ++i ) 
-		{
-			glDisableVertexAttribArray( static_cast<uint32>( info->attr[i].location ) );
-		}
+		glBindVertexArray( 0 );
 	}
 }
@@ -340,4 +351,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!" );
 	if ( info )
 	{
@@ -347,4 +359,5 @@
 
 		glBindTexture( gl_type, info->glid );
+		int this_should_be_subTexImage;
 		if ( info->type == TEXTURE_3D || info->type == TEXTURE_2D_ARRAY )
 			glTexImage3D( gl_type, 0, static_cast<GLint>( nv::image_format_to_internal_enum( format.format ) ), size.x, size.y, size.z, 0, nv::image_format_to_enum( format.format ), nv::datatype_to_gl_enum( format.type ), data );
@@ -722,7 +735,6 @@
 {
 	// TODO: configurable:
-	load_gl_extensions( GL_EXT_FRAMEBUFFER_BLIT | GL_EXT_FRAMEBUFFER_OBJECT | GL_EXT_TEXTURE_ARRAY );
+//	load_gl_extensions( GL_EXT_FRAMEBUFFER_BLIT | GL_EXT_FRAMEBUFFER_OBJECT | GL_EXT_TEXTURE_ARRAY );
 	force_apply_render_state( m_render_state );
-
 }
 
Index: trunk/src/gl/gl_device.cc
===================================================================
--- trunk/src/gl/gl_device.cc	(revision 487)
+++ trunk/src/gl/gl_device.cc	(revision 491)
@@ -17,5 +17,5 @@
 gl_device::gl_device()
 {
-	m_shader_header.append( "#version 330\n" );
+	m_shader_header.append( "#version 330 core\n" );
 	for ( auto& i : get_uniform_factory() ) 
 		m_shader_header.append( "uniform "+datatype_to_glsl_type( i.second->get_datatype() )+" "+ i.first +";\n" );
@@ -95,7 +95,9 @@
 nv::texture nv::gl_device::create_texture( texture_type type, ivec2 size, image_format aformat, sampler asampler, const void* data /*= nullptr */ )
 {
-	NV_ASSERT_ALWAYS( type != TEXTURE_3D && type != TEXTURE_2D_ARRAY, "2D texture type expected!" );
+	NV_ASSERT_ALWAYS( type != TEXTURE_1D_BUFFER && type != TEXTURE_3D && type != TEXTURE_2D_ARRAY, "2D texture type expected!" );
 	unsigned glid = 0;
 	unsigned gl_type = texture_type_to_enum( type );
+	GLint gl_internal = GLint( nv::image_format_to_internal_enum( aformat.format ) );
+	unsigned gl_enum = nv::image_format_to_enum( aformat.format );
 
 	bool is_depth = aformat.format == DEPTH16 || aformat.format == DEPTH24 || aformat.format == DEPTH32;
@@ -106,5 +108,5 @@
 
 	// Detect if mipmapping was requested
-	if ( gl_type == GL_TEXTURE_2D && asampler.filter_min != sampler::LINEAR && asampler.filter_min != sampler::NEAREST )
+	if ( gl_type == GL_TEXTURE_2D && gl_enum != GL_RED_INTEGER && asampler.filter_min != sampler::LINEAR && asampler.filter_min != sampler::NEAREST )
 	{
 		// TODO: This should not be done if we use framebuffers!
@@ -119,6 +121,10 @@
 	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 ) ) );
-	glTexParameteri( gl_type, GL_TEXTURE_WRAP_S, GLint( nv::sampler_wrap_to_enum( asampler.wrap_s) ) );
-	glTexParameteri( gl_type, GL_TEXTURE_WRAP_T, GLint( nv::sampler_wrap_to_enum( asampler.wrap_t) ) );
+	
+	if ( gl_enum != GL_RED_INTEGER )
+	{
+		glTexParameteri( gl_type, GL_TEXTURE_WRAP_S, GLint( nv::sampler_wrap_to_enum( asampler.wrap_s ) ) );
+		glTexParameteri( gl_type, GL_TEXTURE_WRAP_T, GLint( nv::sampler_wrap_to_enum( asampler.wrap_t ) ) );
+	}
 
 	if ( is_depth )
@@ -140,5 +146,5 @@
 // 	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso );
 
-	glTexImage2D( gl_type, 0, GLint( nv::image_format_to_internal_enum(aformat.format) ), size.x, size.y, 0, nv::image_format_to_enum(aformat.format), nv::datatype_to_gl_enum(aformat.type), data );
+	glTexImage2D( gl_type, 0, gl_internal, size.x, size.y, 0, gl_enum, nv::datatype_to_gl_enum(aformat.type), data );
 
 	glBindTexture( gl_type, 0 );
@@ -154,4 +160,24 @@
 }
 
+
+nv::texture nv::gl_device::create_texture( texture_type type, pixel_format format )
+{
+	NV_ASSERT_ALWAYS( type == TEXTURE_1D_BUFFER );
+	unsigned glid = 0;
+	unsigned gl_type = texture_type_to_enum( type );
+
+	glGenTextures( 1, &glid );
+
+	texture result = m_textures.create();
+	gl_texture_info* info = m_textures.get( result );
+	info->type = type;
+	info->format = format;
+	info->tsampler = sampler();
+	info->size = ivec3( 1, 1, 1 );
+	info->glid = glid;
+
+	return result;
+}
+
 nv::texture nv::gl_device::create_texture( texture_type type, ivec3 size, image_format aformat, sampler asampler, const void* data /*= nullptr */ )
 {
@@ -234,11 +260,14 @@
 nv::buffer nv::gl_device::create_buffer( buffer_type type, buffer_hint hint, size_t size, const void* source /*= nullptr */ )
 {
-	unsigned glid   = 0;
+	unsigned glid = 0;
 	unsigned glenum = buffer_type_to_enum( type );
 	glGenBuffers( 1, &glid );
 
-	glBindBuffer( glenum, glid );
-	glBufferData( glenum, GLsizeiptr( size ), source, buffer_hint_to_enum( hint ) );
-	glBindBuffer( glenum, 0 );
+	if ( size > 0 )
+	{
+		glBindBuffer( glenum, glid );
+		glBufferData( glenum, GLsizeiptr( size ), source, buffer_hint_to_enum( hint ) );
+		glBindBuffer( glenum, 0 );
+	}
 
 	buffer result = m_buffers.create();
@@ -249,4 +278,16 @@
 	info->glid = glid;
 	return result;
+}
+
+void nv::gl_device::create_buffer( buffer b, size_t size, const void* source )
+{
+	gl_buffer_info* info = m_buffers.get( b );
+	if ( info )
+	{
+		unsigned glenum = buffer_type_to_enum( info->type );
+		glBindBuffer( glenum, info->glid );
+		glBufferData( glenum, GLsizeiptr( size ), source, buffer_hint_to_enum( info->hint ) );
+		glBindBuffer( glenum, 0 );
+	}
 }
 
Index: trunk/src/gl/gl_enum.cc
===================================================================
--- trunk/src/gl/gl_enum.cc	(revision 487)
+++ trunk/src/gl/gl_enum.cc	(revision 491)
@@ -15,11 +15,12 @@
 	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       : 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;
 	NV_RETURN_COVERED_DEFAULT( 0 );
 	}
@@ -171,4 +172,5 @@
 	case INDEX_BUFFER   : return GL_ELEMENT_ARRAY_BUFFER;
 	case UNIFORM_BUFFER : return GL_UNIFORM_BUFFER;
+	case TEXTURE_BUFFER : return GL_TEXTURE_BUFFER;
 		NV_RETURN_COVERED_DEFAULT( 0 );
 	}
@@ -193,4 +195,10 @@
 	case DEPTH24 : return GL_DEPTH_COMPONENT;
 	case DEPTH32 : return GL_DEPTH_COMPONENT;
+	case R8I     : return GL_RED_INTEGER;
+	case R8UI    : return GL_RED_INTEGER;
+	case R16I    : return GL_RED_INTEGER;
+	case R16UI   : return GL_RED_INTEGER;
+	case R32I    : return GL_RED_INTEGER;
+	case R32UI   : return GL_RED_INTEGER;
 	NV_RETURN_COVERED_DEFAULT( 0 );
 	}
@@ -215,4 +223,10 @@
 	case DEPTH24 : return GL_DEPTH_COMPONENT24;
 	case DEPTH32:  return GL_DEPTH_COMPONENT32;
+	case R8I     : return GL_R8I;
+	case R8UI    : return GL_R8UI;
+	case R16I    : return GL_R16I;
+	case R16UI   : return GL_R16UI;
+	case R32I    : return GL_R32I;
+	case R32UI   : return GL_R32UI;
 	NV_RETURN_COVERED_DEFAULT( 0 );
 	}
@@ -358,4 +372,22 @@
 	case GL_SAMPLER_1D_ARRAY_SHADOW: return INT;
 	case GL_SAMPLER_2D_ARRAY_SHADOW: return INT;
+	case GL_SAMPLER_BUFFER         : return INT;
+
+	case GL_INT_SAMPLER_1D                : return INT;
+	case GL_INT_SAMPLER_2D                : return INT;
+	case GL_INT_SAMPLER_3D                : return INT;
+	case GL_INT_SAMPLER_2D_RECT           : return INT;
+	case GL_INT_SAMPLER_CUBE              : return INT;
+	case GL_INT_SAMPLER_1D_ARRAY          : return INT;
+	case GL_INT_SAMPLER_2D_ARRAY          : return INT;
+	case GL_INT_SAMPLER_BUFFER            : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_1D       : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_2D       : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_3D       : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_2D_RECT  : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_CUBE     : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : return INT;
+	case GL_UNSIGNED_INT_SAMPLER_BUFFER   : return INT;
 		// TODO: implement?
 //	case GL_BOOL	
