Advertisement Jump to content
Sign in to follow this  

[MDX] Matrix Translations of VBs and D3DXSprite's default setup?

This topic is 4579 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently experimenting a bit with adding the support of VertexBuffers to my 2D game, which mostly uses the Sprite interface to do all the work. However, I want to use vertexbuffers to define the selection rectangle(The rect surrounding a unit when it's selected), and I already use a VB to show the drag selection rect. However, for the drag selection I can get away with re-filling the data of the VB each change. However, this becomes a bad thing when you have 10 or 20 units visible on the screen, and you need to fill up the coordinates all the time. I'm doing this on a higher level than having each unit do it's own rect drawing, because there are cases where unit z might overlap the selection box of unit y, which is ugly and confusing. So I filled a (newly created) VB like this: (I'm changing this to be computed later on, it's just a test):
        private void fillVertexBuffer(VertexBuffer vb)
            CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[16];

            verts[0].Position = new Vector3(5.0f, 0.0f, 1.0f);
            verts[1].Position = new Vector3(0.0f, 0.0f, 1.0f);
            verts[2].Position = verts[1].Position;
            verts[3].Position = new Vector3(0.0f, 5.0f, 1.0f);

            verts[4].Position = new Vector3(0.0f, 10.0f, 1.0f);
            verts[5].Position = new Vector3(0.0f, 15.0f, 1.0f);
            verts[6].Position = verts[5].Position;
            verts[7].Position = new Vector3(5.0f, 15.0f, 1.0f);

            verts[8].Position = new Vector3(10.0f, 15.0f, 1.0f);
            verts[9].Position = new Vector3(15.0f, 15.0f, 1.0f);
            verts[10].Position = verts[9].Position;
            verts[11].Position = new Vector3(15.0f, 10.0f, 1.0f);

            verts[12].Position = new Vector3(15.0f, 5.0f, 1.0f);
            verts[13].Position = new Vector3(15.0f, 0.0f, 1.0f);
            verts[14].Position = verts[13].Position;
            verts[15].Position = new Vector3(10.0f, 0.0f, 1.0f);

            for (int i = 0; i < verts.Length; ++i)
                verts.Color = Color.White.ToArgb();

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

First of all: Using the CustomVertex.Transformed isn't a good idea right? The name sort of implies it's already transformed, so I need to use normal vertices(I might aswell use PositionColored) right? EDIT: I changed it to PositionColored, and there's a black line in the top right. However, when I now call Transform, my line disappears completely. And not to mention, it's black, even tho I gave it a color(Also doesn't work with red or any other color). (EDIT: Color problem was fixed by myself: I turned of lightning). Do I need to setup a View and Project to translate it properly? And to what settings do I need to set these to have them use a 1 pixel per 1.0f unit in each Vertor3? While I'm at this, I'm more and more wondering if it's a good idea to just transform this all into textured quads, as a good learning experience to get to know how to work with the different handed coordinate systems. Toolmaker

Share this post

Link to post
Share on other sites
I can't speak for the others, but I'd love to help. I just can't really understand what it is you're trying to do, and what's going wrong.

What do you mean by "Call Transform"? What's that about unit Z and overlapping? I'm not sure what you're even talking about.

Hope to help :).

Share this post

Link to post
Share on other sites
Allow me to explain the overlap:
When moving units across the battlefield(while being selected), there might be a chance of where 2 units collide with eachother. If I let all the units draw their own selection box, the selectionbox of unit a might be below unit b(So basicly, there is a change you can't see the health bar of unit a, because unit b is drawn over it).

This would look ugly to me.


What do you mean by "Call Transform"?

When I fill my VB with the above mentioned coordinates, it's show 2 lines in the top right corner of my screen(See below). This does make sense with all the standard settings I think, because the origin is in the center of the screen.

However, what I want to accomplish is this:

That one is accomplished with a VB filled with CustomVertex.Transformed vertices, however, I can't transform those any further(From what I understand).

My ideas was: To use a normally filled VB, set the View and Projection matrices properly and then transform this VB using a Matrix.Translation to the correct position.

However, I have no idea on what to set up everything to accomplish this. If possible at all... I searched from examples of textured quads, and all the examples I've seen till so far don't make use of the view and projection matrices.

Is it possible to use a VB in this setup? Or do I have to do through a lot of effort to accomplish this, and am I better of drawing the lines in a mostly transparant texture?


Share this post

Link to post
Share on other sites
Aha, I think I got it now.

As for each unit drawing it's own selection box, you could use Z-buffering, and draw all GUI items closer than the units. This would assure that a unit can't block a GUI item. This might require you to restructure your app, so it might not be the best idea.

Original post by Toolmaker
Do I need to setup a View and Project to translate it properly? And to what settings do I need to set these to have them use a 1 pixel per 1.0f unit in each Vertor3?

You're looking for some type of Ortho matrix. I'm not sure what scale they use, IIRC the scale is actually 0, 0 for top left and 1, 1 for bottom right, but conversion should be simple. Have a look at D3DXMatrixOrtho* in the SDK docs for more info.

You would then use an ortho mat for the projection, probably an identity matrix for view, and a translation matrix for world.

Keep in mind, that using such a method would require you to call DrawPrim per each selection box. This could become a problem with many units.

I can think of a nice shader workaround, if you're interested.
Other than that, it's either locking the VB to change the coords every frame, or calling DrawPrim per box. I think the first would scale better, but would likely be more difficult to get working.

Hope this helps.

Share this post

Link to post
Share on other sites
I see. How bad or slow is it to constantly call DrawPrimitive?

I was thinking: I could aswell draw textures for it, but I'm not sure how slow that will be.

As for the shader solution: How would a shader show a number of lines? If it's fast for drawing multiple of those things, go ahead and show it, it might be usefull.


Share this post

Link to post
Share on other sites
For the DIP issue, here's something from an ATI slide:
700 batches/frame @ 100% (!) 1.5GHz CPU: 50fps

This means that if you're doing 700 DIP calls, running at 50fps, on a 1.5GHz CPU, the CPU will be doing nothing other than sending batches to the GPU.

This is obviously bad. While you're not doing 700 batches yet, it might get to that at some point, and you'd be wise to avoid the possibility [smile].

For the shader solution:
The basic idea is you set up an array of points (float2s) in the shader, that represent locations on the screen. Then, you set these points up in pair that form RECTs (upper left point and lower right point). You then set up a vertex buffer with say, 4 * 100 vertices, that would turn into 100 boxes. For each vert, you give it an index into the array to use for it's X coord, and Y coord. That's pretty much it, cause when you draw, you have each vert do two lookups into the array to figure out it's location, and well, that's all you really need [smile].

You can then set up a simple index buffer to turn each 4 vertices into a box of lines, for example.

Note that with the lower shader models, you might be very limited by the number of registers you have available. It might go as low as getting 10 boxes/draw, but that would still be better than 1 box/draw and may well outperform a lock on a buffer.

With the higher models you should easily be able to push out 100 boxes/draw with no real troubles. This technique is a sort of 2D port of the 3D instancing technique. Kinda [smile].

Anyhow, hope this helps, if you need any clarifications, feel free to ask :).

Share this post

Link to post
Share on other sites
I'll try later this weekend. Tomorrow I'm moving to a new house, and the internet connection hasn't been transferred there yet, so it might take a week before I can give my reply :).

But thanks for the idea.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!