[.net] XNA Drawing Sprites

Started by
16 comments, last by alex_myrpg 16 years, 11 months ago
Some screenshots of what you're seeing when you apply the blending modes would be helpful. I'm not sure what XNA is doing when you set BlendMode.None and so on.
Advertisement
Alright, here are some screenshots:

With SpriteBlendMode.None, it seems to half-work. The background of the cursor PNG image is definitely fully transparent by the way, but I still wouldn't expect it to show up since I'm using SpriteBlendMode.None.



Now with SpriteBlendMode.None, it *is* transparent, but fully transparent! I don't even see the black pixels where they should be (in the shape of an I - see below).



The previous two images were where I had this code right before the Draw() method was called:

' Set render state to invert cursor pixels.Me.GraphicsDevice.RenderState.AlphaBlendEnable = TrueMe.GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = TrueMe.GraphicsDevice.RenderState.BlendFunction = BlendFunction.AddMe.GraphicsDevice.RenderState.SourceBlend = Blend.InverseDestinationColorMe.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceColor


This final image is where I do use SpriteBlendMode.AlphaBlend, but I don't include the code to set the custom render state, as above. The 'I' cursor draws fine - where black is drawn on white, it works correctly, but where black is being drawn on black, it still draw blacks of course, where I want it to invert in this case and draw a white pixel instead.



I hope this makes things clearer now. I'll be working on the problem in the meanwhile a bit, but it's unlikely I'm going to solve this by myself any time soon...
Quote:Original post by alex_myrpg
Alright, here are some screenshots:

With SpriteBlendMode.None, it seems to half-work. The background of the cursor PNG image is definitely fully transparent by the way, but I still wouldn't expect it to show up since I'm using SpriteBlendMode.None.



Now with SpriteBlendMode.None, it *is* transparent, but fully transparent! I don't even see the black pixels where they should be (in the shape of an I - see below).



The previous two images were where I had this code right before the Draw() method was called:

*** Source Snippet Removed ***

This final image is where I do use SpriteBlendMode.AlphaBlend, but I don't include the code to set the custom render state, as above. The 'I' cursor draws fine - where black is drawn on white, it works correctly, but where black is being drawn on black, it still draw blacks of course, where I want it to invert in this case and draw a white pixel instead.



I hope this makes things clearer now. I'll be working on the problem in the meanwhile a bit, but it's unlikely I'm going to solve this by myself any time soon...


I'm curious, is the cursor drawn as black (that is, the actual source texture, no blending, etc..)? Try recolouring the cursor to white in a paint program, use BlendMode.AlphaBlend, and use the Source/Dest blends I gave you. The reason being is that I just tried this (using a huge cursor), and when drawn as black it was transparent, and when I recoloured it to white it behaved as I expected. The colour outside of the cursor was set to red, but 0 alpha and in my sprite display it didn't show the inverted red (which is what I wanted).

There's probably a better way of accomplishing the inverted mode, but this is just an idea I whipped up on short notice, and it's not the best solution by far, I'll experiment further when I get home from work.
Yeah, I'd be interested in what your experiments turn out... Thanks very much so far! I'll try out your temporary solution now.
Quote:Original post by alex_myrpg
Yeah, I'd be interested in what your experiments turn out... Thanks very much so far! I'll try out your temporary solution now.


So in my experiments yesterday I wasn't able to find a better solution. I really don't know what XNA does regarding texture states/render states when you set SpriteBlendMode.* and so on, so it's hard to compare my results with that of XNA.

I inverted a texture in a paint program and then inverted it again in my sprite editor, and it displayed as though it hadn't been inverted, so that would indicate that the source/dest blend states were correct. My alpha channel was being observed correctly as well.

I might suggest you set it to SpriteBlendMode.None, and then set the texture/render states yourself, in addition to being a little easier to follow, it'd also give you a lot more control. However, not being familiar with XNA, I don't know if this is possible.

I set the following states:
RenderState.AlphaBlendEnable = true
RenderState.SourceBlend = InverseDestinationColor
RenderState.DestBlend = InverseSourceColor
TextureStageState.ColorOperation = Modulate
TextureStageState.ColorOpArg1 = Diffuse
TextureStageState.ColorOpArg2 = Texture
TextureStageState.AlphaOperation = Modulate
TextureStageState.AlphaOpArg1 = Diffuse
TextureStageState.AlphaOpArg2 = Texture

I don't really know what else to do aside from using a pixel shader to invert, but that seems like overkill to me.

Hope this helps a little.
Well your solution up to know really isn't *that* hacky - it's worked well for me. I'll experiment a bit myself now, and post the result for you and any others that are interested.
all you need to draw transparent sprites is to use a texture that has an alpha channel, then use alphablend as your mode, and it'll do it automatically.
I'm not sure that you realise that doing this together with setting the render state makes neither work properly?

This topic is closed to new replies.

Advertisement