Sign in to follow this  
johndirect

Filling a texture with multiple colors

Recommended Posts

Hi, Is there a way to fill a texture with multiple colors? I have created a surface of size 900x900 and have filled it with a single color (red) using the D3DXFillTexture function. Now, I want to fill it with multiple colors i.e. the first 1/3rd with red, the next 1/3rd wtih Green and finally the last 1/3rd with Blue color. Can someone please guide me on how to accomplish this? Also, can someone suggest some good books where I can learn such basics? Thanks

Share this post


Link to post
Share on other sites
If you created your surface lockable, you can lock it to acquire a pointer to raw data, and then you can fill it pixel-by-pixel with whatever colors you want.

If your surface is not lockable, you can still use IDirect3DDevice9::UpdateSurface to set data per-pixel.

Share this post


Link to post
Share on other sites
You use a lock to signal the GPU that you want to access the surface now. That will cause the GPU not to touch it until you let go of the resource by unlocking it. The resource must be created into D3DPOOL_MANAGED or D3DPOOL_DEFAULT with the D3DUSAGE_DYNAMIC flag for locking to work.

Also, you need to understand how the texture data is mapped into memory. That is, you need to take into account the width,height,stride and the color format of the surface.

Typically the process goes like this:

// Given LPDIRECT3DSURFACE9 s;

// First get format of the surface (you can omit this if you know this already)
D3DSURFACE_DESC d;
HRESULT hr = s->GetDesc(&d);
assert(SUCCEEDED(hr));

// Now fill some pixels white (assuming ARGB8888 format)
D3DLOCKED_RECT r;
hr = s->LockRect(&r, 0, D3DLOCK_DISCARD);
assert(SUCCEEDED(hr));
for(int y = 0; y < d.Height; ++y)
for(int x = 0; x < d.Width; ++x)
((unsigned long*)((uintptr_t)s.pBits)+s.Pitch*y))[x] = 0xFFFFFFFF;

hr = s->UnlockRect();
assert(SUCCEEDED(hr));


That overly complicated looking assignment inside the loop finds the proper pixel position in the surface and assigns it to white. You probably want to enclose the dirty pointer arithmetic logic to a safer PutPixel function or something similar.

Note that this is a good method mainly for initializing a texture with some value, since it is pretty slow (you're using CPU for drawing on your surface instead of the GPU, and the GPU can be stalling while you're doing it). If you need to do something like this on the GPU, you should look into custom render targets and 2D rendering.

The API documentation is your friend, look up the samples and reference there.

Share this post


Link to post
Share on other sites
Thanks again clb.

I tried the piece of code as suggested by you.
It compiles well but generates an exception when I run the program.

The only difference in your code and mine is that I use a Texture instead of a LPDIRECTSURFACE9.



Share this post


Link to post
Share on other sites
A texture contains several surfaces, did you acquire (and release after use) the surface you were interested? Also, this operation sequence would be best to be done outside the rendering loop.

You know, by just saying "generated an exception", you're bringing your message thread closer to the grave. Nobody can help you straightaway without asking you the typical troubleshooting questions, so usually won't bother and will just ignore the post.

To get more chance of a response, think about what's the first thing people would ask you and just provide that information before they have to.

So, what exception was generated? Which operation produced that exception? What was your data like at the point of that call? How did you create your data? (which pool,usage,format,size)

Hope this helps.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this