I'm creating a paint like application using XNA.
I have a render target which acts as a canvas. When the user draws something I draw corresponding triangles using DrawUserPrimitives and triangle strips to make lines and other curves.
I want to implement an eraser in the application, so that the user can erase the triangles from the texture. I've used OpenGL in the past and there I would just use a blend function like so: glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
How would I do this in XNA? I tried setting the GraphicsDevice blend mode to AlphaBlend, Additive, etc.. but it did not work. Any ideas?
If you change your code to use a Texture2D instead of a RenderTarget2D, you can use RenderTarget2D.GetTexture() to get the pixel data from the RenderTarget2D.
Of course, there will probably be a performance hit, but if you can optimize the code in a way that cuts down on the number of times this is done, like temporarily drawing the background color instead of actually erasing, and then iterating through the pixels after the mouse is released, you could make it work.
There may be a better way, but I couldn't find it.
Related
In XNA I am trying to create a game using old style Super Mario sprites, but if I try to make them bigger, they get very blurry. I have tried saving the PNG sprites as nearest neighbor, bicubic, and bilinear in photoshop, but they all appear equally blurry. I have also tried compressing the PNG online, which also didn't help.
My knowledge of XNA is somewhat basic, so unless your answer is code I can simply copy paste into my 'main' class, please explain how to use it.
In your draw-function you should only need to change one row of code.
Where you call spritebatch.Begin(); instead call
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise);
This will set your "GraphicsDevice" to render textures without interpolating the colors between whole pixels when the sprites get zoomed.
One other thing that you could do is to use a rendertarget with the resolution you want the game to "emulate" , draw everything on the rendertarget and finally draw that to the screen.
This is a bit out of the scope of this question but it is ideal if you want to create a genuine oldschool experience.
So I'm making a simple 2D Sidescrolling game in C# however I've found that using Graphics.drawImage doesn't particularly allow me to update the tiles as I wish. For example, I tell it to draw the image and it stays where I tell it to be. I want to be able to move the entire scene left to right. This would be easier if I had to use a for loop or something and define it's position every time it draws the image.
This may be confusing and I'm certain there's a way of doing it, I just don't know how.
So my question to you is: How can I control the positioning of each rectangle drew on a form so that I can scroll the entire scene to the left when I wish?
I'm certainly no game/graphics expert, so take this with a grain of salt.
A couple things spring to mind.
First, you could pre-render the entire level as one bitmap, then just paint the relevent portion into your picturebox.
Second, the Graphics class has a Transforms property (I may have the name wrong). You could add a linear transformation to the graphics object so the painting coordinates of your tiles wouldnt change, but the graphics object would slide, or I think the graphics term is "translate" the output en-masse.
I am developing a game. I would like to draw a couple of textures on the screen. I succesfully achieved that by drawing texture2d using spriteBatch.
The thing is the textures are displayed only if I put the code in the onDraw method. The onDraw method is bound to the timer so it executes many times. I would like to draw my rectangles only once.
When I put the code in the constructor the rectangles are not displayed - they show up only when I put the code in the onDraw function. How can I omit that?
There isn't really any sensible option for doing this in XNA. Most games want to re-draw the entire screen each frame - so that is how XNA is structured. (And, without a really compelling reason, this is how you should structure your game too.)
XNA is double-buffered (I don't think there's a way to turn that off). You do your drawing on the back-buffer and then swap it with the front buffer. You never draw to the screen directly.
So, while you don't have to clear the screen and re-draw it on each frame, if you don't you must manually keep the contents of these two buffers in-sync - otherwise you will get severe flickering. This is not worth the effort.
What you may be looking for is the Game.SupressDraw method (call it from Update - or - as an alternative: override BeginDraw and return false). This will prevent Draw from being called for that particular frame, and prevent the back-buffer from being swapped to the front. So the previous frame simply stays on-screen.
But it's generally easier to simply draw every single frame.
I'm trying to figure out how to draw text in 3D.
Right now I have two ways to display stuff onto the screen. One that uses usual 3d space to render the world, and additional render to render the HUD that does it in pretransformed way.
So, ideally I would like a way to do the same for text, to both render a string in 3D (kind of like "billboarding" way) and pretransformed way (as if I was using 2d mode).
The only thing that I was able to find is to use "Mesh.FromText", but it doesn't seem to be what I need. Oh, and also using spritebatch to draw text to a texture, and then using this texture in 3D with alpha blending, but again it seems like a crappy way to do it...
Any ideas?
You can draw with SpriteBatch in 3D space by using a custom effect. This blog post has the details.
It's as simple as passing an effect (like BasicEffect) with the correct transformations set on it to the appropriate overload of SpriteBatch.Begin (this one).
(The text is made up of transparent sprites - so all the usual caveats with drawing with transparency in 3D apply: sort and draw over the opaque, Z-buffered scene, or use alpha-testing.)
I am trying to make my lighting similar to Terraria's, block-lighting. Now, I know how to make blocks darker, I can assign blocks to a certain lightlevel, but, how would I make an actual light entity, that emits light in a round shape (Can be diamond-shaped too)?
Help would be greatly appreciated, also, if I wasn't clear in my question, feel free to ask.
Basic 2D lighting is very simple. Just do a distance check from your block, to your light, and use that value to scale your light.
This is something you could do fairly simple, since Spritebatch.Draw has a nice Color tint parameter [link]
A pseudo function could be
distance = (block.position - light.position). Length();
lightPower = distance / light.MaxDistance;
finalTint = light.Color * lightPower;
Render Block, with finalTint
For more nice looking light, you could replace "distance / light.MaxDistance" with a more smooth effect.
If you also want lights to go through a few blocks like Terraria, you could count all blocks between your block and the light source. Scale your lightPower down by that amount, and you get the same effect like Terraria has.
Of course, this is a non optimized way of doing it, but should work.
The latest Terraria version however seems to have smooth per pixel lighting instead of per block [preview]. For that I assume they used a second render target and/or Pixel Shader to keep fast performance. This could be a little difficult if you are not familiar with rendering pipelines though.
Hope this helps!
I'm working on a game with a similar lighting model, and the way we do it is this:
Draw the scene, without lighting, to a render target (called the 'Scene Buffer')
Draw the scene's lights, represented as grayscale gradients of any required shape, to a second render target (called the 'Light Map')
Draw the Scene Buffer to the screen, passing in the Light Map as a parameter to the pixel shader
In the pixel shader, query the value of the Light Map at each pixel and adjust the color of the final pixel up or down as necessary.
This also gives you the ability to have colored lighting; all you have to do is tint the light gradients that you render to the Light Map. Just remember to use additive alpha blending.
The downside of this approach is that it's rather naive, and provides no easy way to occlude the lights (that is to say, they pass through walls). In our case, this isn't an issue; you might decide otherwise.