Merging r5892 through r5916 from trunk to ogl-es branch
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5917 dfc29bdd-3216-0410-991c-e03cc46cb475master
|
@ -66,6 +66,9 @@ namespace video
|
|||
EMF_NORMALIZE_NORMALS = 0x1000,
|
||||
|
||||
//! Access to all layers texture wrap settings. Overwrites separate layer settings.
|
||||
/** Note that if you want to change TextureWrapU, TextureWrapV, TextureWrapW
|
||||
independently, then you can't work with this flag, but will have to set the variables
|
||||
directly. */
|
||||
EMF_TEXTURE_WRAP = 0x2000,
|
||||
|
||||
//! AntiAliasing mode
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace io
|
|||
ERFT_LIMIT_READ_FILE = MAKE_IRR_ID('r','l','i','m'),
|
||||
|
||||
//! Unknown type
|
||||
EFIT_UNKNOWN = MAKE_IRR_ID('u','n','k','n'),
|
||||
EFIT_UNKNOWN = MAKE_IRR_ID('u','n','k','n')
|
||||
};
|
||||
} // end namespace io
|
||||
} // end namespace irr
|
||||
|
|
|
@ -187,10 +187,68 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
//! Get mipmaps data.
|
||||
void* getMipMapsData() const
|
||||
//! Get the mipmap size for this image for a certain mipmap level
|
||||
/** level 0 will be full image size. Every further level is half the size.
|
||||
Doesn't care if the image actually has mipmaps, just which size would be needed. */
|
||||
core::dimension2du getMipMapsSize(u32 mipmapLevel) const
|
||||
{
|
||||
return MipMapsData;
|
||||
return getMipMapsSize(Size, mipmapLevel);
|
||||
}
|
||||
|
||||
|
||||
//! Calculate mipmap size for a certain level
|
||||
/** level 0 will be full image size. Every further level is half the size. */
|
||||
static core::dimension2du getMipMapsSize(const core::dimension2du& sizeLevel0, u32 mipmapLevel)
|
||||
{
|
||||
core::dimension2du result(sizeLevel0);
|
||||
u32 i=0;
|
||||
while (i != mipmapLevel)
|
||||
{
|
||||
if (result.Width>1)
|
||||
result.Width >>= 1;
|
||||
if (result.Height>1)
|
||||
result.Height>>=1;
|
||||
++i;
|
||||
|
||||
if ( result.Width == 1 && result.Height == 1 && i < mipmapLevel )
|
||||
return core::dimension2du(0,0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//! Get mipmaps data.
|
||||
/** Note that different mip levels are just behind each other in memory block.
|
||||
So if you just get level 1 you also have the data for all other levels.
|
||||
There is no level 0 - use getData to get the original image data.
|
||||
*/
|
||||
void* getMipMapsData(irr::u32 mipLevel=1) const
|
||||
{
|
||||
if ( MipMapsData && mipLevel > 0)
|
||||
{
|
||||
size_t dataSize = 0;
|
||||
core::dimension2du mipSize(Size);
|
||||
u32 i = 1; // We want the start of data for this level, not end.
|
||||
|
||||
while (i != mipLevel)
|
||||
{
|
||||
if (mipSize.Width > 1)
|
||||
mipSize.Width >>= 1;
|
||||
|
||||
if (mipSize.Height > 1)
|
||||
mipSize.Height >>= 1;
|
||||
|
||||
dataSize += getDataSizeFromFormat(Format, mipSize.Width, mipSize.Height);
|
||||
|
||||
++i;
|
||||
if ( mipSize.Width == 1 && mipSize.Height == 1 && i < mipLevel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MipMapsData + dataSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Set mipmaps data.
|
||||
|
@ -258,19 +316,24 @@ public:
|
|||
virtual void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ) = 0;
|
||||
|
||||
//! Copies the image into the target, scaling the image to fit
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format=ECF_A8R8G8B8, u32 pitch=0) =0;
|
||||
|
||||
//! Copies the image into the target, scaling the image to fit
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyToScaling(IImage* target) =0;
|
||||
|
||||
//! copies this surface into another
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyTo(IImage* target, const core::position2d<s32>& pos=core::position2d<s32>(0,0)) =0;
|
||||
|
||||
//! copies this surface into another
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect=0) =0;
|
||||
|
||||
//! copies this surface into another, using the alpha mask and cliprect and a color to add with
|
||||
/** \param combineAlpha - When true then combine alpha channels. When false replace target image alpha with source image alpha.
|
||||
/** NOTE: mipmaps are ignored
|
||||
\param combineAlpha - When true then combine alpha channels. When false replace target image alpha with source image alpha.
|
||||
*/
|
||||
virtual void copyToWithAlpha(IImage* target, const core::position2d<s32>& pos,
|
||||
const core::rect<s32>& sourceRect, const SColor &color,
|
||||
|
@ -278,6 +341,7 @@ public:
|
|||
bool combineAlpha=false) =0;
|
||||
|
||||
//! copies this surface into another, scaling it to fit, applying a box filter
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyToScalingBoxFilter(IImage* target, s32 bias = 0, bool blend = false) = 0;
|
||||
|
||||
//! fills the surface with given color
|
||||
|
@ -453,7 +517,7 @@ public:
|
|||
|
||||
switch(format)
|
||||
{
|
||||
case ECF_R16:
|
||||
case ECF_R16F:
|
||||
case ECF_G16R16F:
|
||||
case ECF_A16B16G16R16F:
|
||||
case ECF_R32F:
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace video
|
|||
{
|
||||
|
||||
|
||||
//! Enumeration flags telling the video driver in which format textures should be created.
|
||||
//! Enumeration flags used to tell the video driver with setTextureCreationFlag in which format textures should be created.
|
||||
enum E_TEXTURE_CREATION_FLAG
|
||||
{
|
||||
/** Forces the driver to create 16 bit textures always, independent of
|
||||
|
@ -36,6 +36,7 @@ enum E_TEXTURE_CREATION_FLAG
|
|||
which format the file on disk has. Please note that some drivers (like
|
||||
the software device) will ignore this, because they are only able to
|
||||
create and use 16 bit textures.
|
||||
Default is true.
|
||||
When using this flag, it does not make sense to use the flags
|
||||
ETCF_ALWAYS_16_BIT, ETCF_OPTIMIZED_FOR_QUALITY, or
|
||||
ETCF_OPTIMIZED_FOR_SPEED at the same time.
|
||||
|
@ -59,7 +60,9 @@ enum E_TEXTURE_CREATION_FLAG
|
|||
Not all texture formats are affected (usually those up to ECF_A8R8G8B8). */
|
||||
ETCF_OPTIMIZED_FOR_SPEED = 0x00000008,
|
||||
|
||||
/** Automatically creates mip map levels for the textures. */
|
||||
/** Creates textures with mipmap levels.
|
||||
If disabled textures can not have mipmaps.
|
||||
Default is true. */
|
||||
ETCF_CREATE_MIP_MAPS = 0x00000010,
|
||||
|
||||
/** Discard any alpha layer and use non-alpha color format.
|
||||
|
@ -80,6 +83,20 @@ enum E_TEXTURE_CREATION_FLAG
|
|||
*/
|
||||
ETCF_ALLOW_MEMORY_COPY = 0x00000080,
|
||||
|
||||
//! Enable automatic updating mip maps when the base texture changes.
|
||||
/** Default is true.
|
||||
This flag is only used when ETCF_CREATE_MIP_MAPS is also enabled and if the driver supports it.
|
||||
Please note:
|
||||
- On D3D (and maybe older OGL?) you can no longer manually set mipmap data when enabled
|
||||
(for example mips from image loading will be ignored).
|
||||
- On D3D (and maybe older OGL?) texture locking for mipmap levels usually won't work anymore.
|
||||
- On new OGL this flag is ignored.
|
||||
- When disabled you do _not_ get hardware mipmaps on D3D, so mipmap generation can be slower.
|
||||
- When disabled you can still update your mipmaps when the texture changed by manually calling regenerateMipMapLevels.
|
||||
- You can still call regenerateMipMapLevels when this flag is enabled (it will be a hint on d3d to update mips immediately)
|
||||
*/
|
||||
ETCF_AUTO_GENERATE_MIP_MAPS = 0x00000100,
|
||||
|
||||
/** This flag is never used, it only forces the compiler to compile
|
||||
these enumeration values to 32 bit. */
|
||||
ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff
|
||||
|
@ -194,7 +211,8 @@ public:
|
|||
|
||||
//! Unlock function. Must be called after a lock() to the texture.
|
||||
/** One should avoid to call unlock more than once before another lock.
|
||||
The last locked mip level will be unlocked. */
|
||||
The last locked mip level will be unlocked.
|
||||
You may want to call regenerateMipMapLevels() after this when you changed any data. */
|
||||
virtual void unlock() = 0;
|
||||
|
||||
//! Regenerates the mip map levels of the texture.
|
||||
|
@ -204,8 +222,8 @@ public:
|
|||
data. The data has to be a continuous pixel data for all mipmaps until
|
||||
1x1 pixel. Each mipmap has to be half the width and height of the previous
|
||||
level. At least one pixel will be always kept.
|
||||
\param layer It informs a texture about layer which needs
|
||||
mipmaps regeneration. */
|
||||
\param layer It informs a texture about which cubemap or texture array layer
|
||||
needs mipmap regeneration. */
|
||||
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) = 0;
|
||||
|
||||
//! Get original size of the texture.
|
||||
|
|
|
@ -35,8 +35,11 @@ namespace video
|
|||
u16 EnablePasses;
|
||||
|
||||
//! Global enable flag, overwritten by the SceneManager in each pass
|
||||
/** The Scenemanager uses the EnablePass array and sets Enabled to
|
||||
true if the Override material is enabled in the current pass. */
|
||||
/** NOTE: This is generally _not_ set by users of the engine, but the
|
||||
Scenemanager uses the EnablePass array and sets Enabled to true if the
|
||||
Override material is enabled in the current pass.
|
||||
As user you generally _only_ set EnablePasses.
|
||||
The exception is when rendering without SceneManager but using draw calls in the VideoDriver. */
|
||||
bool Enabled;
|
||||
|
||||
struct SMaterialTypeReplacement
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// part of the Irrlicht Engine Shader example.
|
||||
// Part of the Irrlicht Engine Shader example.
|
||||
// These simple Direct3D9 pixel and vertex shaders will be loaded by the shaders
|
||||
// example. Please note that these example shaders don't do anything really useful.
|
||||
// They only demonstrate that shaders can be used in Irrlicht.
|
||||
|
@ -9,7 +9,7 @@
|
|||
float4x4 mWorldViewProj; // World * View * Projection transformation
|
||||
float4x4 mInvWorld; // Inverted world matrix
|
||||
float4x4 mTransWorld; // Transposed world matrix
|
||||
float3 mLightPos; // Light position
|
||||
float3 mLightPos; // Light position (actually just camera-pos in this case)
|
||||
float4 mLightColor; // Light color
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ struct VS_OUTPUT
|
|||
};
|
||||
|
||||
|
||||
VS_OUTPUT vertexMain( in float4 vPosition : POSITION,
|
||||
VS_OUTPUT vertexMain(in float4 vPosition : POSITION,
|
||||
in float3 vNormal : NORMAL,
|
||||
float2 texCoord : TEXCOORD0 )
|
||||
{
|
||||
|
@ -31,13 +31,13 @@ VS_OUTPUT vertexMain( in float4 vPosition : POSITION,
|
|||
// transform position to clip space
|
||||
Output.Position = mul(vPosition, mWorldViewProj);
|
||||
|
||||
// transform normal
|
||||
float3 normal = mul(vNormal, mInvWorld);
|
||||
// transform normal somehow (NOTE: for the real vertex normal you would use an inverse-transpose world matrix instead of mInvWorld)
|
||||
float3 normal = mul(float4(vNormal,0.0), mInvWorld);
|
||||
|
||||
// renormalize normal
|
||||
normal = normalize(normal);
|
||||
|
||||
// position in world coodinates
|
||||
// position in world coordinates (NOTE: not sure why transposed world is used instead of world?)
|
||||
float3 worldpos = mul(mTransWorld, vPosition);
|
||||
|
||||
// calculate light vector, vtxpos - lightpos
|
||||
|
@ -58,7 +58,6 @@ VS_OUTPUT vertexMain( in float4 vPosition : POSITION,
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Pixel shader output structure
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
|
@ -66,15 +65,15 @@ struct PS_OUTPUT
|
|||
};
|
||||
|
||||
|
||||
sampler2D tex0;
|
||||
sampler2D myTexture;
|
||||
|
||||
PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,
|
||||
PS_OUTPUT pixelMain(float2 TexCoord : TEXCOORD0,
|
||||
float4 Position : POSITION,
|
||||
float4 Diffuse : COLOR0 )
|
||||
{
|
||||
PS_OUTPUT Output;
|
||||
|
||||
float4 col = tex2D( tex0, TexCoord ); // sample color map
|
||||
float4 col = tex2D( myTexture, TexCoord ); // sample color map
|
||||
|
||||
// multiply with diffuse and do other senseless operations
|
||||
Output.RGBColor = Diffuse * col;
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
// Part of the Irrlicht Engine Shader example.
|
||||
// Simple GLSL vertex shader
|
||||
// Please note that these example shaders don't do anything really useful.
|
||||
// They only demonstrate that shaders can be used in Irrlicht.
|
||||
|
||||
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
uniform vec3 mLightPos;
|
||||
uniform vec3 mLightPos; // actually just camera-pos in this case
|
||||
uniform vec4 mLightColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
|
||||
// transform normal somehow (NOTE: for the real vertex normal you would use an inverse-transpose world matrix instead of mInvWorld)
|
||||
vec4 normal = vec4(gl_Normal, 0.0);
|
||||
normal = mInvWorld * normal;
|
||||
normal = normalize(normal);
|
||||
|
||||
// (NOTE: not sure why transposed world is used instead of world?)
|
||||
vec4 worldpos = gl_Vertex * mTransWorld;
|
||||
|
||||
vec4 lightVector = worldpos - vec4(mLightPos,1.0);
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace irr
|
|||
if ((Texture != texture) || (CubeSurfaces != cubeSurfaces))
|
||||
{
|
||||
needSizeUpdate = true;
|
||||
CubeSurfaces = cubeSurfaces;
|
||||
CubeSurfaces = cubeSurfaces; // TODO: we can probably avoid some memory allocating/de-allocating if _only_ CubeSurfaces change.
|
||||
|
||||
if (texture.size() > Driver->ActiveRenderTarget.size())
|
||||
{
|
||||
|
@ -78,11 +78,7 @@ namespace irr
|
|||
|
||||
Surface.set_used(size);
|
||||
|
||||
for (u32 i = 0; i < Texture.size(); ++i)
|
||||
{
|
||||
if (Texture[i])
|
||||
Texture[i]->drop();
|
||||
}
|
||||
core::array<ITexture*> prevTextures(Texture);
|
||||
|
||||
Texture.set_used(size);
|
||||
|
||||
|
@ -129,6 +125,12 @@ namespace irr
|
|||
Texture[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < prevTextures.size(); ++i)
|
||||
{
|
||||
if (prevTextures[i])
|
||||
prevTextures[i]->drop();
|
||||
}
|
||||
}
|
||||
|
||||
// Set depth and stencil attachments.
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace video
|
|||
|
||||
CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& image, E_TEXTURE_TYPE type, CD3D9Driver* driver)
|
||||
: ITexture(name, type), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockReadOnly(false), LockData(0), LockLayer(0),
|
||||
AutoGenerateMipMaps(false), Device(0), Texture(0), CubeTexture(0), RTTSurface(0)
|
||||
MipLevelLocked(0), HardwareMipMaps(false), Device(0), Texture(0), CubeTexture(0), RTTSurface(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CD3D9Texture");
|
||||
|
@ -32,13 +32,13 @@ CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& ima
|
|||
|
||||
DriverType = Driver->getDriverType();
|
||||
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
|
||||
AutoGenerateMipMaps = Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE);
|
||||
HardwareMipMaps = Driver->getTextureCreationFlag(ETCF_AUTO_GENERATE_MIP_MAPS) && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE);
|
||||
|
||||
getImageValues(image[0]);
|
||||
|
||||
DWORD flags = 0;
|
||||
|
||||
if (HasMipMaps && AutoGenerateMipMaps)
|
||||
if (HasMipMaps && HardwareMipMaps)
|
||||
{
|
||||
LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9;
|
||||
D3DDISPLAYMODE d3ddm;
|
||||
|
@ -47,7 +47,7 @@ CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& ima
|
|||
if (D3D_OK == intf->CheckDeviceFormat(Driver->Params.DisplayAdapter, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, InternalFormat))
|
||||
flags = D3DUSAGE_AUTOGENMIPMAP;
|
||||
else
|
||||
AutoGenerateMipMaps = false;
|
||||
HardwareMipMaps = false;
|
||||
}
|
||||
|
||||
HRESULT hr = 0;
|
||||
|
@ -110,7 +110,7 @@ CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& ima
|
|||
}
|
||||
|
||||
for (u32 i = 0; i < tmpImage.size(); ++i)
|
||||
uploadTexture(i, 0, tmpImage[i]->getData());
|
||||
uploadTexture(tmpImage[i]->getData(), 0, i);
|
||||
|
||||
bool autoGenerateRequired = true;
|
||||
|
||||
|
@ -152,7 +152,7 @@ CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& ima
|
|||
|
||||
CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size, const io::path& name, E_TEXTURE_TYPE type, const ECOLOR_FORMAT format)
|
||||
: ITexture(name, type), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockReadOnly(false), LockData(0), LockLayer(0),
|
||||
AutoGenerateMipMaps(false), Device(0), Texture(0), CubeTexture(0), RTTSurface(0)
|
||||
MipLevelLocked(0), HardwareMipMaps(false), Device(0), Texture(0), CubeTexture(0), RTTSurface(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CD3D9Texture");
|
||||
|
@ -208,6 +208,7 @@ void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E
|
|||
if (IImage::isCompressedFormat(ColorFormat))
|
||||
return 0;
|
||||
|
||||
MipLevelLocked = mipmapLevel;
|
||||
LockReadOnly = (mode == ETLM_READ_ONLY);
|
||||
LockLayer = layer;
|
||||
|
||||
|
@ -218,13 +219,13 @@ void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E
|
|||
{
|
||||
if (Texture)
|
||||
{
|
||||
hr = Texture->LockRect(0, &rect, 0, LockReadOnly ? D3DLOCK_READONLY : 0);
|
||||
hr = Texture->LockRect(MipLevelLocked, &rect, 0, LockReadOnly ? D3DLOCK_READONLY : 0);
|
||||
}
|
||||
else if (CubeTexture)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(layer > 5)
|
||||
|
||||
hr = CubeTexture->LockRect(static_cast<_D3DCUBEMAP_FACES>(layer), 0, &rect, 0, LockReadOnly ? D3DLOCK_READONLY : 0);
|
||||
hr = CubeTexture->LockRect(static_cast<_D3DCUBEMAP_FACES>(layer), MipLevelLocked, &rect, 0, LockReadOnly ? D3DLOCK_READONLY : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -258,9 +259,9 @@ void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E
|
|||
|
||||
IDirect3DSurface9 *surface = 0;
|
||||
if (Texture)
|
||||
hr = Texture->GetSurfaceLevel(0, &surface);
|
||||
hr = Texture->GetSurfaceLevel(MipLevelLocked, &surface);
|
||||
else if (CubeTexture)
|
||||
hr = CubeTexture->GetCubeMapSurface(static_cast<_D3DCUBEMAP_FACES>(layer), 0, &surface);
|
||||
hr = CubeTexture->GetCubeMapSurface(static_cast<_D3DCUBEMAP_FACES>(layer), MipLevelLocked, &surface);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
os::Printer::log("Could not lock DIRECT3D9 Texture", "Could not get surface.", ELL_ERROR);
|
||||
|
@ -295,11 +296,11 @@ void CD3D9Texture::unlock()
|
|||
{
|
||||
if (Texture)
|
||||
{
|
||||
Texture->UnlockRect(0);
|
||||
Texture->UnlockRect(MipLevelLocked);
|
||||
}
|
||||
else if (CubeTexture)
|
||||
{
|
||||
CubeTexture->UnlockRect(static_cast<_D3DCUBEMAP_FACES>(LockLayer), 0);
|
||||
CubeTexture->UnlockRect(static_cast<_D3DCUBEMAP_FACES>(LockLayer), MipLevelLocked);
|
||||
}
|
||||
}
|
||||
else if (RTTSurface)
|
||||
|
@ -307,9 +308,6 @@ void CD3D9Texture::unlock()
|
|||
RTTSurface->UnlockRect();
|
||||
}
|
||||
|
||||
if (!LockReadOnly)
|
||||
regenerateMipMapLevels(0, LockLayer);
|
||||
|
||||
LockReadOnly = false;
|
||||
LockData = 0;
|
||||
LockLayer = 0;
|
||||
|
@ -317,10 +315,20 @@ void CD3D9Texture::unlock()
|
|||
|
||||
void CD3D9Texture::regenerateMipMapLevels(void* data, u32 layer)
|
||||
{
|
||||
if (!HasMipMaps || (!data && !AutoGenerateMipMaps) || (Size.Width <= 1 && Size.Height <= 1))
|
||||
if (!HasMipMaps || (Size.Width <= 1 && Size.Height <= 1))
|
||||
return;
|
||||
|
||||
if (data)
|
||||
if ( HardwareMipMaps )
|
||||
{
|
||||
// Can't update with custom data with those unfortunately
|
||||
// Also MSDN docs don't mention it, but GenerateMipSubLevels only works when AUTOGENMIPMAP is set.
|
||||
// So we can't call this to get hardware mipmaps when not setting AUTOGENMIPMAP.
|
||||
if (Texture)
|
||||
Texture->GenerateMipSubLevels();
|
||||
else if (CubeTexture)
|
||||
CubeTexture->GenerateMipSubLevels();
|
||||
}
|
||||
else if (data)
|
||||
{
|
||||
u32 width = Size.Width;
|
||||
u32 height = Size.Height;
|
||||
|
@ -339,20 +347,195 @@ void CD3D9Texture::regenerateMipMapLevels(void* data, u32 layer)
|
|||
dataSize = IImage::getDataSizeFromFormat(ColorFormat, width, height);
|
||||
++level;
|
||||
|
||||
uploadTexture(layer, level, tmpData);
|
||||
uploadTexture(tmpData, level, layer);
|
||||
|
||||
tmpData += dataSize;
|
||||
} while (width != 1 || height != 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Texture)
|
||||
Texture->GenerateMipSubLevels();
|
||||
else if (CubeTexture)
|
||||
CubeTexture->GenerateMipSubLevels();
|
||||
createManualMipMaps(1);
|
||||
}
|
||||
}
|
||||
|
||||
void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height,
|
||||
s32 pitchsrc, s32 pitchtgt) const
|
||||
{
|
||||
for (s32 y=0; y<height; ++y)
|
||||
{
|
||||
for (s32 x=0; x<width; ++x)
|
||||
{
|
||||
u32 a=0, r=0, g=0, b=0;
|
||||
|
||||
for (s32 dy=0; dy<2; ++dy)
|
||||
{
|
||||
const s32 tgy = (y*2)+dy;
|
||||
for (s32 dx=0; dx<2; ++dx)
|
||||
{
|
||||
const s32 tgx = (x*2)+dx;
|
||||
|
||||
SColor c;
|
||||
if (ColorFormat == ECF_A1R5G5B5)
|
||||
c = A1R5G5B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
|
||||
else
|
||||
c = R5G6B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
|
||||
|
||||
a += c.getAlpha();
|
||||
r += c.getRed();
|
||||
g += c.getGreen();
|
||||
b += c.getBlue();
|
||||
}
|
||||
}
|
||||
|
||||
a /= 4;
|
||||
r /= 4;
|
||||
g /= 4;
|
||||
b /= 4;
|
||||
|
||||
u16 c;
|
||||
if (ColorFormat == ECF_A1R5G5B5)
|
||||
c = RGBA16(r,g,b,a);
|
||||
else
|
||||
c = A8R8G8B8toR5G6B5(SColor(a,r,g,b).color);
|
||||
*(u16*)(&tgt[(x*2)+(y*pitchtgt)]) = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height,
|
||||
s32 pitchsrc, s32 pitchtgt) const
|
||||
{
|
||||
for (s32 y=0; y<height; ++y)
|
||||
{
|
||||
for (s32 x=0; x<width; ++x)
|
||||
{
|
||||
u32 a=0, r=0, g=0, b=0;
|
||||
SColor c;
|
||||
|
||||
for (s32 dy=0; dy<2; ++dy)
|
||||
{
|
||||
const s32 tgy = (y*2)+dy;
|
||||
for (s32 dx=0; dx<2; ++dx)
|
||||
{
|
||||
const s32 tgx = (x*2)+dx;
|
||||
|
||||
c = *(u32*)(&src[(tgx*4)+(tgy*pitchsrc)]);
|
||||
|
||||
a += c.getAlpha();
|
||||
r += c.getRed();
|
||||
g += c.getGreen();
|
||||
b += c.getBlue();
|
||||
}
|
||||
}
|
||||
|
||||
a /= 4;
|
||||
r /= 4;
|
||||
g /= 4;
|
||||
b /= 4;
|
||||
|
||||
c.set(a, r, g, b);
|
||||
*(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CD3D9Texture::createManualMipMaps(u32 level)
|
||||
{
|
||||
if (level==0)
|
||||
return true;
|
||||
|
||||
if (!Texture) //Manual mips for CubeTexture not supported yet
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// manual mipmap generation
|
||||
IDirect3DSurface9* upperSurface = 0;
|
||||
IDirect3DSurface9* lowerSurface = 0;
|
||||
|
||||
// get upper level
|
||||
HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface);
|
||||
if (FAILED(hr) || !upperSurface)
|
||||
{
|
||||
os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
// get lower level
|
||||
hr = Texture->GetSurfaceLevel(level, &lowerSurface);
|
||||
if (FAILED(hr) || !lowerSurface)
|
||||
{
|
||||
os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING);
|
||||
upperSurface->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DSURFACE_DESC upperDesc, lowerDesc;
|
||||
upperSurface->GetDesc(&upperDesc);
|
||||
lowerSurface->GetDesc(&lowerDesc);
|
||||
|
||||
D3DLOCKED_RECT upperlr;
|
||||
D3DLOCKED_RECT lowerlr;
|
||||
|
||||
// lock upper surface
|
||||
if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0)))
|
||||
{
|
||||
upperSurface->Release();
|
||||
lowerSurface->Release();
|
||||
os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
// lock lower surface
|
||||
if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0)))
|
||||
{
|
||||
upperSurface->UnlockRect();
|
||||
upperSurface->Release();
|
||||
lowerSurface->Release();
|
||||
os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (upperDesc.Format != lowerDesc.Format)
|
||||
{
|
||||
os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((upperDesc.Format == D3DFMT_A1R5G5B5) || (upperDesc.Format == D3DFMT_R5G6B5))
|
||||
copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
|
||||
lowerDesc.Width, lowerDesc.Height,
|
||||
upperlr.Pitch, lowerlr.Pitch);
|
||||
else
|
||||
if (upperDesc.Format == D3DFMT_A8R8G8B8)
|
||||
copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
|
||||
lowerDesc.Width, lowerDesc.Height,
|
||||
upperlr.Pitch, lowerlr.Pitch);
|
||||
else
|
||||
os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING);
|
||||
}
|
||||
|
||||
bool result=true;
|
||||
// unlock
|
||||
if (FAILED(upperSurface->UnlockRect()))
|
||||
result=false;
|
||||
if (FAILED(lowerSurface->UnlockRect()))
|
||||
result=false;
|
||||
|
||||
// release
|
||||
upperSurface->Release();
|
||||
lowerSurface->Release();
|
||||
|
||||
if (!result || (upperDesc.Width <= 3 && upperDesc.Height <= 3))
|
||||
return result; // stop generating levels
|
||||
|
||||
// generate next level
|
||||
return createManualMipMaps(level+1);
|
||||
}
|
||||
|
||||
|
||||
IDirect3DBaseTexture9* CD3D9Texture::getDX9BaseTexture() const
|
||||
{
|
||||
return (Texture) ? static_cast<IDirect3DBaseTexture9*>(Texture) : static_cast<IDirect3DBaseTexture9*>(CubeTexture);
|
||||
|
@ -489,7 +672,7 @@ void CD3D9Texture::getImageValues(const IImage* image)
|
|||
|
||||
if (IImage::isCompressedFormat(image->getColorFormat()))
|
||||
{
|
||||
AutoGenerateMipMaps = false;
|
||||
HardwareMipMaps = false;
|
||||
}
|
||||
|
||||
OriginalSize = image->getDimension();
|
||||
|
@ -521,13 +704,13 @@ void CD3D9Texture::getImageValues(const IImage* image)
|
|||
Pitch = Size.Width * IImage::getBitsPerPixelFromFormat(ColorFormat) / 8;
|
||||
}
|
||||
|
||||
void CD3D9Texture::uploadTexture(u32 layer, u32 level, void* data)
|
||||
void CD3D9Texture::uploadTexture(void* data, u32 mipmapLevel, u32 layer)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
u32 width = Size.Width >> level;
|
||||
u32 height = Size.Height >> level;
|
||||
u32 width = Size.Width >> mipmapLevel;
|
||||
u32 height = Size.Height >> mipmapLevel;
|
||||
|
||||
u32 dataSize = IImage::getDataSizeFromFormat(ColorFormat, width, height);
|
||||
|
||||
|
@ -537,13 +720,13 @@ void CD3D9Texture::uploadTexture(u32 layer, u32 level, void* data)
|
|||
|
||||
if (Texture)
|
||||
{
|
||||
hr = Texture->LockRect(level, &lockRectangle, 0, 0);
|
||||
hr = Texture->LockRect(mipmapLevel, &lockRectangle, 0, 0);
|
||||
}
|
||||
else if (CubeTexture)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(layer > 5)
|
||||
|
||||
hr = CubeTexture->LockRect(static_cast<_D3DCUBEMAP_FACES>(layer), level, &lockRectangle, 0, 0);
|
||||
hr = CubeTexture->LockRect(static_cast<_D3DCUBEMAP_FACES>(layer), mipmapLevel, &lockRectangle, 0, 0);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
|
@ -556,11 +739,11 @@ void CD3D9Texture::uploadTexture(u32 layer, u32 level, void* data)
|
|||
|
||||
if (Texture)
|
||||
{
|
||||
hr = Texture->UnlockRect(level);
|
||||
hr = Texture->UnlockRect(mipmapLevel);
|
||||
}
|
||||
else if (CubeTexture)
|
||||
{
|
||||
hr = CubeTexture->UnlockRect(static_cast<_D3DCUBEMAP_FACES>(layer), level);
|
||||
hr = CubeTexture->UnlockRect(static_cast<_D3DCUBEMAP_FACES>(layer), mipmapLevel);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
|
|
|
@ -53,7 +53,19 @@ private:
|
|||
|
||||
void getImageValues(const IImage* image);
|
||||
|
||||
void uploadTexture(u32 layer, u32 level, void* data);
|
||||
void uploadTexture(void* data, u32 mipmapLevel, u32 layer);
|
||||
|
||||
//! Helper function for mipmap generation.
|
||||
bool createManualMipMaps(u32 level);
|
||||
|
||||
//! Helper function for mipmap generation.
|
||||
void copy16BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
|
||||
|
||||
//! Helper function for mipmap generation.
|
||||
void copy32BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
|
||||
|
||||
|
||||
CD3D9Driver* Driver;
|
||||
|
||||
|
@ -62,8 +74,9 @@ private:
|
|||
bool LockReadOnly;
|
||||
void* LockData;
|
||||
u32 LockLayer;
|
||||
u32 MipLevelLocked;
|
||||
|
||||
bool AutoGenerateMipMaps;
|
||||
bool HardwareMipMaps;
|
||||
|
||||
IDirect3DDevice9* Device;
|
||||
IDirect3DTexture9* Texture;
|
||||
|
|
|
@ -1122,7 +1122,8 @@ bool CIrrDeviceSDL::isWindowActive() const
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
return (SDL_GetAppState()&SDL_APPACTIVE) ? true : false;
|
||||
const Uint8 appState = SDL_GetAppState();
|
||||
return (appState&SDL_APPACTIVE && appState&SDL_APPINPUTFOCUS) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre
|
|||
|
||||
setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
|
||||
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true);
|
||||
setTextureCreationFlag(ETCF_AUTO_GENERATE_MIP_MAPS, true);
|
||||
setTextureCreationFlag(ETCF_ALLOW_MEMORY_COPY, true);
|
||||
|
||||
ViewPort = core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(screenSize));
|
||||
|
|
|
@ -58,23 +58,18 @@ public:
|
|||
DepthStencil->drop();
|
||||
}
|
||||
|
||||
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_
|
||||
virtual void setTexture(const core::array<ITexture*>& textures, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_
|
||||
{
|
||||
bool needSizeUpdate = false;
|
||||
|
||||
// Set color attachments.
|
||||
if ((Texture != texture) || (CubeSurfaces != cubeSurfaces))
|
||||
if ((Texture != textures) || (CubeSurfaces != cubeSurfaces))
|
||||
{
|
||||
needSizeUpdate = true;
|
||||
CubeSurfaces = cubeSurfaces;
|
||||
|
||||
for (u32 i = 0; i < Texture.size(); ++i)
|
||||
{
|
||||
if (Texture[i])
|
||||
Texture[i]->drop();
|
||||
}
|
||||
core::array<ITexture*> prevTextures(Texture);
|
||||
|
||||
if (texture.size() > static_cast<u32>(ColorAttachment))
|
||||
if (textures.size() > static_cast<u32>(ColorAttachment))
|
||||
{
|
||||
core::stringc message = "This GPU supports up to ";
|
||||
message += static_cast<u32>(ColorAttachment);
|
||||
|
@ -83,11 +78,11 @@ public:
|
|||
os::Printer::log(message.c_str(), ELL_WARNING);
|
||||
}
|
||||
|
||||
Texture.set_used(core::min_(texture.size(), static_cast<u32>(ColorAttachment)));
|
||||
Texture.set_used(core::min_(textures.size(), static_cast<u32>(ColorAttachment)));
|
||||
|
||||
for (u32 i = 0; i < Texture.size(); ++i)
|
||||
{
|
||||
TOpenGLTexture* currentTexture = (texture[i] && texture[i]->getDriverType() == DriverType) ? static_cast<TOpenGLTexture*>(texture[i]) : 0;
|
||||
TOpenGLTexture* currentTexture = (textures[i] && textures[i]->getDriverType() == DriverType) ? static_cast<TOpenGLTexture*>(textures[i]) : 0;
|
||||
|
||||
GLuint textureID = 0;
|
||||
|
||||
|
@ -98,7 +93,7 @@ public:
|
|||
|
||||
if (textureID != 0)
|
||||
{
|
||||
Texture[i] = texture[i];
|
||||
Texture[i] = textures[i];
|
||||
Texture[i]->grab();
|
||||
}
|
||||
else
|
||||
|
@ -107,6 +102,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < prevTextures.size(); ++i)
|
||||
{
|
||||
if (prevTextures[i])
|
||||
prevTextures[i]->drop();
|
||||
}
|
||||
|
||||
RequestTextureUpdate = true;
|
||||
}
|
||||
|
||||
if (CubeSurfaces != cubeSurfaces)
|
||||
{
|
||||
CubeSurfaces = cubeSurfaces;
|
||||
RequestTextureUpdate = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
#include "CImage.h"
|
||||
#include "CColorConverter.h"
|
||||
|
||||
// Check if GL version we compile with should have the glGenerateMipmap function.
|
||||
#if defined(GL_VERSION_3_0) || defined(GL_ES_VERSION_2_0)
|
||||
#define IRR_OPENGL_HAS_glGenerateMipmap
|
||||
#endif
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace video
|
||||
|
@ -45,37 +50,49 @@ public:
|
|||
bool IsCached;
|
||||
};
|
||||
|
||||
COpenGLCoreTexture(const io::path& name, const core::array<IImage*>& image, E_TEXTURE_TYPE type, TOpenGLDriver* driver) : ITexture(name, type), Driver(driver), TextureType(GL_TEXTURE_2D),
|
||||
COpenGLCoreTexture(const io::path& name, const core::array<IImage*>& images, E_TEXTURE_TYPE type, TOpenGLDriver* driver) : ITexture(name, type), Driver(driver), TextureType(GL_TEXTURE_2D),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0),
|
||||
KeepImage(false), AutoGenerateMipMaps(false)
|
||||
KeepImage(false), MipLevelStored(0), LegacyAutoGenerateMipMaps(false)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(image.size() == 0)
|
||||
_IRR_DEBUG_BREAK_IF(images.size() == 0)
|
||||
|
||||
DriverType = Driver->getDriverType();
|
||||
TextureType = TextureTypeIrrToGL(Type);
|
||||
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
|
||||
AutoGenerateMipMaps = Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE);
|
||||
KeepImage = Driver->getTextureCreationFlag(ETCF_ALLOW_MEMORY_COPY);
|
||||
|
||||
getImageValues(image[0]);
|
||||
getImageValues(images[0]);
|
||||
|
||||
const core::array<IImage*>* tmpImage = ℑ
|
||||
const core::array<IImage*>* tmpImages = &images;
|
||||
|
||||
if (KeepImage || OriginalSize != Size || OriginalColorFormat != ColorFormat)
|
||||
{
|
||||
Image.set_used(image.size());
|
||||
Images.set_used(images.size());
|
||||
|
||||
for (u32 i = 0; i < image.size(); ++i)
|
||||
for (u32 i = 0; i < images.size(); ++i)
|
||||
{
|
||||
Image[i] = Driver->createImage(ColorFormat, Size);
|
||||
Images[i] = Driver->createImage(ColorFormat, Size);
|
||||
|
||||
if (image[i]->getDimension() == Size)
|
||||
image[i]->copyTo(Image[i]);
|
||||
if (images[i]->getDimension() == Size)
|
||||
images[i]->copyTo(Images[i]);
|
||||
else
|
||||
image[i]->copyToScaling(Image[i]);
|
||||
images[i]->copyToScaling(Images[i]);
|
||||
|
||||
if ( images[i]->getMipMapsData() )
|
||||
{
|
||||
if ( OriginalSize == Size && OriginalColorFormat == ColorFormat )
|
||||
{
|
||||
Images[i]->setMipMapsData( images[i]->getMipMapsData(), false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: handle at least mipmap with changing color format
|
||||
os::Printer::log("COpenGLCoreTexture: Can't handle format changes for mipmap data. Mipmap data dropped", ELL_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tmpImage = &Image;
|
||||
tmpImages = &Images;
|
||||
}
|
||||
|
||||
glGenTextures(1, &TextureName);
|
||||
|
@ -86,7 +103,8 @@ public:
|
|||
glTexParameteri(TextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(TextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
if (HasMipMaps && AutoGenerateMipMaps)
|
||||
#ifdef GL_GENERATE_MIPMAP_HINT
|
||||
if (HasMipMaps)
|
||||
{
|
||||
if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
|
||||
|
@ -95,34 +113,36 @@ public:
|
|||
else
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
|
||||
}
|
||||
|
||||
#if (defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20) || (defined(IRR_OPENGL_ES_VERSION) && IRR_OPENGL_ES_VERSION < 20)
|
||||
if (HasMipMaps)
|
||||
glTexParameteri(TextureType, GL_GENERATE_MIPMAP, (AutoGenerateMipMaps) ? GL_TRUE : GL_FALSE);
|
||||
#endif
|
||||
|
||||
for (u32 i = 0; i < (*tmpImage).size(); ++i)
|
||||
uploadTexture(true, i, 0, (*tmpImage)[i]->getData());
|
||||
|
||||
bool autoGenerateRequired = true;
|
||||
|
||||
for (u32 i = 0; i < (*tmpImage).size(); ++i)
|
||||
#if !defined(IRR_OPENGL_HAS_glGenerateMipmap) && defined(GL_GENERATE_MIPMAP)
|
||||
if (HasMipMaps)
|
||||
{
|
||||
void* mipmapsData = (*tmpImage)[i]->getMipMapsData();
|
||||
LegacyAutoGenerateMipMaps = Driver->getTextureCreationFlag(ETCF_AUTO_GENERATE_MIP_MAPS) &&
|
||||
Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE);
|
||||
glTexParameteri(TextureType, GL_GENERATE_MIPMAP, LegacyAutoGenerateMipMaps ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (autoGenerateRequired || mipmapsData)
|
||||
for (u32 i = 0; i < (*tmpImages).size(); ++i)
|
||||
uploadTexture(true, i, 0, (*tmpImages)[i]->getData());
|
||||
|
||||
if (HasMipMaps && !LegacyAutoGenerateMipMaps)
|
||||
{
|
||||
// Create mipmaps (either from image mipmaps or generate them)
|
||||
for (u32 i = 0; i < (*tmpImages).size(); ++i)
|
||||
{
|
||||
void* mipmapsData = (*tmpImages)[i]->getMipMapsData();
|
||||
regenerateMipMapLevels(mipmapsData, i);
|
||||
|
||||
if (!mipmapsData)
|
||||
autoGenerateRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!KeepImage)
|
||||
{
|
||||
for (u32 i = 0; i < Image.size(); ++i)
|
||||
Image[i]->drop();
|
||||
for (u32 i = 0; i < Images.size(); ++i)
|
||||
Images[i]->drop();
|
||||
|
||||
Image.clear();
|
||||
Images.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -135,7 +155,7 @@ public:
|
|||
: ITexture(name, type),
|
||||
Driver(driver), TextureType(GL_TEXTURE_2D),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0), KeepImage(false),
|
||||
AutoGenerateMipMaps(false)
|
||||
MipLevelStored(0), LegacyAutoGenerateMipMaps(false)
|
||||
{
|
||||
DriverType = Driver->getDriverType();
|
||||
TextureType = TextureTypeIrrToGL(Type);
|
||||
|
@ -210,31 +230,39 @@ public:
|
|||
if (LockImage)
|
||||
LockImage->drop();
|
||||
|
||||
for (u32 i = 0; i < Image.size(); ++i)
|
||||
Image[i]->drop();
|
||||
for (u32 i = 0; i < Images.size(); ++i)
|
||||
Images[i]->drop();
|
||||
}
|
||||
|
||||
virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel=0, u32 layer = 0, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_
|
||||
{
|
||||
if (LockImage)
|
||||
return LockImage->getData();
|
||||
return getLockImageData(MipLevelStored);
|
||||
|
||||
if (IImage::isCompressedFormat(ColorFormat))
|
||||
return 0;
|
||||
|
||||
LockReadOnly |= (mode == ETLM_READ_ONLY);
|
||||
LockLayer = layer;
|
||||
MipLevelStored = mipmapLevel;
|
||||
|
||||
if (KeepImage)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(LockLayer > Image.size())
|
||||
_IRR_DEBUG_BREAK_IF(LockLayer > Images.size())
|
||||
|
||||
LockImage = Image[LockLayer];
|
||||
if ( mipmapLevel == 0 || (Images[LockLayer] && Images[LockLayer]->getMipMapsData(mipmapLevel)) )
|
||||
{
|
||||
LockImage = Images[LockLayer];
|
||||
LockImage->grab();
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
if ( !LockImage )
|
||||
{
|
||||
LockImage = Driver->createImage(ColorFormat, Size);
|
||||
core::dimension2d<u32> lockImageSize( IImage::getMipMapsSize(Size, MipLevelStored));
|
||||
|
||||
// note: we save mipmap data also in the image because IImage doesn't allow saving single mipmap levels to the mipmap data
|
||||
LockImage = Driver->createImage(ColorFormat, lockImageSize);
|
||||
|
||||
if (LockImage && mode != ETLM_WRITE_ONLY)
|
||||
{
|
||||
|
@ -244,6 +272,7 @@ public:
|
|||
IImage* tmpImage = LockImage; // not sure yet if the size required by glGetTexImage is always correct, if not we might have to allocate a different tmpImage and convert colors later on.
|
||||
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, this);
|
||||
Driver->testGLError(__LINE__);
|
||||
|
||||
GLenum tmpTextureType = TextureType;
|
||||
|
||||
|
@ -254,7 +283,8 @@ public:
|
|||
tmpTextureType = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
|
||||
}
|
||||
|
||||
glGetTexImage(tmpTextureType, 0, PixelFormat, PixelType, tmpImage->getData());
|
||||
glGetTexImage(tmpTextureType, MipLevelStored, PixelFormat, PixelType, tmpImage->getData());
|
||||
Driver->testGLError(__LINE__);
|
||||
|
||||
if (IsRenderTarget && lockFlags == ETLF_FLIP_Y_UP_RTT)
|
||||
{
|
||||
|
@ -339,11 +369,11 @@ public:
|
|||
LockImage = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Driver->testGLError(__LINE__);
|
||||
}
|
||||
|
||||
return (LockImage) ? LockImage->getData() : 0;
|
||||
return (LockImage) ? getLockImageData(MipLevelStored) : 0;
|
||||
}
|
||||
|
||||
virtual void unlock() _IRR_OVERRIDE_
|
||||
|
@ -356,11 +386,9 @@ public:
|
|||
const COpenGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, this);
|
||||
|
||||
uploadTexture(false, LockLayer, 0, LockImage->getData());
|
||||
uploadTexture(false, LockLayer, MipLevelStored, getLockImageData(MipLevelStored));
|
||||
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
|
||||
|
||||
regenerateMipMapLevels(0, LockLayer);
|
||||
}
|
||||
|
||||
LockImage->drop();
|
||||
|
@ -372,7 +400,7 @@ public:
|
|||
|
||||
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_
|
||||
{
|
||||
if (!HasMipMaps || (!data && !AutoGenerateMipMaps) || (Size.Width <= 1 && Size.Height <= 1))
|
||||
if (!HasMipMaps || LegacyAutoGenerateMipMaps || (Size.Width <= 1 && Size.Height <= 1))
|
||||
return;
|
||||
|
||||
const COpenGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
|
||||
|
@ -405,7 +433,8 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
#if (defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION >= 20) || (defined(IRR_OPENGL_ES_VERSION) && IRR_OPENGL_ES_VERSION >= 20)
|
||||
#ifdef IRR_OPENGL_HAS_glGenerateMipmap
|
||||
glEnable(GL_TEXTURE_2D); // Hack some ATI cards need this glEnable according to https://www.khronos.org/opengl/wiki/Common_Mistakes
|
||||
Driver->irrGlGenerateMipmap(TextureType);
|
||||
#endif
|
||||
}
|
||||
|
@ -429,6 +458,17 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
void * getLockImageData(irr::u32 miplevel) const
|
||||
{
|
||||
if ( KeepImage && MipLevelStored > 0
|
||||
&& LockImage->getMipMapsData(MipLevelStored) )
|
||||
{
|
||||
return LockImage->getMipMapsData(MipLevelStored);
|
||||
}
|
||||
return LockImage->getData();
|
||||
}
|
||||
|
||||
ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format)
|
||||
{
|
||||
// We only try for to adapt "simple" formats
|
||||
|
@ -489,7 +529,6 @@ protected:
|
|||
if (IImage::isCompressedFormat(image->getColorFormat()))
|
||||
{
|
||||
KeepImage = false;
|
||||
AutoGenerateMipMaps = false;
|
||||
}
|
||||
|
||||
OriginalSize = image->getDimension();
|
||||
|
@ -561,7 +600,7 @@ protected:
|
|||
glTexImage2D(tmpTextureType, level, InternalFormat, width, height, 0, PixelFormat, PixelType, tmpData);
|
||||
else
|
||||
glTexSubImage2D(tmpTextureType, level, 0, 0, width, height, PixelFormat, PixelType, tmpData);
|
||||
|
||||
Driver->testGLError(__LINE__);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -581,7 +620,7 @@ protected:
|
|||
Driver->irrGlCompressedTexImage2D(tmpTextureType, level, InternalFormat, width, height, 0, dataSize, data);
|
||||
else
|
||||
Driver->irrGlCompressedTexSubImage2D(tmpTextureType, level, 0, 0, width, height, PixelFormat, dataSize, data);
|
||||
|
||||
Driver->testGLError(__LINE__);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -617,9 +656,10 @@ protected:
|
|||
u32 LockLayer;
|
||||
|
||||
bool KeepImage;
|
||||
core::array<IImage*> Image;
|
||||
core::array<IImage*> Images;
|
||||
|
||||
bool AutoGenerateMipMaps;
|
||||
u8 MipLevelStored;
|
||||
bool LegacyAutoGenerateMipMaps;
|
||||
|
||||
mutable SStatesCache StatesCache;
|
||||
};
|
||||
|
|
|
@ -133,8 +133,7 @@ void CSoftwareRenderTarget::setTexture(const core::array<ITexture*>& texture, IT
|
|||
{
|
||||
if (Texture != texture)
|
||||
{
|
||||
if (Texture[0])
|
||||
Texture[0]->drop();
|
||||
ITexture* prevTexture = Texture[0];
|
||||
|
||||
bool textureDetected = false;
|
||||
|
||||
|
@ -150,6 +149,9 @@ void CSoftwareRenderTarget::setTexture(const core::array<ITexture*>& texture, IT
|
|||
}
|
||||
}
|
||||
|
||||
if (prevTexture)
|
||||
prevTexture->drop();
|
||||
|
||||
if (!textureDetected)
|
||||
Texture[0] = 0;
|
||||
}
|
||||
|
|
|
@ -185,8 +185,7 @@ void CSoftwareRenderTarget2::setTexture(const core::array<ITexture*>& texture, I
|
|||
{
|
||||
if (Texture != texture)
|
||||
{
|
||||
if (Texture[0])
|
||||
Texture[0]->drop();
|
||||
ITexture* prevTexture = Texture[0];
|
||||
|
||||
bool textureDetected = false;
|
||||
|
||||
|
@ -202,6 +201,9 @@ void CSoftwareRenderTarget2::setTexture(const core::array<ITexture*>& texture, I
|
|||
}
|
||||
}
|
||||
|
||||
if (prevTexture)
|
||||
prevTexture->drop();
|
||||
|
||||
if (!textureDetected)
|
||||
Texture[0] = 0;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ bool testWithDriver(video::E_DRIVER_TYPE driverType)
|
|||
// we use character enumeration as we have more than 9 types
|
||||
name.append(Type-scene::EPT_POINTS+'a');
|
||||
name.append(".png");
|
||||
result &= takeScreenshotAndCompareAgainstReference(driver, name.c_str(), 97.f);
|
||||
result &= takeScreenshotAndCompareAgainstReference(driver, name.c_str(), 99.5f);
|
||||
}
|
||||
|
||||
device->closeDevice();
|
||||
|
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
|
@ -1,4 +1,4 @@
|
|||
Tests finished. 1 test of 1 passed.
|
||||
Tests finished. 70 tests of 70 passed.
|
||||
Compiled as DEBUG
|
||||
Test suite pass at GMT Thu May 30 10:19:28 2019
|
||||
Test suite pass at GMT Tue Nov 12 17:06:08 2019
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ using namespace core;
|
|||
|
||||
namespace
|
||||
{
|
||||
|
||||
//! check miplevels by visual test
|
||||
bool renderMipLevels(video::E_DRIVER_TYPE driverType)
|
||||
{
|
||||
|
@ -26,6 +25,9 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Can't pass manual data with hardware mip maps (at least on d3d, not sure about older GL)
|
||||
driver->setTextureCreationFlag(video::ETCF_AUTO_GENERATE_MIP_MAPS, false);
|
||||
|
||||
stabilizeScreenBackground(driver);
|
||||
|
||||
logTestString("Testing driver %ls\n", driver->getName());
|
||||
|
@ -75,7 +77,7 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType)
|
|||
smgr->drawAll();
|
||||
driver->endScene();
|
||||
|
||||
bool result = takeScreenshotAndCompareAgainstReference(driver, "-renderMipmap.png");
|
||||
bool result = takeScreenshotAndCompareAgainstReference(driver, "-renderMipmap.png", 99.5);
|
||||
|
||||
if (!result)
|
||||
logTestString("mipmap render failed.\n", driver->getName());
|
||||
|
@ -89,8 +91,232 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType)
|
|||
return result;
|
||||
}
|
||||
|
||||
//! Tests locking miplevels
|
||||
bool lockAllMipLevels(video::E_DRIVER_TYPE driverType)
|
||||
{
|
||||
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
|
||||
if (!device)
|
||||
return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
|
||||
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
scene::ISceneManager * smgr = device->getSceneManager();
|
||||
|
||||
if (!driver->queryFeature(video::EVDF_MIP_MAP))
|
||||
{
|
||||
device->closeDevice();
|
||||
device->run();
|
||||
device->drop();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can't lock surfaces for hardware mip-maps
|
||||
driver->setTextureCreationFlag(video::ETCF_AUTO_GENERATE_MIP_MAPS, false);
|
||||
|
||||
stabilizeScreenBackground(driver);
|
||||
|
||||
logTestString("Testing driver %ls\n", driver->getName());
|
||||
|
||||
scene::ISceneNode* n = smgr->addCubeSceneNode();
|
||||
|
||||
if (n)
|
||||
{
|
||||
// create the texture and miplevels with distinct colors
|
||||
u32 texData[16*16];
|
||||
for (u32 i=0; i<16*16; ++i)
|
||||
texData[i]=0xff0000ff-i;
|
||||
video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false);
|
||||
u32 mipdata[8*16];
|
||||
u32 index=0;
|
||||
for (u32 j=8; j>0; j/=2)
|
||||
{
|
||||
u32 val=(j==8?0x00ff00ff:(j==4?0x0000ffff:(j==2?0xc2c200ff:0x001212ff)));
|
||||
for (u32 i=0; i<j; ++i)
|
||||
{
|
||||
for (u32 k=0; k<j; ++k)
|
||||
mipdata[index++]=val-i;
|
||||
}
|
||||
}
|
||||
|
||||
video::ITexture* tex = driver->addTexture("miptest", image, mipdata);
|
||||
if (!tex)
|
||||
// is probably an error in the mipdata handling
|
||||
return false;
|
||||
else
|
||||
n->setMaterialTexture(0, tex);
|
||||
image->drop();
|
||||
}
|
||||
|
||||
smgr->addCameraSceneNode();
|
||||
|
||||
driver->beginScene(true, true, video::SColor(255,100,101,140));
|
||||
smgr->drawAll();
|
||||
driver->endScene();
|
||||
|
||||
video::ITexture* tex = driver->findTexture("miptest");
|
||||
video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
|
||||
bool result = bits && (bits[0].color==0xff0000ff);
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 1);
|
||||
result &= bits && (bits[0].color==0x00ff00ff);
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 2);
|
||||
result &= bits && (bits[0].color==0x0000ffff);
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
|
||||
result &= bits && (bits[0].color==0xc2c200ff);
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 4);
|
||||
result &= bits && (bits[0].color==0x001212ff);
|
||||
tex->unlock();
|
||||
|
||||
if (!result)
|
||||
logTestString("mipmap lock after init with driver %ls failed.\n", driver->getName());
|
||||
|
||||
// test with updating a lower level, and reading upper and lower
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 3);
|
||||
if ( bits )
|
||||
{
|
||||
bits[0]=0xff00ff00;
|
||||
bits[1]=0xff00ff00;
|
||||
}
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
|
||||
result &= bits && (bits[0].color==0x001212ff);
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
|
||||
result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color==0xc2c200fe));
|
||||
tex->unlock();
|
||||
|
||||
if (!result)
|
||||
logTestString("mipmap lock after mipmap write with driver %ls failed.\n", driver->getName());
|
||||
|
||||
// now test locking level 0
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0);
|
||||
if ( bits )
|
||||
{
|
||||
bits[0]=0xff00ff00;
|
||||
bits[1]=0xff00ff00;
|
||||
}
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
|
||||
result &= bits && (bits[0].color==0x001212ff);
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
|
||||
result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color==0xff0000fd));
|
||||
tex->unlock();
|
||||
|
||||
if (!result)
|
||||
logTestString("mipmap lock at level 0 after mipmap write with driver %ls failed.\n", driver->getName());
|
||||
else
|
||||
logTestString("Passed\n");
|
||||
|
||||
device->closeDevice();
|
||||
device->run();
|
||||
device->drop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//! Tests locking miplevels after texture was created with auto mipmap update
|
||||
bool lockWithAutoMipmap(video::E_DRIVER_TYPE driverType)
|
||||
{
|
||||
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
|
||||
if (!device)
|
||||
return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
|
||||
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
scene::ISceneManager * smgr = device->getSceneManager();
|
||||
|
||||
if (!driver->queryFeature(video::EVDF_MIP_MAP))
|
||||
{
|
||||
device->closeDevice();
|
||||
device->run();
|
||||
device->drop();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can't lock surfaces for hardware mip-maps (sadly... so also can't test if it works like this)
|
||||
driver->setTextureCreationFlag(video::ETCF_AUTO_GENERATE_MIP_MAPS, false);
|
||||
|
||||
stabilizeScreenBackground(driver);
|
||||
|
||||
logTestString("Testing driver %ls\n", driver->getName());
|
||||
|
||||
scene::ISceneNode* n = smgr->addCubeSceneNode();
|
||||
|
||||
if (n)
|
||||
{
|
||||
// create the texture
|
||||
u32 texData[16*16];
|
||||
for (u32 i=0; i<16*16; ++i)
|
||||
texData[i]=0xff0000ff-i;
|
||||
video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false);
|
||||
|
||||
video::ITexture* tex = driver->addTexture("miptest", image);
|
||||
if (!tex)
|
||||
return false;
|
||||
else
|
||||
n->setMaterialTexture(0, tex);
|
||||
image->drop();
|
||||
}
|
||||
(void)smgr->addCameraSceneNode();
|
||||
|
||||
driver->beginScene(true, true, video::SColor(255,100,101,140));
|
||||
smgr->drawAll();
|
||||
driver->endScene();
|
||||
|
||||
video::ITexture* tex = driver->findTexture("miptest");
|
||||
video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
|
||||
bool result = bits && (bits[0].color==0xff0000ff);
|
||||
tex->unlock();
|
||||
if (!result)
|
||||
logTestString("mipmap lock after init with driver %ls failed.\n", driver->getName());
|
||||
|
||||
// test with updating a lower level, and reading upper and lower
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 3);
|
||||
if ( bits )
|
||||
{
|
||||
bits[0]=0xff00ff00;
|
||||
bits[1]=0xff00ff00;
|
||||
}
|
||||
tex->unlock();
|
||||
// lock another texture just to invalidate caches in the driver
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
|
||||
result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color!=0xff00ff00));
|
||||
tex->unlock();
|
||||
|
||||
if (!result)
|
||||
logTestString("mipmap lock after mipmap write with driver %ls failed.\n", driver->getName());
|
||||
|
||||
// now test locking level 0
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0);
|
||||
if ( bits )
|
||||
{
|
||||
bits[0]=0x00ff00ff;
|
||||
bits[1]=0x00ff00ff;
|
||||
}
|
||||
tex->unlock();
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
|
||||
result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color!=0xff00ff00));
|
||||
tex->unlock();
|
||||
|
||||
if (!result)
|
||||
logTestString("mipmap lock at level 0 after mipmap write with driver %ls failed.\n", driver->getName());
|
||||
else
|
||||
logTestString("Passed\n");
|
||||
|
||||
device->closeDevice();
|
||||
device->run();
|
||||
device->drop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Tests locking
|
||||
bool lockTexture(video::E_DRIVER_TYPE driverType)
|
||||
bool lockCubemapTexture(video::E_DRIVER_TYPE driverType)
|
||||
{
|
||||
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
|
||||
if (!device)
|
||||
|
@ -177,7 +403,12 @@ bool lockTexture(video::E_DRIVER_TYPE driverType)
|
|||
|
||||
for (u32 i = 0; i < 6; ++i)
|
||||
{
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, i);
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0, i);
|
||||
if ( !bits)
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
bits[0] = 0xff00ff00;
|
||||
bits[1] = 0xff00ff00;
|
||||
tex->unlock();
|
||||
|
@ -185,7 +416,12 @@ bool lockTexture(video::E_DRIVER_TYPE driverType)
|
|||
|
||||
for (u32 i = 0; i < 6; ++i)
|
||||
{
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, i);
|
||||
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0, i);
|
||||
if ( !bits)
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
u32 b0 = bits[0].color;
|
||||
u32 b2 = bits[2].color;
|
||||
|
||||
|
@ -213,7 +449,9 @@ bool textureFeatures(void)
|
|||
bool result = true;
|
||||
|
||||
TestWithAllDrivers(renderMipLevels);
|
||||
TestWithAllDrivers(lockTexture);
|
||||
TestWithAllDrivers(lockAllMipLevels);
|
||||
TestWithAllDrivers(lockWithAutoMipmap);
|
||||
TestWithAllDrivers(lockCubemapTexture);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|