1
\$\begingroup\$

I'm using a control which is using XNA inside. But when I try to draw something, it doesn't appear. I already did a lot of tests but can't figure out what's wrong. Here is the test I set up:

RenderTarget2D rTarget = new RenderTarget2D(GraphicsDevice, 1000, 1000);

GraphicsDevice.SetRenderTarget(rTarget);
GraphicsDevice.Clear(Color.White);
_spriteBatch.Draw(ts.Texture, layer.Location, source, Color.White, layer.Angle * (float)Math.PI /180, origin, SpriteEffects.None, 1f);
int spriteBatchGraphics = _spriteBatch.GraphicsDevice.GetHashCode();
int normalGraphics = GraphicsDevice.GetHashCode();
GraphicsDevice.SetRenderTarget(null);

using (FileStream stream = new FileStream("pic.png", FileMode.Create))
     rTarget.SaveAsPng(stream, 1000, 1000);

using (FileStream stream = new FileStream("pic2.png", FileMode.Create))
     ts.Texture.SaveAsPng(stream, ts.Texture.Width, ts.Texture.Height);

SpriteBatch.Begin, End and GraphicDevice.Present is called too.

Because I didn't see anything, I tried to draw the stuff onto a renderTarget and save it to the HDD. I also saved the texture itself to be sure it's not just white.

However, spriteBatch should draw a 48x48 block here and I checked the parameters of spriteBatch, they are okay. But on the rendertarget, nothing appears. I reacts on GraphicDevice.Clear, the color I pick there really gets drawn. The hashCodes of both graphicDevices are the same, so they really seem to draw to the same device.

What could cause this?

EDIT:------------------------------------------------------------------------------

I searched for some more and I found the following: I'm getting a AccessViolationException when closing the program. First I thought it's unrelated but it seems it's caused by what happened before. I found in the internet that a very bad graphic card can cause this. And the graphic card I tried this on was very bad indeed. So I tried it on an other machine now - I'm getting different results, but it's still not working and I'm still getting the exception.

Here is what it draws now: Stupid Bug

In place of the black spot, the tile should be drawn. But it's not happening. The AccessViolationException only happens when the draw glitch happens - in this case as soon it just draws a black block instead the real texture. The lines are planed and part of it (the horizontal are still missing for some reason, but trying to fix that later).

So what is happening? Gets the graphic device too much stressed? I'm also running a game class which runs with the default loop (which manages the winforms and game).

I absolutely need the XNA technology here, because it should "preview" something from the game and using System.Drawing could change the outcome. The program also could get used by clients so a normal powered graphic card should be able to deal with it.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ So, just to clear up some things: You're using XNA in a control. Is this a WinForms control? What code did you use to set this up? Did you use the official sample? If so, can you reproduce the problem using as little code as possible, and then post that code? Finally, does the code you're using work in regular XNA? Or does it fail in both XNA and WinForms? \$\endgroup\$ Jun 7, 2013 at 17:07
  • \$\begingroup\$ (Just so you have an idea of where I'm going with this: Pretty much everyone's "XNA and WinForms" tutorial out there, with the exception of the official one from Microsoft, is horribly, horribly broken. XNA itself uses WinForms internally - so if your code works in regular XNA, then you've got a problem with your WinForms integration.) \$\endgroup\$ Jun 7, 2013 at 17:09
  • \$\begingroup\$ github.com/Romoku/WindowsGame1/tree/master/… The GraphicsDeviceService and GraphicsDeviceControl classes are needed for it. Will post some code in a bit, it's not easy to reproduce it. \$\endgroup\$
    – t0rb
    Jun 7, 2013 at 17:53
  • \$\begingroup\$ I can't bring it to work in a simple application, even when I produce a lot of stuff (game and window message loop running, running in a dialog, hosted by a splitterContainer). It seems to happen when the program gets really complex :/ \$\endgroup\$
    – t0rb
    Jun 8, 2013 at 10:38

2 Answers 2

3
\$\begingroup\$

I can only speak to the example code you've posted:

SpriteBatch in all modes except SpriteSortMode.Immediate defers all rendering until End is called (it batches). If you're not calling End before you save contents of the render target, your sprite hasn't actually been drawn to it yet.

In Immediate mode, render states are set on the GPU in Begin and actual draw calls are sent to the GPU in Draw. Although I wouldn't be happy having SetRenderTarget inside a Begin/End block either way. I'm not even sure how that would behave (as it messes with things like the viewport).

Also note that, by default, SetRenderTarget will clear the render target that is being set.

Also, rather than GetHashCode, you should be using ReferenceEquals(_spriteBatch.GraphicsDevice, GraphicsDevice) for what you seem to be trying to achieve.

\$\endgroup\$
1
  • \$\begingroup\$ Didn't work sadly. But thanks for the tip with ReferenceEquals :) Also edited the question, found some stuff out but still not close to get it work. \$\endgroup\$
    – t0rb
    Jun 7, 2013 at 15:46
0
\$\begingroup\$

I found the solution, that one was a really hard one. The problem was the texture was loaded on a different graphicsDevice.

I said I have a gameLoop running and because it always exists, I was taking the graphicsDevice from there to create the texture. But the Control creates a graphicDevice itself (I guess I should let them use the same one, have to fix that) and caused the glitch with that.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .