irrlicht/source/Irrlicht/CSoftwareTexture.cpp
cutealien d03881b83a Reworking IRenderTarget interface to avoid constant memory allocations.
setTexture functions for single textures (more or less the usual case) IRenderTarget no longer need memory allocations 
on each call.
Also calling IRenderTarget::setTexture with a nullpointer no longer sets a rendertarget with an array which contains a single nullpointer but clears the array instead.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6243 dfc29bdd-3216-0410-991c-e03cc46cb475
2021-08-26 16:45:20 +00:00

171 lines
3.3 KiB
C++

// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
#include "CSoftwareTexture.h"
#include "CSoftwareDriver.h"
#include "os.h"
namespace irr
{
namespace video
{
//! constructor
CSoftwareTexture::CSoftwareTexture(IImage* image, const io::path& name, bool renderTarget)
: ITexture(name, ETT_2D), Texture(0)
{
#ifdef _DEBUG
setDebugName("CSoftwareTexture");
#endif
DriverType = EDT_SOFTWARE;
ColorFormat = ECF_A1R5G5B5;
HasMipMaps = false;
IsRenderTarget = renderTarget;
if (image)
{
bool IsCompressed = false;
if(IImage::isCompressedFormat(image->getColorFormat()))
{
os::Printer::log("Texture compression not available.", ELL_ERROR);
IsCompressed = true;
}
OriginalSize = image->getDimension();
core::dimension2d<u32> optSize = OriginalSize.getOptimalSize();
Image = new CImage(ECF_A1R5G5B5, OriginalSize);
if (!IsCompressed)
image->copyTo(Image);
if (optSize == OriginalSize)
{
Texture = Image;
Texture->grab();
}
else
{
Texture = new CImage(ECF_A1R5G5B5, optSize);
Image->copyToScaling(Texture);
}
Size = Texture->getDimension();
Pitch = Texture->getDimension().Width * 2;
}
}
//! destructor
CSoftwareTexture::~CSoftwareTexture()
{
if (Image)
Image->drop();
if (Texture)
Texture->drop();
}
//! lock function
void* CSoftwareTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags)
{
return Image->getData();
}
//! unlock function
void CSoftwareTexture::unlock()
{
if (Image != Texture)
{
os::Printer::log("Performance warning, slow unlock of non power of 2 texture.", ELL_WARNING);
Image->copyToScaling(Texture);
}
}
//! returns unoptimized surface
CImage* CSoftwareTexture::getImage()
{
return Image;
}
//! returns texture surface
CImage* CSoftwareTexture::getTexture()
{
return Texture;
}
void CSoftwareTexture::regenerateMipMapLevels(void* data, u32 layer)
{
// our software textures don't have mip maps
}
/* Software Render Target */
CSoftwareRenderTarget::CSoftwareRenderTarget(CSoftwareDriver* driver) : Driver(driver)
{
DriverType = EDT_SOFTWARE;
Textures.set_used(1);
Textures[0] = 0;
}
CSoftwareRenderTarget::~CSoftwareRenderTarget()
{
if (Textures[0])
Textures[0]->drop();
}
void CSoftwareRenderTarget::setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces)
{
if (!Textures.equals(textures, numTextures))
{
ITexture* prevTexture = Textures[0];
bool textureDetected = false;
for (u32 i = 0; i < numTextures; ++i)
{
if (textures[i] && textures[i]->getDriverType() == EDT_SOFTWARE)
{
Textures[0] = textures[i];
Textures[0]->grab();
textureDetected = true;
break;
}
}
if (prevTexture)
prevTexture->drop();
if (!textureDetected)
Textures[0] = 0;
}
}
ITexture* CSoftwareRenderTarget::getTexture() const
{
return Textures[0];
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_