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.
Related
I am implementing a security camera. I have the following methods, lets call them for simplicity:
capture(...)// captures the frame from the camera, frame used by the following methods:
comparetemplates(...)//if it detects any motion it triggers the following method:
detection(...)// applies haarcascade detection and recognition through EmguCv;
Basically I capture() the frame, check the boolean comparetemplates() and render the captured frame with detection() applied on it.
The Problem:
capture() renders to the screen real time in 30fps, however, the other methods require more time.
All operations are made with System.Drawing.Bitmap and conversions to wpf Source for rendering.
The Question:
I am willing to sacrifice real time rendering for a smooth, 30 fps rendering delayed by up to 6 seconds. I am not asking necesarily for code, but for the actual principle to call the methods and apply System delays or anything (threads etc).
Thank you.
Im working on isometric 2D tile engin for RTS game. I have two ways how can I draw floor. One option is one big image (for example 8000px x 8000px have about 10MB) and second option is draw images tile by tile only in visibly area.
My questin is what is better (for performance)?
Performance-wise and memory-wise, a tiled approach is better.
Memory-wise: If you can use a single spritesheet to hold the textures of every tile you need to render, then the amount of memory used would decrease tremendously - as opposed to redefining textures for tiles you want to render more than once. Also, on every texture there is an attribute called "pitch". This attribute tells us how much more memory is being used than the image actually needs. What? Why would my program be doing this? Back in the good old days, when Ben Kenobi was still called Obi Wan Kenobi, textures took up the memory they were supposed to. But now, with hardware acceleration, the GPU adds some padding to your texture to make it align with boundaries that it can process faster. This is memory you can reduce with the use of a spritesheet.
From a performance standpoint: Whenever you draw a regular sprite to the screen, the graphics hardware requires three main pieces of information: 1) The texture you want to render from. 2) What part of that texture you want to render from. 3) Where on the screen you want to render to. Repeat for every object you want to render. With a spritesheet, it only passes data once - a big performance increase because passing data from the CPU to the GPU (and vice-versa) is really slow.
And I disagree with the two comments, actually. Making a change of this caliber would be difficult when your program is mature.
Suppose I use DrawImage a few times to draw a bunch of images.
e.Graphics.DrawImage(newImage, destRect);
How can I delete a specific image from the Graphics paper that I drew it on?
Is there a specific function I can use for deletion?
I have tried dispose and Rectangle.Empty, but they don't actually delete the image I already drew on the paper.
First of all, there's no concept of "delete an object" in GDI+ Graphics. You have to redraw the the entire client area in every frame. You should keep a list of objects and their states in memory and redraw the entire surface in every frame. Beware though, this can lead to flickers and not-so-smooth user experience. Here are a few tips to avoid these:
Make sure your Form or UserControl has its DoubleBuffered property set to True. This will result in a far smoother animation than otherwise.
NEVER EVER call CreateGraphics() to get a reference to the Graphics object in your drawing loop. Update your list of objects and states in your loop and then call Invalidate() on your Control/Form and do the drawing process in Paint event.
One overload of Invalidate() allows you to specify the rectangle that needs to be invalidated (redrawn). You can pass a "safe" rectangle around your bouncing ball's current position (say 20 pixels wider/taller than the ball size) as agrument and then draw only that portion in your Paint event.
To further increase performance you can keep auxilary information such as scores, player names etc. outside the actual "game board" and use normal labels/textboxes for them instead of drawing.
krikara, what you should do is:
Keep track of all the bricks in a list
When the ball hits a brick, remove that brick from the list
Every frame, you must redraw everything from scratch. This includes the ball, the paddle and the list of bricks (and whatever else you need, like score, etc.)
Hope this clears up whatever confusion you had.
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'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.