Programming 2D Games

The official forum for "Programming 2D Games" the book by: Charles Kelly

It is currently Fri Feb 28, 2020 8:52 am

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Sun Feb 09, 2014 11:44 am 
Offline

Joined: Mon Dec 23, 2013 1:40 am
Posts: 37
Hi Professor Kelly,

I am up to adding some textures into my directx11 engine based on your code. I have edited some sample Microsoft code to simply create a textured quad in the middle of my screen. I now want to adapt this code to be the 'walls' in my game.

As far as I understand each texture has to be mapped onto a quad. In your engine I see the drawQuad() function defined in graphics.h, but I can't see where it comes into play when you draw your sprites (only for the buttons and console). Any clarification on these points would be appreciated:

1. is the purpose of gameTextures.initialize(graphics,TEXTURES_IMAGE) to load the sprite sheet into video memory so each sprite can be later selected. Is this faster or a better way than to have a separate image file for each individual component eg one for the planet in the center, one for the ships, one for the explosions?

2. After gameTextures are initlized, you then initialize the individual components of the game. When you call

Code:
planet.initialize(this, planetNS::WIDTH, planetNS::HEIGHT, 2, &gameTextures)


how does planet 'know' that it is the planet? I cant quite see where you have extracted the top right section of pixels which compromise the planet and called them 'planet'.

3. Where does the quad come into this? I cant see it be drawn to have the planet or spaceship texture mapped to it. Or is it a different way that directX 9 draws sprites compared to directX 11?

Thank you for your time and this wonderful book / source code.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 14, 2014 9:49 pm 
Offline
Site Admin
User avatar

Joined: Sat Jan 28, 2012 4:36 pm
Posts: 554
SteveHatcher wrote:
As far as I understand each texture has to be mapped onto a quad. In your engine I see the drawQuad() function defined in graphics.h, but I can't see where it comes into play when you draw your sprites (only for the buttons and console). Any clarification on these points would be appreciated:
DirectX9 has its own sprite class that I use in the engine. The sprite object pointer is created in graphics.h with the code
Code:
    LP_SPRITE   sprite;
The DirectX sprite is created in Graphics::Initialize
Code:
    result = D3DXCreateSprite(device3d, &sprite);
This is the sprite used by the Image class for all drawing. The console and dialog boxes use the quad.
SteveHatcher wrote:
1. is the purpose of gameTextures.initialize(graphics,TEXTURES_IMAGE) to load the sprite sheet into video memory so each sprite can be later selected. Is this faster or a better way than to have a separate image file for each individual component eg one for the planet in the center, one for the ships, one for the explosions?
Yes, gameTextures is a TextureManager object that is responsible for loading the texture files. It also contains functions that may be used to release and reload the textures to recover from losing control of the graphics card. There is no difference in speed when using individual sprite textures or a large sprite sheet that contains multiple textures. Using individual textures is better for tiled images that move on the screen. See this topic for more: http://www.programming2dgames.com/forum/viewtopic.php?f=6&t=18&hilit=tile
SteveHatcher wrote:
2. After gameTextures are initialized, you then initialize the individual components of the game. When you call
Code:
planet.initialize(this, planetNS::WIDTH, planetNS::HEIGHT, 2, &gameTextures)
how does planet 'know' that it is the planet? I cant quite see where you have extracted the top right section of pixels which compromise the planet and called them 'planet'.
The planet.cpp file's constructor contains the following code that sets the texture to the planet:
Code:
    startFrame      = planetNS::START_FRAME;    // first frame of ship animation
    endFrame        = planetNS::END_FRAME;      // last frame of ship animation
    setCurrentFrame(startFrame);
The Image class needs to know the size of the individual texture, how big the entire texture sheet is, and how many columns of textures are in the sheet. It uses that information along with the frame information to calculate the rectangular portion of the texture sheet to apply to the sprite. The Image::setRect() function does the calculation.

P.S. I'm glad you like the book.

_________________
Professor Kelly


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 19, 2014 12:37 pm 
Offline

Joined: Mon Dec 23, 2013 1:40 am
Posts: 37
Thanks for the detailed reply.

profkelly wrote:
DirectX9 has its own sprite class that I use in the engine.


I cant find anything like this for DX11. So does the DX9 sprite class not require any of the setup that DX11 needs (such as the InputLayout, the quad vertices which the texture will be mapped to, SamplerState, ShaderResourceView etc...). It seems there is quite a big difference between DX9 and DX11.

profkelly wrote:
Yes, gameTextures is a TextureManager object that is responsible for loading the texture files. It also contains functions that may be used to release and reload the textures to recover from losing control of the graphics card. There is no difference in speed when using individual sprite textures or a large sprite sheet that contains multiple textures. Using individual textures is better for tiled images that move on the screen.


Great. So its up to the programmer how to split up the game art. Eg depending on the scale of the game, there could be a sheet for just land, a sheet for player interactions, a sheet for enemies etc...

profkelly wrote:
The planet.cpp file's constructor contains the following code that sets the texture to the planet:
...
The Image class needs to know the size of the individual texture, how big the entire texture sheet is, and how many columns of textures are in the sheet. It uses that information along with the frame information to calculate the rectangular portion of the texture sheet to apply to the sprite. The Image::setRect() function does the calculation.


So the sprite sheet gets divided up into appropriate squares and played back depending if there is an animation or not. This is a very neat way of doing things. So for DX11, I will need to implement my own sprite class which sets up the buffers accordingly it seems. I will have a go.

Thanks again


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 20, 2014 10:00 pm 
Offline
Site Admin
User avatar

Joined: Sat Jan 28, 2012 4:36 pm
Posts: 554
A Google search will reveal several examples of creating sprites in DX11. Some use HLSL and some use textured quads.

FYI, there is no advantage in using DX11, in fact it will limit the target audience of your game. I assume you are doing this as an exercise or for some other reason.

I'm happy to help if I can.

_________________
Professor Kelly


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 22, 2014 3:08 am 
Offline

Joined: Mon Dec 23, 2013 1:40 am
Posts: 37
Hi Prof,

I found a Microsoft example that uses textured quads so I will stick with that for now, as I am still not very familiar with HLSL.

I had started work on a DX11 engine before I found your book, and since your book already has the framework of DX9 code there would not be too much for me to do, so rather than copying and pasting sections to make my own game, I think it as a good idea to continue using DX11 so I understand the actual fundamentals of the graphics drawing protocol.

Thanks


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 25, 2014 9:38 am 
Offline

Joined: Mon Dec 23, 2013 1:40 am
Posts: 37
Hi professor,

I am trying to re-create your kind of sprite drawing procedure in DX11 (As I am sure you know by now...).

I somewhat understand your procedure in DX9 but because the sprite drawing system is so different in DX11 this wont be so easy. Using your input sprite sheet I have converted it to a .dds and load it using CreateDDSTextureFromFile(). To Initialize the planet I then draw a quad with the textures U and V co-ordinates selected to only map the planet onto the quad. This is done as:

Code:
   SimpleVertex vertices[] =
   {
      { XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.5f, 0.5f) },
      { XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.5f, 0.0f) },
      { XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 0.5f) },
      { XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f) },
   };


Where the U V co-ordinates are normalized to 1, so 0.5 is 128 and 1 is 256 (since the planet is lives from pixel 128 to 256 in the x and y direction). This seems to work (still figuring out transparency), but I am wondering if you would know of another / better way to do it. It seems like there is the Map() and CreateTexture2D() functions for things like this but I cant fully understand them without seeing an example, and googling has not been very helpful.

Thanks for your time.

P.S I am not sure how much DX11 you know so I am happy to keep questions based around your book and engine in the future if you wish.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 28, 2014 1:40 pm 
Offline
Site Admin
User avatar

Joined: Sat Jan 28, 2012 4:36 pm
Posts: 554
A sprite is essentially a textured quad that always faces the screen. This is referred to as a billboard. There are a number of online tutorials that have example code. I did a Google search and pulled this from the results. I have not verified the accuracy of the code but it looks reasonable.
http://www.rastertek.com/dx11tut34.html

_________________
Professor Kelly


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 02, 2014 3:29 am 
Offline

Joined: Mon Dec 23, 2013 1:40 am
Posts: 37
Hi Professor,

Thanks, that site has some good examples. The biggest problem with internet resources I have come across is they are so damn hard to understand.

Your book is the best combination of well written, understandable C++ combined with directX that exists in my opinion.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 02, 2014 3:28 pm 
Offline
Site Admin
User avatar

Joined: Sat Jan 28, 2012 4:36 pm
Posts: 554
SteveHatcher wrote:
Hi Professor,
Thanks, that site has some good examples. The biggest problem with internet resources I have come across is they are so damn hard to understand.
I agree. I would like to provide my own example code to answer all of the forum questions but I just don't have enough time.
SteveHatcher wrote:
Your book is the best combination of well written, understandable C++ combined with directX that exists in my opinion.
Thank you very much.

_________________
Professor Kelly


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


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 post attachments in this forum

Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group