[SOLVED] Black Image

I have a variety of controls that are composed then drawn. One of them is more complex than the others, and is showing as a black square. I suppose I should mention that this was working under XNA 4.0, and I am shifting over to MG3.8, which has been mostly a painless process, but there are just a few differences, perhaps between DX9 and DX11. This seems like it is probably just one of the differences.

Since I have working code form other controls, I chopped most everything out of the recalcitrant control, then compared what was left, which was pretty minimal. I then altered the code a bit to more closely match the working code, and by doing so, I believe I narrowed it down to at least one line, which takes just a bit of a backstory.

I set one render target, do some drawing to that, set a second render target, do some drawing to that, then draw the first target onto the second. There’s a bit of clipping going on in there based on a stencil, and I may yet find an issue with that, but I was able to comment out all of that, to isolate the current issue.

So, what matters is that I set one render target, do some drawing, set a second render target, do some drawing, then draw one on the other. I then have this line:

GraphicalDevice.SetRenderTarget(Nothing)

Following which, I draw a texture, draw the combined rendertarget2D from the earlier step, then draw a couple more things.

It is the line shown that seems to be the source of the problem. In the working control, there is only one layer, not the blending of a few different layers (it’s just a rectangle), so I never call SetRenderTarget, I just start drawing.

Is SetRenderTarget(Nothing) the right thing to be doing having set two other render targets earlier in the code?

I also saw the other thread about a png image being all black, so I followed that SetRenderTarget line with a call to GraphicalDevice.Clear(Color.Transparent), but that didn’t appear to have any effect.

I guess I should add that the reason I feel that one line is the issue is because, if I comment out everything before it (all the rendering to other targets), I still get a black square. If I then comment out that one line, I now get a drawing. It isn’t the RIGHT drawing, since all the other composition is commented out, but it isn’t a black square, and what drawing remains is correct. So the difference between a black square and a drawing, is that one line.

A quick further test may add something: Adding that line to the working code caused the working code to break. The working code did not set a render target for the graphical object, it used whatever the setting was if you don’t explicitly set a render target.

From a bit of searching, setting the render target to Null or Nothing is appropriate, as it targets the back buffer. I would assume that to be the target if the render target is not set at all. However, setting it explicitly causes blackness.

So, does SetRenderTarget(null) not return it to whatever state it was in if you don’t set a render target at all?

The back buffer does not preserve the state but you can create a render target as replacement which supports it. You would have to pass this option as a parameter when calling the constructor of the render target. You draw everything to this render target and as a final step you can just render the render target to the back buffer for example with sprite batch. This way you get this functionality.

Does that fit with what I described? If I never set the render target, drawing works fine. If I explicitly set render target to Null or Nothing as the first line of the exact same code, I get a black rectangle.

What am I using when I don’t explicitly set a render target?

I believe a default RT is in use?

When you create a GraphicsDevice, it has them set up…

Then you maybe need to clear the back buffer after setting it to null.

RenderTarget2D rt;
...
GraphicsDevice.SetRenderTarget(rt);
GraphicsDevice.SetRenderTarget(null); // This is the default if you don't explicitly set anything
GraphicsDevice.Clear(Color.CornflowerBlue); // If you don't clear the back buffer it is black (Only happens if you set up a render target other than null before.)

@kwyrky: That won’t work. That’s the very code that I’m saying doesn’t work. The act of setting the render target to null results in a black screen for those controls that didn’t set it, and results in a black screen if it was first set to something else (in which case it seems like you SHOULD set it to null).

I’ll be digging into the MG source behind this over the next week to see if I can figure out what is going on. If what Mr. Valentine said is true, that would explain a whole lot, but then how do I get back to the default once I move away from it. I tried to get the current render target, but there is no means to do so that I can see. The source will provide an answer.

1 Like

I think using seperate render targets for each control and then finally set the render target to null (and draw everything) could work here.

A bit of digging showed what was happening: It was me.

What I hadn’t realized was that I was setting a render target in the base class to all the controls (I wrote it a long time back). I created a SwapChainRenderTarget, and set the render target to that back when the control was created. So, setting the render target to Nothing was not returning to original state, it was returning to some other state.

By adding a method to return to original state, which meant setting the state back to the SwapChainRenderTarget, things were better. Not perfect, but this particular problem has been solved.

2 Likes

Mark as [SOLVED]

I was looking for a means to do that, and have yet to find it. There are aspects of this chat software that I am still learning. So, how DO you mark it [SOLVED]?

I marked it as solved by editing the title. I think as new registered user this is maybe not available yet.

1 Like

My bad, headache is not helping…

So, that’s an option that gets unlocked after some number of posts? I’ll get to it, then. If I don’t find an answer to my current question (regarding stencils) by reading other threads, I’ll start another.

1 Like

Funny enough, another stencil thread is recently active.

If your issue is unrelated, you can start a different thread with a more specific title.