Sign in to follow this  
Toolmaker

D3DSprite and rendering a VB: VB no longer renders

Recommended Posts

I was working on my game right now, and all the sudden I noticed that the DragSelection no longer worked. So I went to look at while, removed all other render objects, and noticed that the drag selection is pretty messed up. After messing a bit around with how the VB is filled(It's a square linestrip showing the drag selection), the line no longer shows up. I changed it then to show up with a fixed position and size. The result is this: The rendering code is this:
        public void Render()
        {
            if (visible)
            {
                engine.Sprite.End();

                engine.Device.VertexFormat = CustomVertex.Transformed.Format;
                engine.Device.SetStreamSource(0, vb, 0);
                engine.Device.DrawPrimitives(PrimitiveType.LineStrip, 0, 4);

                engine.Sprite.Begin(SpriteFlags.AlphaBlend);
            }
        }

        private void fillVertexBuffer(VertexBuffer vb)
        {
            size.Width = 100;
            size.Height = 100;
            top.X = 100;
            top.Y = 100;

            // Now fill our vertexbuffer
            CustomVertex.Transformed[] verts = new CustomVertex.Transformed[5];
            verts[0].Position = new Vector4(top.X, top.Y, 1.0f, 1.0f);
            verts[1].Position = new Vector4(top.X, top.Y + size.Height, 1.0f, 1.0f);
            verts[2].Position = new Vector4(top.X + size.Width, top.Y + size.Height, 1.0f, 1.0f);
            verts[3].Position = new Vector4(top.X + size.Width, top.Y, 1.0f, 1.0f);
            verts[4].Position = new Vector4(top.X, top.Y, 1.0f, 1.0f);

            vb.SetData(verts, 0, LockFlags.None);            
        }

What causes this? It worked before, and I don't recall changing the render state. Toolmaker

Share this post


Link to post
Share on other sites
That looks like the backbuffer isn't the same size as the client area of the window to me. That causes D3D to StretchBlt() the backbuffer, resulting in distortion - particularly evident where you have 1 pixel wide lines.

I don't know how C# works, but presumably the CreateWindow() call is similar to C++'s - in which case you should be using AdjustWindowRect() to give the the window size from the client area size.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
I don't know how C# works, but presumably the CreateWindow() call is similar to C++'s - in which case you should be using AdjustWindowRect() to give the the window size from the client area size.

You can set the client size using Form.ClientSize. Just make sure you call that with the correct size somewhere in your code, or use the value returned from it when constructing the backbuffer.

[EDIT] You also most likely want to be offsetting the positions by half a pixel, since you're drawing Transformed Vertices. You can find more information about that here: Directly Mapping Texels to Pixels.

Hope this helps.

Share this post


Link to post
Share on other sites
I already set the ClientRectangle to the same size as I initialize the backbuffers. I use a ScreenWidth / ScreenHeight pair which I set the client rect to and pass to Engine.Initialize().

I've been messing around a bit with an offset of -0.5f, but that doesn't help much. However, after a few tries it showed up, with the horizontal lines being dotted. But now, after a few times running it wuthout any major change, it no logner shows up...

Any ideas?

Share this post


Link to post
Share on other sites
I don't understand it... I checked my DX book, and it basically should work. So I created a little seperate piece of code to render a random triangle on the screen. The code is below, and nothing is visible...


namespace DuneRemake.GameStates
{
public class TestState : GameState
{
private Engine engine;
private Mouse mouse;
private VertexBuffer vb;
private float offset = 0f;

public TestState(Engine engine, GameStack stack, Mouse mouse)
: base(stack)
{
this.engine = engine;
this.mouse = mouse;

InputMap inputMap = new InputMap();
inputMap.MouseMove += new MouseEventHandler(mouse.MouseMoved);
InputManager inputMgr = (InputManager)engine.TaskManager.FindTask("input");
inputMgr.InputMap = inputMap;

vb = new VertexBuffer(typeof(CustomVertex.Transformed), 5, engine.Device,
Usage.WriteOnly, CustomVertex.Transformed.Format, Pool.Default);
vb.Created += new EventHandler(OnVertexBufferCreated);

}

private void OnVertexBufferCreated(object sender, EventArgs e)
{
VertexBuffer vb = (VertexBuffer)sender;

FillVertexBuffer(vb);
}

private void FillVertexBuffer(VertexBuffer vb)
{
CustomVertex.Transformed[] verts = new CustomVertex.Transformed[5];
verts[0].Position = new Vector4(100 - offset, 100 - offset, 1.0f, 1.0f);
verts[1].Position = new Vector4(100 - offset, 100 + 100 - offset, 1.0f, 1.0f);
verts[2].Position = new Vector4(100 + 100 - offset, 100 + 100 - offset, 1.0f, 1.0f);
verts[3].Position = new Vector4(100 + 100 - offset, 100 - offset, 1.0f, 1.0f);
verts[4].Position = new Vector4(100 - offset, 100 - offset, 1.0f, 1.0f);

vb.SetData(verts, 0, LockFlags.None);
}

public override void Update(float deltaTime)
{
engine.Device.RenderState.Lighting = false;
}

public override void Render(Engine engine)
{
engine.Device.VertexFormat = CustomVertex.Transformed.Format;
engine.Device.SetStreamSource(0, vb, 0);
engine.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);

mouse.Render();
}
}
}

Share this post


Link to post
Share on other sites
The OnVertexBufferCreated might not be getting called in your test code. It's been a while since I worked with MDX, but IIRC the Created event typically only fires when the device is reset (seems to be true), so you'll have to call OnVertexBufferCreated manually the first time (i.e. when initializing in the constructor).

As for your original problem, it might be worth a try to render a PointList of the vertices you use to see if at least the vertices show up at their expected positions. Alternatively Pix might be of use to determine if the mesh is being rendered correctly. There doesn't seem to be anything wrong with your original code at first glance, but I'd try reducing the Z coordinate of the vertices to 0.95f or something like that. Just maybe some rounding error is causing them to fall behind (or z-fight) the far clipping plane at Z=1.

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker

I'm starting to lose faith in myself...


Well, you shouldn't. I'm no guru by any means, but I can't even begin to count the number of times I was completely stumped by some 3D coding problem myself, only to find I was making a stupid mistake or that MDX didn't quite work as I had expected. Fortunately with the help of the forum goers here and other extremely patient people, I got to learn from my mistakes. But enough of my uninspiring ramblings, you simply must keep faith at least until the Dune 2 remake is done [smile]

I was thinking disabling backface culling might help (device.Renderstate.CullMode = Cull.None), but even so the pointlist should still be rendered regardless of cullmode and winding order. Maybe the problem lies with the renderstates and/or how the sprite mangles them. I don't recall if MDX sprites can be set up to preserve renderstate like the XNA ones, but you might want to check out the flags available for Sprite.Begin.

Another thing to try is to set up the states you need (like disabling lighting) just before your rendering code, so you can rely on them being set correctly. As it is now, any states you set in the Update method could very well be overwritten by other code, like the rendering of the sprite.

Hope this helps :)


Share this post


Link to post
Share on other sites
Issue fixed: I walked through the list of renderstates, and disabled each of the states I knew what they did. Turns out that turning the Z-Buffer off fixed the issue.

Thanks for all the help guys.

Toolmaker

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this