Index: trunk/src/gl/gl_context.cc
===================================================================
--- trunk/src/gl/gl_context.cc	(revision 462)
+++ trunk/src/gl/gl_context.cc	(revision 463)
@@ -111,5 +111,5 @@
 }
 
-void nv::gl_context::attach( framebuffer f, texture depth )
+void nv::gl_context::attach( framebuffer f, texture depth, int layer /*= -1*/ )
 {
 	// TODO: framebuffer variable, so no re-binding?
@@ -121,13 +121,15 @@
 		glBindFramebuffer( GL_FRAMEBUFFER, info->glid );
 		unsigned gl_type = texture_type_to_enum( tinfo->type );
-		if ( tinfo )
-		{
-			glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, gl_type, tinfo->glid, 0 );
+		unsigned glid = ( tinfo ? tinfo->glid : 0 );
+		if ( layer >= 0 )
+		{
+			glFramebufferTextureLayer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tinfo->glid, 0, layer );
 		}
 		else
 		{
-			glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, gl_type, 0, 0 );
-		}
-	}
+			glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, gl_type, glid, 0 );
+		}
+	}
+
 }
 
@@ -328,9 +330,12 @@
 	{
 		image_format format  = info->format;
-		ivec2        size    = info->size;
+		ivec3        size    = info->size;
 		unsigned     gl_type = texture_type_to_enum( info->type );
 
 		glBindTexture( gl_type, info->glid );
-		glTexImage2D( gl_type, 0, static_cast<GLint>( nv::image_format_to_internal_enum(format.format) ), size.x, size.y, 0, nv::image_format_to_enum(format.format), nv::datatype_to_gl_enum(format.type), data );
+		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 );
+		else
+			glTexImage2D( gl_type, 0, static_cast<GLint>( nv::image_format_to_internal_enum(format.format) ), size.x, size.y, 0, nv::image_format_to_enum(format.format), nv::datatype_to_gl_enum(format.type), data );
 	}
 }
@@ -690,5 +695,5 @@
 {
 	// TODO: configurable:
-	load_gl_extensions( GL_EXT_FRAMEBUFFER_BLIT | GL_EXT_FRAMEBUFFER_OBJECT );
+	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 462)
+++ trunk/src/gl/gl_device.cc	(revision 463)
@@ -17,5 +17,5 @@
 gl_device::gl_device()
 {
-	m_shader_header.append( "#version 120\n" );
+	m_shader_header.append( "#version 120\n#extension GL_EXT_texture_array : require\n" );
 	for ( auto& i : get_uniform_factory() ) 
 		m_shader_header.append( "uniform "+datatype_to_glsl_type( i.second->get_datatype() )+" "+ i.first +";\n" );
@@ -95,6 +95,10 @@
 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!" );
 	unsigned glid = 0;
 	unsigned gl_type = texture_type_to_enum( type );
+
+	bool is_depth = aformat.format == DEPTH16 || aformat.format == DEPTH24 || aformat.format == DEPTH32;
+
 	glGenTextures( 1, &glid );
 
@@ -117,4 +121,29 @@
 	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 )
+	{
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+
+#define GL_INTENSITY 0x8049
+#define GL_LUMINANCE 0x1909
+// 		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
+// 		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
+// 		glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
+//    		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, 0 );
+//    		glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY );
+	}
+
+// #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+// #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+// 
+// 	float aniso = 0.0f;
+// 	glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso );
+// 	NV_LOG_INFO( "Anisotropy at ", aniso, " (", int( aniso ), " ) " );
+// 	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 );
@@ -127,8 +156,45 @@
 	info->format   = aformat;
 	info->tsampler = asampler;
-	info->size     = size;
+	info->size     = ivec3( size.x, size.y, 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 */ )
+{
+	NV_ASSERT_ALWAYS( type == TEXTURE_3D || type == TEXTURE_2D_ARRAY, "3D texture type expected!" );
+	unsigned glid = 0;
+	unsigned gl_type = texture_type_to_enum( type );
+
+	bool is_depth = aformat.format == DEPTH16 || aformat.format == DEPTH24 || aformat.format == DEPTH32;
+
+	glGenTextures( 1, &glid );
+	glBindTexture( gl_type, glid );
+
+	if ( asampler.filter_max != sampler::NEAREST )
+	{
+		asampler.filter_max = sampler::LINEAR;
+	}
+
+	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 ) ) );
+
+	//glTexStorage3D( GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA8, width, height, layerCount );
+	glTexImage3D( gl_type, 0, GLint( nv::image_format_to_internal_enum( aformat.format ) ), size.x, size.y, size.z, 0, nv::image_format_to_enum( aformat.format ), nv::datatype_to_gl_enum( aformat.type ), data );
+	glBindTexture( gl_type, 0 );
+
+	texture result = m_textures.create();
+	gl_texture_info* info = m_textures.get( result );
+	info->type = type;
+	info->format = aformat;
+	info->tsampler = asampler;
+	info->size = size;
+	info->glid = glid;
+	return result;
+}
+
+
 
 void nv::gl_device::release( texture t )
Index: trunk/src/gl/gl_enum.cc
===================================================================
--- trunk/src/gl/gl_enum.cc	(revision 462)
+++ trunk/src/gl/gl_enum.cc	(revision 463)
@@ -15,9 +15,11 @@
 	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      : 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;
 	NV_RETURN_COVERED_DEFAULT( 0 );
 	}
@@ -347,5 +349,9 @@
 	case GL_SAMPLER_1D_SHADOW      : return INT;	
 	case GL_SAMPLER_2D_SHADOW      : return INT;
-// TODO: implement?
+	case GL_SAMPLER_1D_ARRAY       : return INT;
+	case GL_SAMPLER_2D_ARRAY       : return INT;
+	case GL_SAMPLER_1D_ARRAY_SHADOW: return INT;
+	case GL_SAMPLER_2D_ARRAY_SHADOW: return INT;
+		// TODO: implement?
 //	case GL_BOOL	
 //	case GL_BOOL_VEC2
Index: trunk/src/lib/gl.cc
===================================================================
--- trunk/src/lib/gl.cc	(revision 462)
+++ trunk/src/lib/gl.cc	(revision 463)
@@ -269,4 +269,7 @@
 #include <nv/lib/detail/gl_ext/gl_ext_framebuffer_object_functions.inc>
 	} break;
+	case GL_EXT_TEXTURE_ARRAY: {
+#include <nv/lib/detail/gl_ext/gl_ext_texture_array_functions.inc>
+	} break;
 	default : {
 		NV_LOG_ERROR( "load_gl_extension - unknown extension \"", name, "\"!" );
