Changing the colours of a texture in DirectX
Hello, I have loaded a texture of a cow with a magenta border surrounding the cow. Is there anyway for me to change the magenta border into another colour at runtime depending on what player controls it?
Two easy ways to do this, as far as I see:
1. Lock the texture to get a pointer to the texture's raw data, and change the values yourself.
2. Use a color-key to make the magenta transparent, then draw the cow texture on top of another texture containing the appropriate color for that player.
If you tell me which API (D3D9, D3D10, Managed D3D9, SlimDX, XNA) you're using I can be more specific on how to do these.
1. Lock the texture to get a pointer to the texture's raw data, and change the values yourself.
2. Use a color-key to make the magenta transparent, then draw the cow texture on top of another texture containing the appropriate color for that player.
If you tell me which API (D3D9, D3D10, Managed D3D9, SlimDX, XNA) you're using I can be more specific on how to do these.
or you could just load a couple different images, one with each color border, not the most efficient, but it is the easiest
I am using DX3D9, and I think editing the textures data would be my best bet. How would I do this?
Quote:Original post by beatdown_master
I am using DX3D9, and I think editing the textures data would be my best bet. How would I do this?
I can't answer your question directly but I would suggest that a multi-textured approach would be superior to this. The reason is that when you are manually "replacing" a color in a texture you are limited to essentially 1-bit of alpha information on the border of where your "outline color" meets your "texture color" (unless your outline is purely rectangular, or you're willing to write complicated code to perform the blending operation.) For instance, if your outline is green and you're blending it with a black-and-white cow texture, the proper ("antialiased") result is going to result in a number of pixels that are dark green, light green, and everywhere in between.
If you use two textures (either a base texture on top of your colored outline, or a colored outline on top of your base texture), you can use the alpha channels stored inside your assets to determine the level of blending on a per-pixel basis. Assuming your "outline texture" is pure white, you would then complete the blending operation by varying only the -vertex- colors used to render this white texture. This gives you the freedom to get good looking results merely by defining a single 24-bit color value to use for the outline.
If you do this, your only decision to make is one of memory vs. performance tradeoffs: whether to perform the composition at load time (presumably using a render-to-surface technique) or at render time (requiring you to draw both textures every frame, but saving you the memory required to store all possible color combinations in some offscreen surface).
I can give you some sample images to better illustrate what I mean if this isn't clear...
Thank you for the reply. I think I understand your explanation. Are you saying that if I just replace colour values for each pixel, I would not get the desired result because of the different colours used in anti-aliasing? I had not thought of this, and what I was thinking wouldn't work.
So, I should create another texture with just the outline of the cow in white (with the other portions transparent) and just change the alpha of that texture to produce the desired result?
So, I should create another texture with just the outline of the cow in white (with the other portions transparent) and just change the alpha of that texture to produce the desired result?
You can use the alpha channel to mark how much to blend your desired colour with the texture. "lerp(texture.rgb, colour.rgb, texture.a)" should do the trick. If you're already using the alpha, you can use another texture to supply the alpha.
Your description of a cow with a border sounds like you're doing a 2D, so I think that the smooth blending that MasterWorks talks about isn't necessary. You could probably make do with a simple pixel shader "return texture == magenta ? colour : texture". Using the alpha is actually more efficient, but pixel shader efficiency shouldn't be a problem if you're doing 2D.
Your description of a cow with a border sounds like you're doing a 2D, so I think that the smooth blending that MasterWorks talks about isn't necessary. You could probably make do with a simple pixel shader "return texture == magenta ? colour : texture". Using the alpha is actually more efficient, but pixel shader efficiency shouldn't be a problem if you're doing 2D.
There's probably a million ways to solve this sort of problem, but you get much more flexibility and higher image quality using some sort of (usually 8-bit) texture information to determine where to draw the border, and where not to.
Depending on your setup, the exact techiques will vary, but I think its MORE important to do proper blending if this is a 2D situation than if it is a 3D situation, which you haven't really specified; you'll have to give us more information if you need more detailed help. (For example, what does your cow texture look like? what kind of vertices is it rendered on to, and in 2D or 3D? does it already have its own alpha channel? is the outline perfectly rectangular or not? what kind of shaders/FFP stages are you using? do you need the freedom to render any color outline on any given frame? etc.)
Anyways, I'm not trying to make this more complicated than it needs to be; I am just generally adverse to the entire concept of "replacing a color" in this day and age since that either forces you to have ugly, 1-bit jagged edges, or to write complicated code where you have to figure out what exactly is close enough to some "magic color" to be replaced (and thus also precluding your use of the "magic color" in the image itself.) Even though "antialiasing" is technically not the correct term, I still can't imagine ANY outline that would be of adequate visual quality that didnt have varying levels of translucency in it -- except for an outline with only 90 degree angles, as mentioned.
Depending on your setup, the exact techiques will vary, but I think its MORE important to do proper blending if this is a 2D situation than if it is a 3D situation, which you haven't really specified; you'll have to give us more information if you need more detailed help. (For example, what does your cow texture look like? what kind of vertices is it rendered on to, and in 2D or 3D? does it already have its own alpha channel? is the outline perfectly rectangular or not? what kind of shaders/FFP stages are you using? do you need the freedom to render any color outline on any given frame? etc.)
Anyways, I'm not trying to make this more complicated than it needs to be; I am just generally adverse to the entire concept of "replacing a color" in this day and age since that either forces you to have ugly, 1-bit jagged edges, or to write complicated code where you have to figure out what exactly is close enough to some "magic color" to be replaced (and thus also precluding your use of the "magic color" in the image itself.) Even though "antialiasing" is technically not the correct term, I still can't imagine ANY outline that would be of adequate visual quality that didnt have varying levels of translucency in it -- except for an outline with only 90 degree angles, as mentioned.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement