Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have recently been converting our XNA 3.1 game to XNA 4.0 and am stuck on the shaders. I have the game running, but nothing is drawing to the screen, except things not using a shader.

This is only 2D drawing, using SpriteBatch, which im sure is where the problem is coming from.

In XNA 3.1 everything works fine with my custom vertex and pixel shaders targeting SM 3.0. I cant find any info on what has changed or why its not working. Ive stripped it down as far as I can to try to figure it out, but am not sure. It definitely seems like a coordinate issue with the vertex shader. If I strip our the vertex shader and switch to SM 2.0 for the pixel shader so it uses XNAs default vertex shader for SpriteBatch, it works as expected, but I need 3.0 and custom vertex shader functionality.

Here is stripped down version of things, I cant get PS to output anything anywhere:

// Input parameters.
float2   ViewportSize    : register(c0);
float2   TextureSize     : register(c1);
float4x4 MatrixTransform : register(c2);
sampler  TextureSampler  : register(s0);

struct VS_INPUT
{
    float4 position : POSITION0;
    float4 color    : COLOR0;
    float2 texCoord : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 position : POSITION0;
    float4 color    : COLOR0;
    float2 texCoord : TEXCOORD0;    
};

struct PS_INPUT
{
    float4 color    : COLOR0;
    float2 texCoord : TEXCOORD0;
};

VS_OUTPUT VertexTileShader(VS_INPUT input)
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    float4 position = input.position;

    // Apply the matrix transform.
    output.position = mul(position, transpose(MatrixTransform));

    // Half pixel offset for correct texel centering.
    output.position.xy -= 0.5;

    // Viewport adjustment.
    output.position.xy /= ViewportSize;
    output.position.xy *= float2(2, -2);
    output.position.xy -= float2(1, -1);

    // Compute the texture coordinate.
    output.texCoord = input.texCoord / TextureSize;

    // Pass on color
    output.color = input.color;

    return (output);
}

float4 PSTileLighting(PS_INPUT input) : COLOR
{
    return float4(1.0, 1.0, 1.0, 1.0);
}

technique TileLighting
{
    pass Pass1
    {
        VertexShader = compile vs_3_0 VertexTileShader();
        PixelShader = compile ps_3_0 PSTileLighting();
    }
}

C#:

// Setup matrix
transform = Matrix.CreateTranslation(-bounds.X, -bounds.Y, 0);

// Setup viewport
SectionViewport.X = 0;
SectionViewport.Y = 0;
SectionViewport.Width = bounds.Width;
SectionViewport.Height = bounds.Height;

Engine.GraphicsDevice.SetRenderTarget(background);

Engine.GraphicsDevice.Viewport = SectionViewport;
Engine.GraphicsDevice.Clear(Color.Transparent);

Map.TilesEffect.CurrentTechnique = Map.TilesEffect.Techniques["TileLighting"];

Vector2 viewportSize = new Vector2(SectionViewport.Width, SectionViewport.Height);
Map.TilesEffect.Parameters["ViewportSize"].SetValue(viewportSize);
Map.TilesEffect.Parameters["TextureSize"].SetValue(new Vector2(2048, 2048));

Engine.SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, Map.TilesEffect, transform);
DrawTiles(tileLayer, 0, 5, bounds, Color.White);
Engine.SpriteBatch.End();

DrawTiles calls the draw function on all the tiles within the bounds rectangle. They are all in a large 2048x2048 sprite sheet. Map is broken up into blocks of these which the transform matrix is used to offset.

This all works in XNA 3.1. I stripped the pixel shader to absolutely nothing, just outputs white (or is supposed to). Im sure its not any of the specific drawing code because like I said if I switch to the default SpriteBatch vertex shader (IE not defining one, and rolling the PS back to 2.0). Then it works as expected. It draws white pixels everywhere it should.

There must be something wrong im doing with the matrix / viewport manipulations, but am not sure what. Ive looked at SpriteBatches default shader, but it uses a lot of macros and sets the matrix up before going to the shader and not sure how to correlate it with mine.

Any help is appreciated, thanks.

share|improve this question
    
have you tried running this in pix? that could help you alot to debug your problem! –  Tordin Jul 15 '13 at 7:13
    
have you initialized the projection matrix in the shader? –  Blau Jul 15 '13 at 8:43
    
I asked this question a while back and here's the perfect answer: stackoverflow.com/questions/19690746/xna-3-1-to-4-0-shader –  Nick Jan 15 at 1:20

2 Answers 2

I think you are not initalizing the shader right. I don't see projection matrix initialization.

Here you can find how custom shaders work in xna 4.0

http://blogs.msdn.com/b/shawnhar/archive/2010/04/05/spritebatch-and-custom-shaders-in-xna-game-studio-4-0.aspx

share|improve this answer
    
Hmm, I thought thats what I was doing, except I do it inside the vertex shader itself? I will try doing it outside the shader and see if I can get any different results later tonight. Thanks. –  Joshjje Jul 15 '13 at 11:26
    
oh.. I didn´t realize you was doing that in the shader... :( and it seems right... –  Blau Jul 15 '13 at 14:40
    
try to set the texture before calling to spritebatch.Begin... or call to the effect.Apply when you set it... –  Blau Jul 15 '13 at 15:04

I believe ive solved this immediate issues, though now I have other unrelated ones lol. I dont know why this is, but this fixed it. Before I could not get any output whatsover, all blank/transparent. But just changing this fixed most of it:

From:

// Compute the texture coordinate.
output.texCoord = input.texCoord / TextureSize;

To:

// Compute the texture coordinate.
output.texCoord = input.texCoord;

Maybe it was a quirk in XNA 3.1 where the input texture coordinates wasnt in the 0-1 range? Bleh, I dunno.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.