Rather weird D3DXCreateTexture problem

Started by
7 comments, last by MikeWW 18 years, 3 months ago

int level = 1;
D3DXCreateTexture( pd3dDevice, tWidth,tHeight, level, D3DUSAGE_DYNAMIC,D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTexture )


After this I use LockRect() and write a procedural pattern to this texture. Then send it to shaders and is not modified thereafter. My prob is if I set level to anything other than 1 (including 0, which generates all mip levels), this texture automatically get applied a simple and changing color gradient when the model it is on is rotated. If level is 1, the gradient doesn't show up. Surely I m missing something obvious?
Advertisement
Are the dimensions of the texture not powers of two by any chance? If they are not that may be the source of the problem depending on your gfx card.

Support for non-pow2 textures is split into three types in D3D9:
* Not at all
* Conditional
* Full
(See docs for the TextureCaps member of the D3DCAPS9 structure for the cap bits to check to see what your gfx card supports).

If your texture is non-pow2 I would hazard a guess that your gfx card has conditional support for non-pow2 textures and that is the cause of your problem. This would be because one of the conditions for conditional non-pow2 support is that the texture is non mip mapped (together with a non DXT format and CLAMP sampling).

While you would expect the runtime to just refuse to use a non-pow2 texture that does not meet the required conditions on a "conditional support" card I have found at least 1 gfx card that will happily accept the texture (with no related debug spew IIRC) but render a random colour gradient when using the texture.

A bit obscure but you never know! Hope this helps,

Mike.

[EDIT: I should mention that I don't remember the gradient changing as the model moved with this issue - but that could be caused to various strange memory goings on in the gfx card...possibly...]
Dimension is 128*128
GPU is ATI radeon x1800 xl
directx 9c, debug enabled

Gradient appears when surface normal forms approximately 70 degree angle with the camera's view vector. Then, even in the PS, when I read from the texture I get the erraneous color values from the gradient.

Gradient recedes and disappears when surface normal aligns with the view vector direction. All color values in the texture returns to normal. Thus the process is not destructive to the texture.

There is no evidence orientation affects color values stored in this texture.Perhaps its the GPU.
Could you post a screenshot?
Ah, maybe you are not filling (or auto-generating) all the extra mip-map levels? That could be why the angle of the surface to the camera causes the effect to occur - it is selecting mip map levels that contain garbage?
Feel free to look at the source, a modification of a sample project.

http://www.geocities.com/darkforest4/BasicHLSL.zip

The problem is at line 422 in BasicHLSL.cpp
Change 1 to 0,2,3... the prob occurs.

If equals to 0, dx should fill in all levels.
Hi,

With D3DXCreateTexture, if the number of mip map levels requested is 0 D3DX *creates* a complete mip map chain but it does not do anything else (i.e. it does not auto generate the mip maps for you). If you want a complete set of mip maps but you don't want to set them all yourself you can either specify D3DUSAGE_AUTOGENMIPMAP when creating the texture for D3D to generate them for you (if the gfx card supports it) or use D3DXFilterTexture.

I've checked out your code and this does seem to be the problem: Specifying D3DUSAGE_AUTOGENMIPMAP solves the problem.

(Also the D3D debug spew is saying that you are not freeing all the D3D objects you are using and that your IB and VB should really be WRITEONLY (as they are in the default pool) - just letting you know in case you had it turned off!).

I hope that this helps! (finally!)

Mike.
Thank you! While this is a subtlty, it makes sense considering calling this function simply creates a blank texture. BTW, what is the reason the value 1 works.

Yes, the sloppiness is due to simplying/adapting the project for public viewing. Nonetheless, yes, lots to learn about various flags.
Glad I could help!

The reason that specifying one mip-map level works is that you are filling in the top level of the surface in your code only - so that one level gets the correct data. When >1 mip map levels are created (when numLevels is set to 0 or >1) they start off uninitialised (full of random garbage) and as you are not filling them yourself they remain full of garbage.

Remember that mip-mapping is not always required. It depends on your usage of the texture in question.

Mike.

This topic is closed to new replies.

Advertisement