Skip to main content
gamedev.net
🔒 Locked

Painting Texture

Started by dehseth Feb 25, 2009 at 9:22 AM 6 replies 1.6k views
Original Post
dehseth
dehseth
Hey guys, I am using c++ and directx9.0c in my application. I have a texture and I would like to paint all of the texture area to a certain color. Here is my code: D3DLOCKED_RECT locked; D3DSURFACE_DESC desc; HRESULT hr = m_texture->GetLevelDesc(0, &desc); hr = m_texture->LockRect(0, &locked, NULL, D3DLOCK_NOSYSLOCK); D3DCOLOR* buffer = (D3DCOLOR*)locked.pBits; D3DCOLOR count = (desc.Width * desc.Height); for (D3DCOLOR i = 0; i < count; i++) { buffer = color; // filling color value to buffer } hr = m_texture->UnlockRect(0); But whatever I do the background is WHITE! So what's the problem? Any help would be appriciated! THANX!
MCA
Evil Steve
Evil Steve
That code assumes three things:
1. The texture is 32-bit, ARGB format (D3DFMT_A8R8G8B8).
2. The texture does not have any padding at the end of the scanline.
3. The texture is not in the default pool.

To fix the second issue, your code would be:
D3DLOCKED_RECT locked;D3DSURFACE_DESC desc;HRESULT hr = m_texture->GetLevelDesc(0, &desc);if(FAILED(hr)){   // Error, bail   return;}hr = m_texture->LockRect(0, &locked, NULL, 0);if(FAILED(hr)){   // Error, bail   return;}BYTE* pBits = (BYTE*)locked.pBits;for(int y=0; y<desc.Height; ++y){   D3DCOLOR* pPixel = (D3DCOLOR*)(pBits + locked.Pitch * y);   for(int x=0; x<desc.Width; ++x)      pPixel[x] = color;}m_texture->UnlockRect(0);
As for the first issue, if your texture isn't D3DFMT_A8R8G8B8, you'll have to adjust the loop to use whatever format it is. And if your texture is in the default pool, you'll need to either move it to the managed pool, or use IDirect3DDevice9::UpdateSurface to update it.
dehseth
dehseth
Hey again,

well there's no difference in your code against mine.

I also check SURFACE_DESC it is as you have described:

Format D3DFMT_A8R8G8B8
Type D3DRTYPE_SURFACE
Usage 0x00000000
Pool D3DPOOL_SYSTEMMEM
MultiSampleType D3DMULTISAMPLE_NONE

I also copy and paste your code, and there was no affect.

I got noticed that texture and description info is not same so I added this code:

m_texture->Format = desc.Format;
m_texture->Pool = desc.Pool;
m_texture->Width = desc.Width;
m_texture->Height = desc.Height;

But Still NOT WORKING! So what causes this.. Thank you...
MCA
Evil Steve
Evil Steve
Quote:
Original post by dehseth
I got noticed that texture and description info is not same so I added this code:

m_texture->Format = desc.Format;
m_texture->Pool = desc.Pool;
m_texture->Width = desc.Width;
m_texture->Height = desc.Height;

But Still NOT WORKING! So what causes this.. Thank you...
That code doesn't do what you think, those values are just for debugging, and writing to them will probably crash your app if you run with the release runtimes.


If you call D3DXSaveTextureToFile(), does that still save a white texture? If you're trying to show the texture applied to a model, you need it to be in D3DPOOL_MANAGED, not system memory (The GPU can't access system memory).
dehseth
dehseth
Okey, so its useless to try that :)

Anyways I have tried to save texture by using this code:

hr = D3DXSaveTextureToFile(_T("c:\\texture.bmp"), D3DXIFF_BMP, m_texture, NULL);

But it was not successful and returned -2005530516;

something's fishy isn't it? how to solve it ?

thank you man...

note:by the way I am using IDirect3DTexture9 but save functions needs IDirect3DBaseTexture that may be why function failed..

I use system memory cause there's a warning about locking a texture:
Textures created with D3DPOOL_DEFAULT are not lockable. Textures created in video memory are lockable when created with USAGE_DYNAMIC.

And I do not need this texture all the time. I am directly drawing this texture to screen using Sprite. I am trying to develop a User Interface, so this basic texture with color is gonna represent background.
MCA
Evil Steve
Evil Steve
Quote:
Original post by dehseth
Okey, so its useless to try that :)

Anyways I have tried to save texture by using this code:

hr = D3DXSaveTextureToFile(_T("c:\\texture.bmp"), D3DXIFF_BMP, m_texture, NULL);

But it was not successful and returned -2005530516;

something's fishy isn't it? how to solve it ?
What is that as an 8-digit hex number, and more importantly what do the Debug Runtimes say about it?

Quote:
Original post by dehseth
note:by the way I am using IDirect3DTexture9 but save functions needs IDirect3DBaseTexture that may be why function failed..
IDirect3DTexture9 inherits from IDirect3DBaseTexture, so that's not a problem.

Quote:
Original post by dehseth
I use system memory cause there's a warning about locking a texture:
Textures created with D3DPOOL_DEFAULT are not lockable. Textures created in video memory are lockable when created with USAGE_DYNAMIC.

And I do not need this texture all the time. I am directly drawing this texture to screen using Sprite. I am trying to develop a User Interface, so this basic texture with color is gonna represent background.
You almost definitely want to use D3DPOOL_MANAGED. A system memory texture can only really be used for updating a video memory (D3DPOOL_DEFAULT) copy of a resource, which is what the managed pool does internally, and as you found out, you can't lock a default pool texture unless it's dynamic.

If you're drawing this sprite to the screen with ID3DXSprite, then it just won't work because it's in the system memory pool.

Short answer: Use the managed pool, this is what it's for.
programci_84
programci_84
@dehseth;

Ya kardeşim niye Lock() ve Unlock() ile uğraşıyorsun ki?

Bunun canavar gibi bir yolu var: IDirect3DDevice9::ColorFill(IDirect3DSurface9 * pSurface, CONST RECT * pRect, D3DCOLOR color).
Burada;
*pSurface: Dolduracağın yüzey
*pRect: Yüzeyin hangi bölümünü belirten dikdörtgensel yapı
*color: Renk

Örnek de yazayım:
LPDIRECT3DSURFACE9 pSurf;
m_texture->GetSurfaceLevel (0, &pSurf);
DWORD color = 0xFFFF0000; //kırmızı
m_pD3DDevice->ColorFill (pSurf, NULL, renk);

*pRect parametresini NULL geçtiğin zaman ilgili yüzeyin tamamını ilgili renkle dolduracağını belirtmiş oluyorsun.

Bir başka yöntem olarak da pSurf parametresini bir RenderTarget olarak gösterip Clear() yöntemini kullanarak temizleme imkânın da var:
LPDIRECT3DSURFACE9 pSurf, pRTYedek;
m_texture->GetSurfaceLevel (0, &pSurf);
m_pD3DDevice->GetRenderTarget (0, &pRTYedek);
m_pD3DDevice->SetRenderTarget (0, &pSurf);
DWORD color = 0xFFFF0000; //kırmızı
m_pD3DDevice->Clear (0, 0, D3DCLEAR_TARGET, color, 1, 0);
m_pD3DDevice->SetRenderTarget (0, &pRTYedek);

Kolay gelsin.
There's no "hard", and "the impossible" takes just a little time.
dehseth
dehseth
Thank you Evil Steve... My problem is solved. Actually I think I haven't studied enough about memory pools.

Also thank you programci_84, I tried ColorFill method which was unsuccessful beacuse of this I guess:
"This method can only be applied to a render target, a render-target texture surface, or an off-screen plain surface with a pool type of D3DPOOL_DEFAULT."

Well my problem is solved.. And I learn where the color fill is :) I couldn't find a method which will fill color for me..

Thanx!
MCA

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.