コード例 #1
0
ファイル: egRendererBase.cpp プロジェクト: dreamsxin/nawia
void RenderDevice::uploadTextureData( uint32 texObj, int slice, int mipLevel, const void *pixels )
{
	const RDITexture &tex = _textures.getRef( texObj );
	TextureFormats::List format = tex.format;

	glActiveTexture( GL_TEXTURE15 );
	glBindTexture( tex.type, tex.glObj );
	
	int inputFormat = GL_BGRA, inputType = GL_UNSIGNED_BYTE;
	bool compressed = (format == TextureFormats::DXT1) || (format == TextureFormats::DXT3) ||
	                  (format == TextureFormats::DXT5);
	
	switch( format )
	{
	case TextureFormats::RGBA16F:
		inputFormat = GL_RGBA;
		inputType = GL_FLOAT;
		break;
	case TextureFormats::RGBA32F:
		inputFormat = GL_RGBA;
		inputType = GL_FLOAT;
		break;
	case TextureFormats::DEPTH:
		inputFormat = GL_DEPTH_COMPONENT;
		inputType = GL_FLOAT;
	};
	
	// Calculate size of next mipmap using "floor" convention
	int width = std::max( tex.width >> mipLevel, 1 ), height = std::max( tex.height >> mipLevel, 1 );
	
	if( tex.type == TextureTypes::Tex2D || tex.type == TextureTypes::TexCube )
	{
		int target = (tex.type == TextureTypes::Tex2D) ?
			GL_TEXTURE_2D : (GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice);
		
		if( compressed )
			glCompressedTexImage2D( target, mipLevel, tex.glFmt, width, height, 0,
			                        calcTextureSize( format, width, height, 1 ), pixels );	
		else
			glTexImage2D( target, mipLevel, tex.glFmt, width, height, 0, inputFormat, inputType, pixels );
	}
	else if( tex.type == TextureTypes::Tex3D )
	{
		int depth = std::max( tex.depth >> mipLevel, 1 );
		
		if( compressed )
			glCompressedTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			                        calcTextureSize( format, width, height, depth ), pixels );	
		else
			glTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			              inputFormat, inputType, pixels );
	}
コード例 #2
0
ファイル: utTexture.cpp プロジェクト: CZdravko/Horde
bool utTextureLoadKTX( const char *data, int size, utTextureInfo* info )
{
	ASSERT_STATIC( sizeof( KTXHeader ) == 64 );

	info->_surfaces = NULL;

	memcpy( &ktxHeader, data, 64 );

	// Check header
	if( memcmp(ktxHeader.identifier, ktxIdentifier, 12) !=0 )
	{
		Modules::log().writeError( "Invalid KTX header" );
		return false;
	}
	
	// Store properties
    info->_width = ktxHeader.pixelWidth;
    info->_height = ktxHeader.pixelHeight;
	info->_depth = 1;
    info->_format = utTextureFormats::Unknown;
	info->_mipCount = ktxHeader.numberOfMipmapLevels;

	// Get texture type
	if( ktxHeader.numberOfFaces > 1 )
	{
		if( ktxHeader.numberOfFaces != 6 )
		{
			Modules::log().writeError( "Wrong number of cube texture faces (should be 6)" );
			return false;
		}
		else
		{
			info->_type = utTextureTypes::TexCube;
		}
	}
	else if( ktxHeader.pixelDepth > 1 )
	{
		info->_depth = ktxHeader.pixelDepth;
		info->_type = utTextureTypes::Tex3D;
	}
	else
		info->_type = utTextureTypes::Tex2D;
	
	// Texture arrays are not supported yet
	if( ktxHeader.numberOfArrayElements > 1 )
	{
		Modules::log().writeWarning( "Texture Arrays not supported. using first array element only" );
	}

	// Get pixel format
	switch( ktxHeader.glInternalFormat )
	{
		case GL_RGB8:
			info->_format = utTextureFormats::RGB8;
			break;
		case GL_RGBA8:
			info->_format = utTextureFormats::BGRA8;
			break;
		case GL_BGRA:
			info->_format = utTextureFormats::BGRA8;
			break;
		case GL_RGBA16F:
			info->_format = utTextureFormats::RGBA16F;
			break;
		case GL_RGBA32F:
			info->_format = utTextureFormats::RGBA32F;
			break;
		case GL_COMPRESSED_RGBA_S3TC_DXT1:
			info->_format = utTextureFormats::DXT1;
			break;
		case GL_COMPRESSED_RGBA_S3TC_DXT3:
			info->_format = utTextureFormats::DXT3;
			break;
		case GL_COMPRESSED_RGBA_S3TC_DXT5:
			info->_format = utTextureFormats::DXT5;
			break;
		case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_2BPP;
			break;
		case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_A2BPP;
			break;
		case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_4BPP;
			break;
		case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_A4BPP;
			break;
		case GL_ETC1_RGB8_OES:
			info->_format = utTextureFormats::ETC1;
			break;
	}
	
	if( info->_format == utTextureFormats::Unknown )
	{
		Modules::log().writeError( "Unsupported KTX pixel format" );
		return false;
	}

	info->_sliceCount = info->_type == utTextureTypes::TexCube ? 6 : 1;
	unsigned char *pixels = (unsigned char *)(data + 128);

	uint32 surfaceIndex = 0;
	info->_surfaceCount = info->_sliceCount * info->_mipCount;
	info->_surfaces = new utTextureSurfaceInfo[info->_surfaceCount];

	int width = info->_width, height = info->_height, depth = info->_depth;

	for( uint32 i = 0; i < info->_mipCount; ++i )
	{
		size_t mipSize =  calcTextureSize( info->_format, width, height, depth );
		if( pixels + mipSize > (unsigned char *)data + size )
		{
			Modules::log().writeError( "Corrupt KTX" );
			return false;
		}
		
		for( uint32 j = 0; j < ktxHeader.numberOfArrayElements; ++j )
		{
			for( uint32 k = 0; k < ktxHeader.numberOfFaces; ++k )
			{
				if ( j == 0)
				{	// using only first element of array now
					utTextureSurfaceInfo& surface = info->_surfaces[surfaceIndex++];
					surface._mip = i;
					surface._slice = k;
					surface._data = pixels;
					surface._size = (uint32)mipSize;
				}
					
				pixels += mipSize;
			}
		}
		if( width > 1 ) width >>= 1;
		if( height > 1 ) height >>= 1;
		if( depth > 1 ) depth >>= 1;
	}

	ASSERT( pixels == (unsigned char *)data + size );
	return true;
}
コード例 #3
0
ファイル: utTexture.cpp プロジェクト: CZdravko/Horde
bool utTextureLoadPVR( const char* data, uint32 size, utTextureInfo* info)
{
	// Load pvr
    ASSERT_STATIC( sizeof( PVRHeader ) == 52 );

	info->_surfaces = NULL;

	memcpy( &pvrHeader, data, 52 );

    // Store properties
    info->_width = pvrHeader.dwWidth;
    info->_height = pvrHeader.dwHeight;
	info->_depth = 1;
    info->_format = utTextureFormats::Unknown;
	info->_mipCount = pvrHeader.dwMipMapCount;

    // Get texture type
    if( pvrHeader.dwNumFaces == 6 )
    {
		info->_type = utTextureTypes::TexCube;
    }
    else
    {
		info->_type = utTextureTypes::Tex2D;
    }

    // Get pixel format
	if (pvrHeader.dwPixelFormatHigh == 0 )
	{
		switch(pvrHeader.dwPixelFormatLow)
		{
		case ePVRTPF_PVRTCI_2bpp_RGBA:
			info->_format = utTextureFormats::PVRTCI_A2BPP;
			break;
		case ePVRTPF_PVRTCI_4bpp_RGBA:
			info->_format = utTextureFormats::PVRTCI_A4BPP;
			break;
		case ePVRTPF_DXT1:
			info->_format = utTextureFormats::DXT1;
			break;
		case ePVRTPF_DXT3:
			info->_format = utTextureFormats::DXT3;
			break;
		case ePVRTPF_DXT5:
			info->_format = utTextureFormats::DXT5;
			break;
		case ePVRTPF_PVRTCI_2bpp_RGB:
			info->_format = utTextureFormats::PVRTCI_2BPP;
			break;
		case ePVRTPF_PVRTCI_4bpp_RGB:
			info->_format = utTextureFormats::PVRTCI_4BPP;
			break;
		case ePVRTPF_ETC1:
			info->_format = utTextureFormats::ETC1;
			break;
		}
	}

	if( info->_format == utTextureFormats::Unknown )
	{
		Modules().log().writeError( "Unsupported PVR pixel format" );
		return false;
	}

    // Upload texture subresources
    info->_sliceCount = info->_type == utTextureTypes::TexCube ? 6 : 1;
    unsigned char *pixels = (unsigned char *)(data + 52);

	uint32 surfaceIndex = 0;
	info->_surfaceCount = info->_sliceCount * info->_mipCount;
	info->_surfaces = new utTextureSurfaceInfo[info->_surfaceCount];

    for( uint32 i = 0; i < info->_sliceCount; ++i )
    {
        int width = pvrHeader.dwWidth, height = pvrHeader.dwHeight;

        for( uint32 j = 0; j < info->_mipCount; ++j )
        {
			size_t mipSize =  calcTextureSize( info->_format, width, height, 1 );
            if( pixels + mipSize > (unsigned char *)data + size )
 			{
				Modules::log().writeError( "Corrupt PVR" );
				return false;
			}

			utTextureSurfaceInfo& surface = info->_surfaces[surfaceIndex++];
			surface._mip = j;
			surface._slice = i;
			surface._data = pixels;
			surface._size = (uint32)mipSize;

            pixels += mipSize;
            if( width > 1 ) width >>= 1;
            if( height > 1 ) height >>= 1;
        }
    }

    ASSERT( pixels == (unsigned char *)data + size);
	return true;
}
コード例 #4
0
ファイル: egRendererBase.cpp プロジェクト: dreamsxin/nawia
uint32 RenderDevice::createTexture( TextureTypes::List type, int width, int height, int depth,
                                    TextureFormats::List format,
                                    bool hasMips, bool genMips, bool compress, bool sRGB )
{
	if( !_caps.texNPOT )
	{
		// Check if texture is NPOT
		if( (width & (width-1)) != 0 || (height & (height-1)) != 0 )
			Modules::log().writeWarning( "Texture has non-power-of-two dimensions although NPOT is not supported by GPU" );
	}
	
	RDITexture tex;
	tex.type = type;
	tex.format = format;
	tex.width = width;
	tex.height = height;
	tex.depth = (type == TextureTypes::Tex3D ? depth : 1);
	tex.sRGB = sRGB && Modules::config().sRGBLinearization;
	tex.genMips = genMips;
	tex.hasMips = hasMips;
	
	switch( format )
	{
	case TextureFormats::BGRA8:
		tex.glFmt = tex.sRGB ? GL_SRGB8_ALPHA8_EXT : GL_RGBA8;
		break;
	case TextureFormats::DXT1:
		tex.glFmt = tex.sRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT : GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
		break;
	case TextureFormats::DXT3:
		tex.glFmt = tex.sRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
		break;
	case TextureFormats::DXT5:
		tex.glFmt = tex.sRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
		break;
	case TextureFormats::RGBA16F:
		tex.glFmt = GL_RGBA16F_ARB;
		break;
	case TextureFormats::RGBA32F:
		tex.glFmt = GL_RGBA32F_ARB;
		break;
	case TextureFormats::DEPTH:
		tex.glFmt = _depthFormat;
		break;
	default:
		ASSERT( 0 );
		break;
	};
	
	glGenTextures( 1, &tex.glObj );
	glActiveTexture( GL_TEXTURE15 );
	glBindTexture( tex.type, tex.glObj );
	
	float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	glTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor );
	
	tex.samplerState = 0;
	applySamplerState( tex );
	
	glBindTexture( tex.type, 0 );
	if( _texSlots[15].texObj )
		glBindTexture( _textures.getRef( _texSlots[15].texObj ).type, _textures.getRef( _texSlots[15].texObj ).glObj );

	// Calculate memory requirements
	tex.memSize = calcTextureSize( format, width, height, depth );
	if( hasMips || genMips ) tex.memSize += ftoi_r( tex.memSize * 1.0f / 3.0f );
	if( type == TextureTypes::TexCube ) tex.memSize *= 6;
	_textureMem += tex.memSize;
	
	return _textures.add( tex );
}
コード例 #5
0
void RenderDevice::uploadTextureData( uint32 texObj, int slice, int mipLevel, const void *pixels )
{
	const RDITexture &tex = _textures.getRef( texObj );
	TextureFormats::List format = tex.format;

    glActiveTexture( GL_TEXTURE0 );
	glBindTexture( tex.type, tex.glObj );
	
#ifdef PLATFORM_ES2
	int inputFormat = GL_RGBA, inputType = GL_UNSIGNED_BYTE;
#else
	int inputFormat = GL_BGRA, inputType = GL_UNSIGNED_BYTE;
#endif
	bool compressed = (format == TextureFormats::DXT1) || (format == TextureFormats::DXT3) || (format == TextureFormats::DXT5) || 
                        (format == TextureFormats::PVRTC2) || (format == TextureFormats::PVRTCA2) ||
                        (format == TextureFormats::PVRTC4) || (format == TextureFormats::PVRTCA4);
	
	switch( format )
	{
	case TextureFormats::RGBA16F:
		inputFormat = GL_RGBA;
#ifdef PLATFORM_ES2
        // GL_HALF_FLOAT_OES seems not to work on 3GS, 4G and iPad1
        // http://stackoverflow.com/questions/3850569/render-to-floating-point-texture-under-ios
        inputType = glExt::OES_texture_half_float ? GL_HALF_FLOAT_OES : GL_RGBA ;
#else
		inputType = GL_FLOAT;
#endif
		break;
	case TextureFormats::RGBA32F:
		inputFormat = GL_RGBA;
		inputType = GL_FLOAT;
		break;
	case TextureFormats::DEPTH:
		inputFormat = GL_DEPTH_COMPONENT;
#ifdef PLATFORM_ES2
		inputType = GL_UNSIGNED_SHORT;
#else
		inputType = GL_FLOAT;
#endif
    default:
        break;
	};
	
	// Calculate size of next mipmap using "floor" convention
	int width = std::max( tex.width >> mipLevel, 1 ), height = std::max( tex.height >> mipLevel, 1 );
	
	if ( (tex.type == TextureTypes::Tex2D && (width>_maxTextureSize || height>_maxTextureSize)) || 
		 (tex.type == TextureTypes::TexCube && (width>_maxCubeTextureSize || height>_maxCubeTextureSize)))
        goto UPLOADE_TEXUTURE_EXIT;//return;

	if( tex.type == TextureTypes::Tex2D || tex.type == TextureTypes::TexCube )
	{
		int target = (tex.type == TextureTypes::Tex2D) ? GL_TEXTURE_2D : (GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice);
		
		if( compressed )
			glCompressedTexImage2D( target, mipLevel, tex.glFmt, width, height, 0,
			                        calcTextureSize( format, width, height, 1 ), pixels );	
		else
			glTexImage2D( target, mipLevel, tex.glFmt, width, height, 0, inputFormat, inputType, pixels );
	}
	else if( tex.type == TextureTypes::Tex3D )
	{
#if !defined(PLATFORM_ES2)
		int depth = std::max( tex.depth >> mipLevel, 1 );
		
		if( compressed )
			glCompressedTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			                        calcTextureSize( format, width, height, depth ), pixels );	
		else
			glTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			              inputFormat, inputType, pixels );
#endif
	}