Exemplo n.º 1
0
TextureHandle LoadTexture(const char *filename, const char *textureResourceName) // if not provided, the default resource name used is the filename
{
	TextureHandle hnd = textureResourceName ? ResourceManager::get().CreateAndGetResource<Texture>(textureResourceName) : ResourceManager::get().CreateAndGetResource<Texture>(filename);
	if(hnd->GetGLTextureID()) { return hnd; }; // return resource if already loaded
	if(!hnd->Load(filename)) { ResourceManager::get().RemoveResource(hnd->GetResourceID()); }
	return hnd;
};
Exemplo n.º 2
0
bool CButtonManager::Init(CGraphicsSystem &g) {
	char fileName[256];
	sprintf_s(fileName,256,"%s/buttons/button.png",g.texturePath.c_str());
	TextureHandle buttonTexture = g.getTexture(fileName);
	if (buttonTexture.isNull()) {
		return false;
	} else {
		g.cacheTexture(buttonTexture);
		buttonTextures.push_back(buttonTexture);
	}

	sprintf_s(fileName,256,"%s/buttons/buttonDownArrow.png",g.texturePath.c_str());
	buttonTexture = g.getTexture(fileName);
	if (buttonTexture.isNull()) {
		return false;
	} else {
		g.cacheTexture(buttonTexture);
		buttonTextures.push_back(buttonTexture);
	}

	sprintf_s(fileName,256,"%s/buttons/buttonUpArrow.png",g.texturePath.c_str());
	buttonTexture = g.getTexture(fileName);
	if (buttonTexture.isNull()) {
		return false;
	} else {
		g.cacheTexture(buttonTexture);
		buttonTextures.push_back(buttonTexture);
	}

	return true;
}
Exemplo n.º 3
0
inline TextureHandle CreateSingleColorTexture( const SFloatRGBAColor& color = SFloatRGBAColor::White(), uint width = 1, uint height = 1 )
{
	TextureResourceDesc desc;
	desc.Width     = width;
	desc.Height    = height;
	desc.MipLevels = 0;
	desc.Format    = TextureFormat::A8R8G8B8;
	desc.pLoader.reset( new SingleColorTextureGenerator( color ) );

	TextureHandle tex;
	bool loaded = tex.Load( desc );

	if( !loaded )
		LOG_PRINTF_ERROR(( " Failed to create the specified texture (size: %dx%d).", width, height ));

	return tex;
}
static TextureHandle GetSingleColorWhiteTexture()
{
	if( !sg_SingleColorWhiteTexture.IsLoaded() )
	{
		sg_SingleColorWhiteTexture = CreateSingleColorTexture( SFloatRGBAColor::White(), 1, 1 );
	}

	return sg_SingleColorWhiteTexture;
}
Exemplo n.º 5
0
void ShadowMapDemo::HandleInput( const InputData& input )
{
	switch( input.iGICode )
	{
	case 'T':
		if( input.iType == ITYPE_KEY_PRESSED )
		{
			m_RenderSceneWithShadow = !m_RenderSceneWithShadow;
		}
		break;

	case 'L':
		if( input.iType == ITYPE_KEY_PRESSED )
		{
			m_Lighting = !m_Lighting;
		}
		break;

	case GIC_F11:
		if( input.iType == ITYPE_KEY_PRESSED )
		{
			if( m_pShadowMapManager )
			{
				TextureHandle tex = m_pShadowMapManager->GetSceneShadowTexture();
				tex.SaveTextureToImageFile( ".debug/shadow_maps/scene_shadow_texture.png" );

				m_pShadowMapManager->SaveShadowMapTexturesToImageFiles( ".debug/shadow_maps" );

//				shared_ptr<TextureRenderTarget> pTexRenderTarget
//					= m_pShadowMapManager->GetSceneShadowTexture();
//
//				if( pTexRenderTarget )
//					pTexRenderTarget->GetRenderTargetTexture().SaveTextureToImageFile( "scene_shadow_texture.png" );
			}
		}
		break;

	default:
		CGraphicsTestBase::HandleInput( input );
		break;
	}
}
Exemplo n.º 6
0
 void Gfx_Texture_Destroy(RenderDevice* dev, TextureHandle& h)
 {
     if( h.valid() )
     {
         SafeRelease(dev->resources->textures[h].surface);
         SafeRelease(dev->resources->textures[h].native2D);
         SafeRelease(dev->resources->textures[h].native3D);
         SafeRelease(dev->resources->textures[h].nativeCUBE);
         dev->resources->textures.remove(h);
     }
 };
Exemplo n.º 7
0
void TextureManager::set(const TextureHandle &handle) {
	if (handle.empty()) {
		set();
		return;
	}

	TextureID id = handle._it->second->texture->getID();
	if (id == 0)
		warning("Empty texture ID for texture \"%s\"", handle._it->first.c_str());

	glBindTexture(GL_TEXTURE_2D, id);
}
Exemplo n.º 8
0
 void Gfx_Texture_Destroy(RenderDevice* dev, TextureHandle& h)
 {
     if( h.valid() )
     {
         TextureDX11& t = dev->resources.textures[h];
         SafeRelease(t.rtv);
         SafeRelease(t.srv);
         SafeRelease(t.native2D);
         SafeRelease(t.native3D);
         SafeRelease(t.nativeCUBE);
         dev->resources.textures.remove(h);
     }
 }
Exemplo n.º 9
0
void TextureManager::set(const TextureHandle &handle, TextureMode mode) {
	if (handle.empty()) {
		set();
		return;
	}

	TextureID id = handle._it->second->texture->getID();
	if (id == 0)
		warning("Empty texture ID for texture \"%s\"", handle._it->first.c_str());

	if (handle._it->second->texture->getImage().isCubeMap()) {
		glBindTexture(GL_TEXTURE_CUBE_MAP, id);

		glDisable(GL_TEXTURE_2D);
		glEnable(GL_TEXTURE_CUBE_MAP);
	} else {
		glBindTexture(GL_TEXTURE_2D, id);

		glDisable(GL_TEXTURE_CUBE_MAP);
		glEnable(GL_TEXTURE_2D);
	}

	switch (mode) {
		case kModeEnvironmentMapReflective:
			if (handle._it->second->texture->getImage().isCubeMap()) {
				glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
				glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
				glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);

				glEnable(GL_TEXTURE_GEN_S);
				glEnable(GL_TEXTURE_GEN_T);
				glEnable(GL_TEXTURE_GEN_R);
			} else {
				glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
				glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);

				glEnable(GL_TEXTURE_GEN_S);
				glEnable(GL_TEXTURE_GEN_T);
			}

			break;

		case kModeDiffuse:
		default:
			glDisable(GL_TEXTURE_GEN_S);
			glDisable(GL_TEXTURE_GEN_T);
			glDisable(GL_TEXTURE_GEN_R);
			break;
	}
}
Exemplo n.º 10
0
namespace amorphous
{

using namespace std;


static ShaderHandle sg_NoLightingShader;
static TextureHandle sg_SingleColorWhiteTexture;


static TextureHandle GetSingleColorWhiteTexture()
{
	if( !sg_SingleColorWhiteTexture.IsLoaded() )
	{
		sg_SingleColorWhiteTexture = CreateSingleColorTexture( SFloatRGBAColor::White(), 1, 1 );
	}

	return sg_SingleColorWhiteTexture;
}


/// Used when a rectangle in 3D space is rendered via custom mesh
/// This function do not set vertex positions of the rect mesh,
/// since they are calculated when Draw3DRect() is called.
static void InitRectMesh( CustomMesh& mesh, const SFloatRGBAColor& vertex_diffuse_color )
{
	U32 vertex_format_flags
		= VFF::POSITION
		| VFF::NORMAL
		| VFF::DIFFUSE_COLOR
		| VFF::TEXCOORD2_0;

	mesh.InitVertexBuffer( 4, vertex_format_flags );

	mesh.SetNormals( Vector3(0,0,1) );

	mesh.SetDiffuseColors( vertex_diffuse_color );

	vector<unsigned int> indices;
	indices.resize( 6 );
	indices[0] = 0;
	indices[1] = 2;
	indices[2] = 1;
	indices[3] = 0;
	indices[4] = 3;
	indices[5] = 2;

	mesh.SetIndices( indices );

	vector<CMMA_TriangleSet> triangle_sets;
	triangle_sets.resize( 1 );
	triangle_sets[0].m_iStartIndex             = 0;
	triangle_sets[0].m_iMinIndex               = 0;
	triangle_sets[0].m_iNumVertexBlocksToCover = 4;
	triangle_sets[0].m_iNumTriangles           = 2;
	triangle_sets[0].m_AABB                    = AABB3( Vector3(0,0,0), Vector3(0,0,0) );

	mesh.SetTriangleSets( triangle_sets );
}



CustomMesh PrimitiveShapeRenderer::ms_BoxMesh;

CustomMesh PrimitiveShapeRenderer::ms_RectMesh;


PrimitiveShapeRenderer::PrimitiveShapeRenderer()
{
//	ShaderResourceDesc desc;
//	desc = non_programmable;

//	m_Shader.Load( desc );
}

void PrimitiveShapeRenderer::RenderSphere( const Sphere& sphere, const SFloatRGBAColor& color )
{
}


void PrimitiveShapeRenderer::RenderBox( const Vector3& vEdgeLengths, const Matrix34& world_pose, const SFloatRGBAColor& color )
{
	ShaderManager *pShaderMgr = GetShaderManagerForPrimitiveShape();

	if( !pShaderMgr )
		return;

	ShaderManager& shader_mgr = *pShaderMgr;

	Vector3 s( vEdgeLengths );
	shader_mgr.SetWorldTransform( ToMatrix44(world_pose) * Matrix44Scaling(s.x,s.y,s.z) );

	if( ms_BoxMesh.GetNumVertices() == 0 )
	{
		BoxMeshGenerator generator;
		generator.Generate( Vector3(1,1,1), MeshGenerator::DEFAULT_VERTEX_FLAGS, color );
		C3DMeshModelArchive mesh_archive( generator.GetMeshArchive() );
		bool loaded = ms_BoxMesh.LoadFromArchive( mesh_archive );
	}
	else
		ms_BoxMesh.SetDiffuseColors( color );

	ms_BoxMesh.Render( shader_mgr );
}


void PrimitiveShapeRenderer::RenderCapsule( float radius, float height, const Matrix34& world_pose, const SFloatRGBAColor& color )
{
}


void PrimitiveShapeRenderer::RenderCylinder( float radius, float height, const Matrix34& world_pose, const SFloatRGBAColor& color )
{
}


ShaderManager *PrimitiveShapeRenderer::GetShaderManagerForPrimitiveShape()
{
	ShaderManager *pShaderMgr = m_Shader.GetShaderManager();

	if( pShaderMgr )
		return pShaderMgr;

	if( !sg_NoLightingShader.IsLoaded() )
		sg_NoLightingShader = GetNoLightingShader();

	return sg_NoLightingShader.GetShaderManager();
}


Result::Name PrimitiveShapeRenderer::RenderPlane(
	const Vector3 *positions,
	const Vector3& normal,
	const SFloatRGBAColor& color,
	TextureHandle& texture,
	const TEXCOORD2& top_left,
	const TEXCOORD2& bottom_right,
	ShaderManager& shader_mgr
	)
{
	if( ms_RectMesh.GetNumVertices() == 0 )
		InitRectMesh( ms_RectMesh, color );
	else
		ms_RectMesh.SetDiffuseColors( color );

	// Set the four vertices of the rectangle.
	const unsigned int num_vertices_to_set = 4;
	ms_RectMesh.SetPositions( positions, num_vertices_to_set );
	ms_RectMesh.UpdateAABBs();

	ms_RectMesh.SetNormals( normal );

	TEXCOORD2 tex_coords[4] =
	{
		TEXCOORD2( top_left.u,     top_left.v ),
		TEXCOORD2( bottom_right.u, top_left.v ),
		TEXCOORD2( bottom_right.u, bottom_right.v ),
		TEXCOORD2( top_left.u,     bottom_right.v )
	};

	ms_RectMesh.Set2DTexCoords( tex_coords, num_vertices_to_set, 0 );

//	if( ms_RectMesh.GetNumMaterials() == 0 )
//		return Result::UNKNOWN_ERROR;

	// Temporarily override the texture
	ms_RectMesh.Materials().resize( 1 );
	ms_RectMesh.Material(0).Texture.resize( 1 );
	ms_RectMesh.Material(0).Texture[0] = texture;

	ms_RectMesh.Render( shader_mgr );

	ms_RectMesh.Material(0).Texture[0] = TextureHandle();

	return Result::SUCCESS;
}


void PrimitiveShapeRenderer::RenderPlane(
	const Matrix34& pose,
	float width,
	float height,
	const SFloatRGBAColor& color,
	TextureHandle& texture,
	const TEXCOORD2& top_left,
	const TEXCOORD2& bottom_right
	)
{
	ShaderManager *pShaderMgr = GetShaderManagerForPrimitiveShape();

	if( !pShaderMgr )
		return;

	ShaderManager& shader_mgr = *pShaderMgr;

	shader_mgr.SetWorldTransform( pose );

	float hr = width  * 0.5f; // horizontal raidus
	float vr = height * 0.5f; // vertical raidus

	const Vector3 positions[4] =
	{
		Vector3(-hr, vr,0),
		Vector3( hr, vr,0),
		Vector3( hr,-vr,0),
		Vector3(-hr,-vr,0)
	};

	const Vector3 normal = pose.matOrient.GetColumn(1);

	RenderPlane( positions, normal, color, texture, top_left, bottom_right, shader_mgr );
}


void PrimitiveShapeRenderer::RenderAxisAlignedPlane(
	uint axis,
	const Vector3& vCenter,
	float span_0,
	float span_1,
	const SFloatRGBAColor& color,
	TextureHandle& texture,
	const TEXCOORD2& top_left,
	const TEXCOORD2& bottom_right
	)
{
	if( 6 <= axis )
		return;

	uint uaxis = axis % 3;

	uint span_index_0 = (uaxis+1) % 3;
	uint span_index_1 = (uaxis+2) % 3;

	if( 3 <= axis )
		std::swap( span_index_0, span_index_1 );

	Vector3 normal( Vector3(0,0,0) );
	normal[uaxis] = (axis < 3) ? 1.0f : -1.0f;

	Vector3 corners[4] =
	{
		vCenter,
		vCenter,
		vCenter,
		vCenter
	};

	corners[0][span_index_0] -= span_0 * 0.5f;
	corners[0][span_index_1] += span_1 * 0.5f;
	corners[1][span_index_0] += span_0 * 0.5f;
	corners[1][span_index_1] += span_1 * 0.5f;
	corners[2][span_index_0] += span_0 * 0.5f;
	corners[2][span_index_1] -= span_1 * 0.5f;
	corners[3][span_index_0] -= span_0 * 0.5f;
	corners[3][span_index_1] -= span_1 * 0.5f;

	TextureHandle default_texture;

	TextureHandle texture_to_set;
	if( texture.IsLoaded() )
		texture_to_set = texture;
	else
	{
		if( !default_texture.IsLoaded() )
			default_texture = CreateSingleColorTexture( SFloatRGBAColor::White(), 1, 1 );
		texture_to_set = default_texture;
	}

	ShaderManager *pShaderMgr = GetShaderManagerForPrimitiveShape();

	if( !pShaderMgr )
		return;

	ShaderManager& shader_mgr = *pShaderMgr;

	shader_mgr.SetWorldTransform( Matrix44Identity() );

	Result::Name res = shader_mgr.SetTexture( 0, texture_to_set );

	// Commented out; lighting does not work in the OpenGL mode
	// when the texture is set to the second stage. 
//	res = shader_mgr.SetTexture( 1, texture_to_set );

	RenderPlane( corners, normal, color, texture_to_set, top_left, bottom_right, shader_mgr );
}


void PrimitiveShapeRenderer::RenderFloorPlane( const Vector3& vCenter, float width, float depth, const SFloatRGBAColor& color, TextureHandle& texture, const TEXCOORD2& top_left, const TEXCOORD2& bottom_right )
{
	RenderAxisAlignedPlane( 1, vCenter, width, depth, color, texture, top_left, bottom_right );
}


void PrimitiveShapeRenderer::RenderWireframeBox( const Vector3& vEdgeLengths, const Matrix34& world_pose, const SFloatRGBAColor& wireframe_color )
{
	if( !sg_NoLightingShader.IsLoaded() )
		sg_NoLightingShader = GetNoLightingShader();

	// Wireframes are always rendered without lighting
	ShaderManager *pShaderMgr = sg_NoLightingShader.GetShaderManager();

//	ShaderManager *pShaderMgr = GetShaderManagerForPrimitiveShape();

	if( !pShaderMgr )
		return;

	ShaderManager& shader_mgr = *pShaderMgr;

	Result::Name res = shader_mgr.SetTexture( 0, GetSingleColorWhiteTexture() );
	res = shader_mgr.SetTexture( 1, GetSingleColorWhiteTexture() );

	Vector3 r( vEdgeLengths * 0.5f );
	shader_mgr.SetWorldTransform( ToMatrix44(world_pose) * Matrix44Scaling(r.x,r.y,r.z) );

//	Vector3 radii = vEdgeLengths * 0.5f;
	Vector3 vertices[8] =
	{
		Vector3( 1, 1, 1),// * radii,
		Vector3( 1, 1,-1),// * radii,
		Vector3(-1, 1,-1),// * radii,
		Vector3(-1, 1, 1),// * radii,
		Vector3( 1,-1, 1),// * radii,
		Vector3( 1,-1,-1),// * radii,
		Vector3(-1,-1,-1),// * radii,
		Vector3(-1,-1, 1),// * radii,
	};
/*
	uint indices[24] =
	{
		0, 1, 1, 2, 2, 3, 3, 0,
		0, 1, 1, 2, 2, 3, 3, 0,
		0, 1, 1, 2, 2, 3, 3, 0
	};

	GetPrimitiveRenderer().DrawIndexedLines( vertices, 8, indices, 24, wireframe_color );
*/
	Vector3 *v = vertices;
	const Vector3 points[24] =
	{
		v[0], v[1], v[1], v[2], v[2], v[3], v[3], v[0],
		v[0], v[4], v[1], v[5], v[2], v[6], v[3], v[7],
		v[4], v[5], v[5], v[6], v[6], v[7], v[7], v[4],
	};

	shader_mgr.Begin();

	const int num_edges = 12;
	for( int i=0; i<num_edges; i++ )
	{
		GetPrimitiveRenderer().DrawLine( points[i*2], points[i*2+1], wireframe_color, wireframe_color );
	}
}


} // namespace amorphous
Exemplo n.º 11
0
void PrimitiveShapeRenderer::RenderAxisAlignedPlane(
	uint axis,
	const Vector3& vCenter,
	float span_0,
	float span_1,
	const SFloatRGBAColor& color,
	TextureHandle& texture,
	const TEXCOORD2& top_left,
	const TEXCOORD2& bottom_right
	)
{
	if( 6 <= axis )
		return;

	uint uaxis = axis % 3;

	uint span_index_0 = (uaxis+1) % 3;
	uint span_index_1 = (uaxis+2) % 3;

	if( 3 <= axis )
		std::swap( span_index_0, span_index_1 );

	Vector3 normal( Vector3(0,0,0) );
	normal[uaxis] = (axis < 3) ? 1.0f : -1.0f;

	Vector3 corners[4] =
	{
		vCenter,
		vCenter,
		vCenter,
		vCenter
	};

	corners[0][span_index_0] -= span_0 * 0.5f;
	corners[0][span_index_1] += span_1 * 0.5f;
	corners[1][span_index_0] += span_0 * 0.5f;
	corners[1][span_index_1] += span_1 * 0.5f;
	corners[2][span_index_0] += span_0 * 0.5f;
	corners[2][span_index_1] -= span_1 * 0.5f;
	corners[3][span_index_0] -= span_0 * 0.5f;
	corners[3][span_index_1] -= span_1 * 0.5f;

	TextureHandle default_texture;

	TextureHandle texture_to_set;
	if( texture.IsLoaded() )
		texture_to_set = texture;
	else
	{
		if( !default_texture.IsLoaded() )
			default_texture = CreateSingleColorTexture( SFloatRGBAColor::White(), 1, 1 );
		texture_to_set = default_texture;
	}

	ShaderManager *pShaderMgr = GetShaderManagerForPrimitiveShape();

	if( !pShaderMgr )
		return;

	ShaderManager& shader_mgr = *pShaderMgr;

	shader_mgr.SetWorldTransform( Matrix44Identity() );

	Result::Name res = shader_mgr.SetTexture( 0, texture_to_set );

	// Commented out; lighting does not work in the OpenGL mode
	// when the texture is set to the second stage. 
//	res = shader_mgr.SetTexture( 1, texture_to_set );

	RenderPlane( corners, normal, color, texture_to_set, top_left, bottom_right, shader_mgr );
}
Exemplo n.º 12
0
TextureHandle CRenderLayer::CreateRenderTargetTexture(UINT width, UINT height, texture_format format)
{
	TextureHandle th = renderer->CreateRenderTargetTexture(width, height, format);
	th->IncrementReferences();
	return th;
}
Exemplo n.º 13
0
// set uniform to texture slot index (0 to 7) - same as using SetUniform(name, int) but less error prone
void Shader::SetUniform(const c8 * const name, const TextureHandle tex)
{
	SetUniform(name, (GLint)tex->GetTextureSlotIndex());
};
Exemplo n.º 14
0
TextureHandle CRenderLayer::CreateTextureFromFile(PCTSTR filename, texture_format format)
{
	TextureHandle th = renderer->CreateTextureFromFile(filename, format, true);
	th->IncrementReferences();
	return th;
}
Exemplo n.º 15
0
TextureHandle CRenderLayer::CreateTextureFromFileInMemory(LPCVOID pData, UINT len, texture_format format)
{
	TextureHandle th = renderer->CreateTextureFromFileInMemory(pData, len, format, true);
	th->IncrementReferences();
	return th;
}
Exemplo n.º 16
0
TextureHandle CRenderLayer::CreateTextureFromResource(HMODULE hModule, LPCTSTR resource, texture_format format)
{
	TextureHandle th = renderer->CreateTextureFromResource(hModule, resource, format, true);
	th->IncrementReferences();
	return th;
}
Exemplo n.º 17
0
TextureHandle TextureManager::loadTexture(const std::string& name) {
	// Check if texture has already been loaded.
	TextureHandle existing = getLoadedResource(name);
	if (existing.valid())
		return existing;

	std::string texture_filename;
	Texture::FilterMode filter_mode = Texture::FilterMode::LINEAR;
	Texture::RepeatMode repeat_mode = Texture::RepeatMode::WRAP;
	int channels = 4;

	HSQUIRRELVM vm = ::hw::engine::script_engine->vm;
	sq_pushroottable(vm);
	loadVariablePath(vm, "Resources^TextureInfo^" + name);

	const SQChar* tex_filename_cstr;

	CSQ(getKey(vm, "filename"));
	sq_getstring(vm, -1, &tex_filename_cstr);
	sq_poptop(vm);
	texture_filename = tex_filename_cstr;

	if (SQ_SUCCEEDED(getKey(vm, "channels"))) {
		sq_getinteger(vm, -1, &channels);
		sq_poptop(vm);
	}

	if (SQ_SUCCEEDED(getKey(vm, "filter_mode"))) {
		SQInteger tmp;
		sq_getinteger(vm, -1, &tmp);
		sq_poptop(vm);

		filter_mode = Texture::FilterMode(tmp);
	}

	if (SQ_SUCCEEDED(getKey(vm, "repeat_mode"))) {
		SQInteger tmp;
		sq_getinteger(vm, -1, &tmp);
		sq_poptop(vm);

		repeat_mode = Texture::RepeatMode(tmp);
	}

	texture_filename = "data/" + texture_filename;

	if (texture_filename.empty()) {
		return TextureHandle();
	}

	gl::Texture new_tex;
	glGenTextures(1, &new_tex.name);

	glBindTexture(GL_TEXTURE_2D, new_tex.name);

	setTextureParameters(filter_mode, repeat_mode);

	assert(channels >= 1 && channels <= 4);
	static const GLint internal_formats[4] = {GL_RED, GL_RG, GL_RGB, GL_RGBA};
	GLint gl_format = internal_formats[channels-1];

	int width, height, comp;
	unsigned char* data = stbi_load(texture_filename.c_str(), &width, &height, &comp, channels);
	if (data == nullptr) {
		return TextureHandle();
	}

	glTexImage2D(GL_TEXTURE_2D, 0, gl_format, width, height, 0, gl_format, GL_UNSIGNED_BYTE, data);

	return constructResource(name, Texture(std::move(new_tex), name, width, height));
}