- Home /
Regenerate Mips in Native plugin
Hi all,
I've been working on this for nearly a day now and I can't find what my problem is so here I go:
I wrote a plugin that allows a texture to write itself on another texture. I do this this way to optimize since I need all this to run very fast. It works fine except for one thing : I'm unable to regenerate the mips (since I'm only modifying the mip 0).
So there is 3 elements here that I think are needed to be known so you can help me better :
1: I create the texture I write in in C# like this:
mResultingAtlas = new Texture2D(mMaxAtlasSize,mMaxAtlasSize,TextureFormat.ARGB32,true);
For the record, I don't want to use PackTexture(), just so this is out of the way. Lets go on.
In this call, I specify I want mips, I figure this is OK, but I'm not sure how Unity create the texture in DirectX so it's hard for me to understand what is going on. If anyone has access to source code, maybe just tells me how this is handled?
2: Here is my writing function in C++:
void EXPORT_API WriteTextureInAtlas(void* aAtlasTexture, void* aTextureToWrite, int aStartX, int aStartY, int aBpp) {
if (aAtlasTexture && aTextureToWrite)
{
IDirect3DTexture9* d3dAtlasTex = (IDirect3DTexture9*)aAtlasTexture;
IDirect3DTexture9* d3dTex = (IDirect3DTexture9*)aTextureToWrite;
D3DSURFACE_DESC atlasDesc;
D3DSURFACE_DESC texDesc;
d3dAtlasTex->GetLevelDesc (0, &atlasDesc);
d3dTex->GetLevelDesc (0, &texDesc);
D3DLOCKED_RECT lrAtlas;
D3DLOCKED_RECT lrTex;
RECT rectToLock;
rectToLock.top = aStartY;
rectToLock.left = aStartX;
rectToLock.bottom = aStartY + texDesc.Height;
rectToLock.right = aStartX + texDesc.Width;
d3dAtlasTex->LockRect (0, &lrAtlas, &rectToLock, 0);
d3dTex->LockRect(0, &lrTex, NULL, 0);
unsigned char* atlasData = (unsigned char*)lrAtlas.pBits;
unsigned char* texData = (unsigned char*)lrTex.pBits;
for(int i = 0; i < texDesc.Height; i++)
{
memcpy(atlasData,texData,texDesc.Width*aBpp);
atlasData += lrAtlas.Pitch;
texData += lrTex.Pitch;
}
d3dAtlasTex->UnlockRect(0);
d3dTex->UnlockRect(0);
}
}
So this works perfectly like I want it to work.
3: Here how I'm trying to regenerate the mips:
void EXPORT_API RegenerateMips(void* aAtlasTexture) {
if (aAtlasTexture)
{
IDirect3DTexture9* d3dAtlasTex = (IDirect3DTexture9*)aAtlasTexture;
d3dAtlasTex->GenerateMipSubLevels();
}
}
I tried a lot of stuff like telling the constructor of Texture2D to NOT generate mips, and only generate them afterward in the plugin function call RegenerateMips() but to no avail.
Also, I tried (for the heck of it) to call Apply() in C# right after RegenerateMips() and this seems to "erase" the modifications the call to WriteTextureInAtlas() does... any reason for that? Would really like to know why Apply() seems to conflict!
Anyway, I could do this piece of code for each mip levels but this would take much longer to run and thus is not really a viable option.
Hope someone can help me out here!
Just want to add that I did the Android version of this plugin (in OpenGL ES) and for some reason, when my texture has mips, the copy of the texture does not work as intended either (its a completely different way to deal with than in DirectX so maybe its not related). Anyways, $$anonymous$$ips seems to be a problem when dealing with textures in Plugins! Any answer would really be appreciated!
Your answer
