Commit 453d24cf authored by nadro's avatar nadro

- Added TextureWrapW field to SMaterialLayer.

- Improved IRenderTarget::setTexture warnings.
- Minor improvements for textures in D3D9 and OpenGL drivers.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5241 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 472a30e4
--------------------------
Changes in 1.9 (not yet released)
- Add SMaterialLayer::TextureWrapW for cubemap texture wrap mode at W axis.
- Add cubemap texture support for D3D9 and OpenGL drivers.
- Do no longer re-calculate md2 frames when they don't change (thx @npc for reporting)
- Add multibyteToWString wrapper functions around mbstowcs which work with Irrlicht string class.
- Fix: addFileArchive now grab()'s the archive when you pass one in by pointer.
......
......@@ -202,6 +202,7 @@ namespace video
case EMF_TEXTURE_WRAP:
material.TextureLayer[0].TextureWrapU = Material.TextureLayer[0].TextureWrapU;
material.TextureLayer[0].TextureWrapV = Material.TextureLayer[0].TextureWrapV;
material.TextureLayer[0].TextureWrapW = Material.TextureLayer[0].TextureWrapW;
break;
case EMF_ANTI_ALIASING: material.AntiAliasing = Material.AntiAliasing; break;
case EMF_COLOR_MASK: material.ColorMask = Material.ColorMask; break;
......
......@@ -595,6 +595,7 @@ namespace video
{
TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)value;
TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)value;
TextureLayer[i].TextureWrapW = (E_TEXTURE_CLAMP)value;
}
}
break;
......@@ -655,12 +656,7 @@ namespace video
case EMF_TEXTURE_WRAP:
return !(TextureLayer[0].TextureWrapU ||
TextureLayer[0].TextureWrapV ||
TextureLayer[1].TextureWrapU ||
TextureLayer[1].TextureWrapV ||
TextureLayer[2].TextureWrapU ||
TextureLayer[2].TextureWrapV ||
TextureLayer[3].TextureWrapU ||
TextureLayer[3].TextureWrapV);
TextureLayer[0].TextureWrapW);
case EMF_ANTI_ALIASING:
return (AntiAliasing==1);
case EMF_COLOR_MASK:
......
......@@ -49,16 +49,10 @@ namespace video
{
public:
//! Default constructor
SMaterialLayer()
: Texture(0),
TextureWrapU(ETC_REPEAT),
TextureWrapV(ETC_REPEAT),
BilinearFilter(true),
TrilinearFilter(false),
AnisotropicFilter(0),
LODBias(0),
TextureMatrix(0)
{}
SMaterialLayer() : Texture(0), TextureWrapU(ETC_REPEAT), TextureWrapV(ETC_REPEAT), TextureWrapW(ETC_REPEAT),
BilinearFilter(true), TrilinearFilter(false), AnisotropicFilter(0), LODBias(0), TextureMatrix(0)
{
}
//! Copy constructor
/** \param other Material layer to copy from. */
......@@ -109,6 +103,7 @@ namespace video
}
TextureWrapU = other.TextureWrapU;
TextureWrapV = other.TextureWrapV;
TextureWrapW = other.TextureWrapW;
BilinearFilter = other.BilinearFilter;
TrilinearFilter = other.TrilinearFilter;
AnisotropicFilter = other.AnisotropicFilter;
......@@ -161,6 +156,7 @@ namespace video
Texture != b.Texture ||
TextureWrapU != b.TextureWrapU ||
TextureWrapV != b.TextureWrapV ||
TextureWrapW != b.TextureWrapW ||
BilinearFilter != b.BilinearFilter ||
TrilinearFilter != b.TrilinearFilter ||
AnisotropicFilter != b.AnisotropicFilter ||
......@@ -187,6 +183,7 @@ namespace video
/** Values are taken from E_TEXTURE_CLAMP. */
u8 TextureWrapU:4;
u8 TextureWrapV:4;
u8 TextureWrapW:4;
//! Is bilinear filtering enabled? Default: true
bool BilinearFilter:1;
......
......@@ -1065,6 +1065,8 @@ void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const
material.Material.TextureLayer[i].TextureWrapU=video::ETC_CLAMP;
if (material.Textures[i]->Flags & 0x20) // Clamp V
material.Material.TextureLayer[i].TextureWrapV=video::ETC_CLAMP;
if (material.Textures[i]->Flags & 0x20) // Clamp R
material.Material.TextureLayer[i].TextureWrapW=video::ETC_CLAMP;
}
}
......
......@@ -108,6 +108,7 @@ namespace
const core::stringc dataName = "data";
const core::stringc wrapsName = "wrap_s";
const core::stringc wraptName = "wrap_t";
const core::stringc wraprName = "wrap_r";
const core::stringc minfilterName = "minfilter";
const core::stringc magfilterName = "magfilter";
const core::stringc mipfilterName = "mipfilter";
......@@ -1569,11 +1570,16 @@ void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect *
idx = effect->Parameters->findAttribute(wraptName.c_str());
if ( idx >= 0 )
twv = (video::E_TEXTURE_CLAMP)(effect->Parameters->getAttributeAsInt(idx));
video::E_TEXTURE_CLAMP twr = video::ETC_REPEAT;
idx = effect->Parameters->findAttribute(wraprName.c_str());
if ( idx >= 0 )
twr = (video::E_TEXTURE_CLAMP)(effect->Parameters->getAttributeAsInt(idx));
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
{
effect->Mat.TextureLayer[i].TextureWrapU = twu;
effect->Mat.TextureLayer[i].TextureWrapV = twv;
effect->Mat.TextureLayer[i].TextureWrapW = twr;
}
effect->Mat.setFlag(video::EMF_BILINEAR_FILTER, effect->Parameters->getAttributeAsBool("bilinear"));
......
......@@ -1381,6 +1381,12 @@ void CColladaMeshWriter::writeMaterialEffect(const irr::core::stringw& materialf
Writer->writeClosingTag(L"wrap_t");
Writer->writeLineBreak();
// <wrap_r>WRAP</wrap_r>
Writer->writeElement(L"wrap_r", false);
Writer->writeText(toString((video::E_TEXTURE_CLAMP)layer.TextureWrapW).c_str());
Writer->writeClosingTag(L"wrap_r");
Writer->writeLineBreak();
// <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>
Writer->writeElement(L"minfilter", false);
Writer->writeText(minTexfilterToString(layer.BilinearFilter, layer.TrilinearFilter).c_str());
......
......@@ -2303,9 +2303,18 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
// If separate UV not supported reuse U for V
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV))
{
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV)
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV));
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSW, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
}
else
{
if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV)
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV));
if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapW != material.TextureLayer[st].TextureWrapW)
pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSW, getTextureWrapMode(material.TextureLayer[st].TextureWrapW));
}
// Bilinear, trilinear, and anisotropic filter
if (resetAllRenderstates ||
......
......@@ -89,16 +89,25 @@ namespace irr
for (u32 i = 0; i < size; ++i)
{
IDirect3DTexture9* currentTexture = (texture[i] && texture[i]->getDriverType() == EDT_DIRECT3D9) ?
static_cast<CD3D9Texture*>(texture[i])->getDX9Texture() : 0;
CD3D9Texture* currentTexture = (texture[i] && texture[i]->getDriverType() == DriverType) ? static_cast<CD3D9Texture*>(texture[i]) : 0;
IDirect3DTexture9* textureID = 0;
if (currentTexture)
{
if (currentTexture->getType() == ETT_2D)
textureID = currentTexture->getDX9Texture();
else
os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
}
if (textureID)
{
Texture[i] = texture[i];
Texture[i]->grab();
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
textureID->GetSurfaceLevel(0, &currentSurface);
Surface[i] = currentSurface;
}
......@@ -128,10 +137,19 @@ namespace irr
DepthStencilSurface = 0;
}
IDirect3DTexture9* currentTexture = (depthStencil && depthStencil->getDriverType() == EDT_DIRECT3D9) ?
static_cast<CD3D9Texture*>(depthStencil)->getDX9Texture() : 0;
CD3D9Texture* currentTexture = (depthStencil && depthStencil->getDriverType() == DriverType) ? static_cast<CD3D9Texture*>(depthStencil) : 0;
IDirect3DTexture9* textureID = 0;
if (currentTexture)
{
if (currentTexture->getType() == ETT_2D)
textureID = currentTexture->getDX9Texture();
else
os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
}
if (textureID)
{
const ECOLOR_FORMAT textureFormat = (depthStencil) ? depthStencil->getColorFormat() : ECF_UNKNOWN;
......@@ -141,7 +159,7 @@ namespace irr
DepthStencil->grab();
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
textureID->GetSurfaceLevel(0, &currentSurface);
DepthStencilSurface = currentSurface;
}
......
......@@ -85,8 +85,18 @@ 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());
bool autoGenerateRequired = true;
for (u32 i = 0; i < tmpImage.size(); ++i)
regenerateMipMapLevels(tmpImage[i]->getMipMapsData(), i);
{
void* mipmapsData = tmpImage[i]->getMipMapsData();
if (autoGenerateRequired || mipmapsData)
regenerateMipMapLevels(mipmapsData, i);
if (!mipmapsData)
autoGenerateRequired = false;
}
}
else
{
......@@ -123,7 +133,7 @@ CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& si
if (!Driver->queryFeature(EVDF_TEXTURE_NPOT))
{
Size = OriginalSize.getOptimalSize(true, !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth);
Size = Size.getOptimalSize(true, !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth);
if (Size != OriginalSize)
os::Printer::log("RenderTarget size has to be a power of two", ELL_INFORMATION);
......@@ -421,7 +431,9 @@ void CD3D9Texture::getImageValues(const IImage* image)
Size.Width = (u32)(Driver->Caps.MaxTextureHeight * ratio);
}
Size = Size.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth);
bool needSquare = (!Driver->queryFeature(EVDF_TEXTURE_NSQUARE) || Type == ETT_CUBEMAP);
Size = Size.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), needSquare, true, Driver->Caps.MaxTextureWidth);
Pitch = Size.Width * IImage::getBitsPerPixelFromFormat(ColorFormat) / 8;
}
......
......@@ -202,6 +202,7 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre
InitMaterial2D.TextureLayer[i].BilinearFilter=false;
InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT;
InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT;
InitMaterial2D.TextureLayer[i].TextureWrapW = video::ETC_REPEAT;
}
OverrideMaterial2D=InitMaterial2D;
}
......@@ -2096,6 +2097,9 @@ io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMateria
prefix="TextureWrapV";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapV, aTextureClampNames);
prefix="TextureWrapW";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapW, aTextureClampNames);
prefix="LODBias";
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].LODBias);
......@@ -2185,6 +2189,7 @@ void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMater
{
outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+core::stringc(i+1)).c_str(), aTextureClampNames);
outMaterial.TextureLayer[i].TextureWrapV = outMaterial.TextureLayer[i].TextureWrapU;
outMaterial.TextureLayer[i].TextureWrapW = outMaterial.TextureLayer[i].TextureWrapW;
}
}
else
......@@ -2193,6 +2198,9 @@ void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMater
{
outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"U"+core::stringc(i+1)).c_str(), aTextureClampNames);
outMaterial.TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"V"+core::stringc(i+1)).c_str(), aTextureClampNames);
if (attr->existsAttribute((prefix+"W"+core::stringc(i+1)).c_str())) // legacy
outMaterial.TextureLayer[i].TextureWrapW = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"W"+core::stringc(i+1)).c_str(), aTextureClampNames);
}
}
......
......@@ -88,7 +88,17 @@ public:
for (u32 i = 0; i < Texture.size(); ++i)
{
GLuint textureID = (texture[i] && texture[i]->getDriverType() == DriverType) ? static_cast<TOGLTexture*>(texture[i])->getOpenGLTextureName() : 0;
TOGLTexture* currentTexture = (texture[i] && texture[i]->getDriverType() == DriverType) ? static_cast<TOGLTexture*>(texture[i]) : 0;
GLuint textureID = 0;
if (currentTexture)
{
if (currentTexture->getType() == ETT_2D)
textureID = currentTexture->getOpenGLTextureName();
else
os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
}
if (textureID != 0)
{
......@@ -108,7 +118,18 @@ public:
if (depthStencilUpdate)
{
GLuint textureID = (depthStencil && depthStencil->getDriverType() == DriverType) ? static_cast<TOGLTexture*>(depthStencil)->getOpenGLTextureName() : 0;
TOGLTexture* currentTexture = (depthStencil && depthStencil->getDriverType() == DriverType) ? static_cast<TOGLTexture*>(depthStencil) : 0;
GLuint textureID = 0;
if (currentTexture)
{
if (currentTexture->getType() == ETT_2D)
textureID = currentTexture->getOpenGLTextureName();
else
os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
}
const ECOLOR_FORMAT textureFormat = (textureID != 0) ? depthStencil->getColorFormat() : ECF_UNKNOWN;
if (IImage::isDepthFormat(textureFormat))
......
......@@ -28,15 +28,15 @@ class COGLCoreTexture : public ITexture
public:
struct SStatesCache
{
SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT),
LODBias(0), AnisotropicFilter(0),
BilinearFilter(false), TrilinearFilter(false),
SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT), WrapW(ETC_REPEAT),
LODBias(0), AnisotropicFilter(0), BilinearFilter(false), TrilinearFilter(false),
MipMapStatus(false), IsCached(false)
{
}
u8 WrapU;
u8 WrapV;
u8 WrapW;
s8 LODBias;
u8 AnisotropicFilter;
bool BilinearFilter;
......@@ -111,8 +111,18 @@ public:
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
bool autoGenerateRequired = true;
for (u32 i = 0; i < (*tmpImage).size(); ++i)
regenerateMipMapLevels((*tmpImage)[i]->getMipMapsData(), i);
{
void* mipmapsData = (*tmpImage)[i]->getMipMapsData();
if (autoGenerateRequired || mipmapsData)
regenerateMipMapLevels(mipmapsData, i);
if (!mipmapsData)
autoGenerateRequired = false;
}
if (!KeepImage)
{
......@@ -154,9 +164,11 @@ public:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
StatesCache.WrapW = ETC_CLAMP_TO_EDGE;
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, Size.Width, Size.Height, 0, PixelFormat, PixelType, 0);
......@@ -432,7 +444,9 @@ protected:
Size.Width = (u32)(Driver->MaxTextureSize * ratio);
}
Size = Size.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT));
bool needSquare = (!Driver->queryFeature(EVDF_TEXTURE_NSQUARE) || Type == ETT_CUBEMAP);
Size = Size.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), needSquare, true, Driver->MaxTextureSize);
Pitch = Size.Width * IImage::getBitsPerPixelFromFormat(ColorFormat) / 8;
}
......
......@@ -2707,7 +2707,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
#ifdef GL_VERSION_2_1
if (Version>=210)
{
if(!statesCache.IsCached || material.TextureLayer[i].LODBias != statesCache.LODBias)
if (!statesCache.IsCached || material.TextureLayer[i].LODBias != statesCache.LODBias)
{
if (material.TextureLayer[i].LODBias)
{
......@@ -2743,7 +2743,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
}
#endif
if(!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
......@@ -2755,7 +2755,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
if (material.UseMipMaps && tmpTexture->hasMipMaps())
{
if(!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || !statesCache.MipMapStatus)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
......@@ -2770,7 +2770,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
}
else
{
if(!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || statesCache.MipMapStatus)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
......@@ -2793,18 +2793,24 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
}
#endif
if(!statesCache.IsCached || material.TextureLayer[i].TextureWrapU != statesCache.WrapU)
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapU != statesCache.WrapU)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
statesCache.WrapU = material.TextureLayer[i].TextureWrapU;
}
if(!statesCache.IsCached || material.TextureLayer[i].TextureWrapV != statesCache.WrapV)
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapV != statesCache.WrapV)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
statesCache.WrapV = material.TextureLayer[i].TextureWrapV;
}
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapW != statesCache.WrapW)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, getTextureWrapMode(material.TextureLayer[i].TextureWrapW));
statesCache.WrapW = material.TextureLayer[i].TextureWrapW;
}
statesCache.IsCached = true;
}
......
......@@ -383,6 +383,7 @@ void CQuake3ShaderSceneNode::render()
material.TextureLayer[0].TextureWrapU = q.TextureAddressMode;
material.TextureLayer[0].TextureWrapV = q.TextureAddressMode;
material.TextureLayer[0].TextureWrapW = q.TextureAddressMode;
//material.TextureLayer[0].TrilinearFilter = 1;
//material.TextureLayer[0].AnisotropicFilter = 0xFF;
material.setTextureMatrix( 0, textureMatrix );
......
......@@ -43,6 +43,7 @@ CSkyBoxSceneNode::CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom
mat.AntiAliasing=0;
mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
mat.TextureLayer[0].TextureWrapW = video::ETC_CLAMP_TO_EDGE;
/* Hey, I am no artist, but look at that
cool ASCII art I made! ;)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment