Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

2D in Direct3D tutorial

Post new topic   Reply to topic    Cheat Engine Forum Index -> Game Development
View previous topic :: View next topic  
Author Message
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5802

PostPosted: Thu Sep 10, 2009 12:05 am    Post subject: 2D in Direct3D tutorial Reply with quote

Ok, I've had this written for like a week now, just sitting. Might as well post it. It's more a primer than anything before I actually get into the code, which will probably be this weekend.

Next up is (if people find this interesting enough):
- Getting D3D initialized.
- Getting something drawn.
- Getting a lot of somethings drawn and future optimizations.
- An example of a map format, maybe.

Alright, here is a quick and dirty guide on the dead simple basics of Direct3D and what to expect when using it. Direct3D is a way to interface with your video hardware in numerous ways with the ultimate goal of getting something neat displayed on your monitor. Awesome, right? Sure is, and this simple guide will hopefully be going over a few points and laying out a few key concepts of D3D as well as helping set up your first D3D program. Now, I'll just be putting out a few things to expect while reading this.

I'll try not to go into too extravagant of detail on many things, but who knows if I will get carried away or not... Smile I'll generally just be outlining the concepts of such as I know all anyone ever really wants to do is GET SOMETHING ON SCREEN. Thankfully, it is dead simple to do just that as DX provides us with a plethora of tools that enable us to do all sorts of wonderful things as well as avoiding the reinvention of the wheel. Furthermore, keep in mind that this is written with 2D in mind, and even though D3D is an API primarily meant for 3D, we can very easily coax it into providing us with glorious, hardware accelerated 2D. How will we do that? Ho ho, it's quite simple in fact.

When working with Direct X, you may see functions and headers prefixed with D3DX. These are the aptly named D3D extension functions / libraries which so just so happen to be the wonderful collection of tools and functions described before that will help us get up and running with minimal muss and fuss. Of course, nothing is stopping you from going hog wild and doing it all yourself and replacing the provided interfaces with your own, but in this case, we will find little need to do that. From the D3DX library, we will be utilizing the ID3DXSPRITE interface.

ID3DXSPRITE is basically Microsoft's answer to 2D drawing in D3D, and as such, it is what we'll be using. With Direct Draw being deprecated, something had to be done to provide, and somewhat unsurprisingly, the answer was QUADS. Now, if you have ever worked with anything 3D, I am sure the concept of quads and triangles is all too familiar, but just in case, I will be going over it here. In D3D (and OpenGL... or anything else), everything is rendered as triangles. Even if you tried to push a quad to your hardware, chances are your display driver would simply handle it for you; in fact, I am not even sure if there is any actual graphics hardware out there that will draw a straight up quad.

A quad is a rectangular set of polygons and if you can't guess by now, you can easily form a quad with 2 triangles, and from there, easily go on to form whatever shape it is you want. Perhaps the more thoughtful of you are wondering why we don't use real quads for drawing? Doesn't that mean less polygons being drawn? First off, the triangle is the basis of all 3d geometry and is the simplest of possible shapes (but not the simplest of possible primitives!). Secondly is the optimization possibilities, such as the overall vertex cost. For example, all it takes is one more vertex to add another triangle to a triangle strip. Of course, there are more reasons, but as far as I can imagine, these are the largest of problems.

Here's a nice introduction to the different types of primitives.

When rendering, the primary form of "connectivity" between your polygons is likely going to be triangle strips. (or in OpenGL, you can use quad strips for simplicity, just remember that they will be broken up into tri's by the display driver when they are actually drawn!) D3D9 does provide other methods of rendering, such as triangle lists and fans, however triangle strips are by far the most common. You will probably never find a need to use the other triangle types, ever. In fact, D3D10 completely did away with everything other than strips, so get used to it. Smile

So, how do we typically get something on screen? The first key point is that everything in D3D is made up of vertices, regardless if it's 2D or 3D. A vertex (in it's simplest form) is simply a point defined in any given space, be it 2D or 3D, however they can also bare all sorts of information such as specular or color values, texture coordinates and other fun goodies. Now, think about this for a moment, if you made a vertex at 0x, 0y, 0z where would you expect it to be? In order for the position of a vertex to have any meaning, it must be relative to some semblance of space. As such, we have the coordinate system to help direct our misguided points. The four main systems you're likely to see are as follows:

- Model Space:    Typically, 0,0,0 is relative to the center of a given model.
- World Space:   Here, 0,0,0 represents the center of the world of which you will be creating.
- Screen Space:    This matches your screen dimensions, for example: 320x240 goes 0-319 and 0-      239. Think coordinates like a graph.

Furthermore, there are transformed and untransformed vertices. A transformed vertex has no processing done on it as it exists in screen space. A 3D model will likely use untransformed vertices, however in a 2D game, it is typical to use transformed ones.

Continuing, we have to feed D3D vertices somehow, and there are two ways this can swing. First, you could use a form of immediate mode, where whatever you draw is instantly sent to the GPU. In OpenGL, this is typically not too bad, however in D3D9, draw calls and state changes are quite the vicious beast. They are stupidly expensive, and as such, you should always prioritize keeping them to a minimum. Yes, this means that changing textures (a type of state change!) all willy-nilly without a care in the world can potentially ravage your performance. We will get more into this when we actually get to the code part.

Draw calls (and state changes) are MUCH cheaper in both OpenGL and D3D10, but ultimately, the better answer to the problem is to use vertex buffers. Vertex buffers are a bunch of memory that holds information about the various vertices that you pass into it with the hopes of eventually drawing something with them. To do this, you get the joy of creating your own vertex definition, but we won't be doing that right now. Vertex buffers can be allocated in either system memory or your SAVAGELY FAST video memory. Truly, you would probably be hard pressed to ever find a reason for storing it in system memory. Basically, it boils down to this: regardless of API, if you need seriously polygon crunching power, you will be using a vertex buffer.

Secondly, comes another (but much needed, unless you are insane, for performance reasons!) buffer, the index buffer! The index buffer allows us to refer to specific points in the vertex buffer to avoid sending duplicates (verts that occupy the exact same space). Now maybe you're thinking, pff, a couple extra verts... just remember that you can easily have thousands upon thousands on screen at once and you can get quite the enormous gain from all the bandwidth saved.

This is a DEAD simple explanation of both, and I know you are probably scratching your head. So take a look here:
The illustrations should further help clarify a bit.

That's it for now. I'll get to the actual code soon enough
Back to top
View user's profile Send private message
I post too much
Reputation: 3

Joined: 17 Apr 2007
Posts: 3899

PostPosted: Sat Sep 12, 2009 7:00 pm    Post subject: Reply with quote

Good job on the guide.
I haven't really been into coding for games or much of anything visual (D3D probably wouldn't be a priority either), but it would be good to learn this type of thing and I've certainly got the time.
I'll look out for any updates if you decide to make them. This board isn't exactly well-surfed.
Back to top
View user's profile Send private message
Member of the Year
Reputation: 195

Joined: 14 Jan 2009
Posts: 1847

PostPosted: Sat Sep 12, 2009 7:20 pm    Post subject: Reply with quote

Well done, sir.
Thought I think you could add some more in depth details later.
Back to top
View user's profile Send private message
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5802

PostPosted: Sat Sep 12, 2009 8:08 pm    Post subject: Reply with quote

I will be updating it when I get un-lazy. I have most of the second part written out, just need to finish it.

Next will be setting up the D3D device and drawing a glorious blank screen of your color choice.
Back to top
View user's profile Send private message
Master Cheater
Reputation: 0

Joined: 05 Sep 2006
Posts: 378
Location: The pizza country!

PostPosted: Sun Sep 13, 2009 12:10 pm    Post subject: Reply with quote

Just a question, do you use only one instance of LPD3DXSPRITE to draw all your sprites (so you put it as a static/global variable) or better have one for each sprite?

ASM/C++ Coder
Project Speranza lead developer
Back to top
View user's profile Send private message
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5802

PostPosted: Sun Sep 13, 2009 3:40 pm    Post subject: Reply with quote

Robotex wrote:
Just a question, do you use only one instance of LPD3DXSPRITE to draw all your sprites (so you put it as a static/global variable) or better have one for each sprite?

Yes, you should only use 1 sprite interface.

Each ID3DXSPRITE::Draw call adds a sprite to it's nice little internal batch list. Draw doesn't so much draw the actual sprite as it does just create the information about it. When you call ID3DXSPRITE::End, it calls flush and ultimately draws your scene
Back to top
View user's profile Send private message
Reputation: 0

Joined: 03 May 2010
Posts: 27

PostPosted: Wed Jun 09, 2010 7:45 am    Post subject: Reply with quote

I don't really know what you mean but making a 3d game you defiantly need C++ using this you could get DarkGDK and easily learn how to program using this
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Game Development All times are GMT - 6 Hours
Page 1 of 1

Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum

Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites