Thread: Setting up 2D game (VIEW)

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    73

    Setting up 2D game (VIEW)

    Just wondering if I'm setting up my Projection matrix correctly for a 2D game.

    I would like the top left of my screen to be (0, 0). Below is the code I am using.

    Code:
    	
    D3DXMATRIX Ortho2D;	
    D3DXMATRIX Identity;
    	
    D3DXMatrixOrthoLH(&Ortho2D, 640, 480, 0.0f, 1.0f);
    D3DXMatrixIdentity(&Identity);
    
    g_Direct3dDevice->SetTransform(D3DTS_PROJECTION, &Ortho2D);
    g_Direct3dDevice->SetTransform(D3DTS_WORLD, &Identity);
    g_Direct3dDevice->SetTransform(D3DTS_VIEW, &Identity);
    Thinking something is off because when I draw to the screen the coordinates I need to input for my sprite seem odd.

    Code:
    g_Background->Begin(D3DXSPRITE_OBJECTSPACE);
    
    D3DXVECTOR3 center = D3DXVECTOR3(320, 240, 0);
    D3DXVECTOR3 position = D3DXVECTOR3(0, 0, 0);
    g_Background->Draw(g_MainMenu, NULL, &center, &position, 0xFFFFFFFF);
    .bmp 640x480.

    g_Background is ID3DXSprite. I would think if I wanted to draw my sprite to the upper left.... the center and position vectors would both be (0, 0, 0). Maybe just the way the ID3DXSprite is drawn is confusing me.

    Oh yeah my image is being drawn upside down. At first I thought it was because bitmaps store their data upside down, but I tried re-saving as .tga and still its upside down ? huh?
    Code:
    D3DXMatrixOrthoLH(&Ortho2D, 640, 480, 0.0f, 1.0f);
    Code:
    D3DXMatrixOrthoLH(&Ortho2D, 640, -480, 0.0f, 1.0f);
    Change to negative and all works fine, but that doesn't seem kosher to me.. is this the proper way to do things?
    Last edited by Deo; 06-04-2005 at 08:13 PM.

  2. #2
    ---
    Join Date
    May 2004
    Posts
    1,379
    Don't your near and far clipping planes need to be further apart? (Probably has nothing to do with your problem though)

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    i dont think so, hes drawing 2d instead of 3d, so why would he even need a near/far clipping plane?

    oh and btw, heres the code i used to set the position of a sprite:

    Code:
    D3DMATRIX matPosition;
    float fx, fy;
    
    fx = (float)x - (m_nScreenWidth / 2);
    fy = (float)y - ((m_nScreenHeight / 2) - m_nHeight); //m_nHeight is the height of the sprite
    
    D3DXMatrixTranslation(&matPosition, fx, -fy, 0.0f);
    and the negative thing is fine

    edit [just incase you needed a bit more explaining for the code above]

    x, y: coords of where you want to put the sprite
    m_nscreenwidth, m_nscreenheight: self explanatory
    Last edited by X PaYnE X; 06-07-2005 at 07:30 AM.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    To rotate you must rotate from the center of the sprite. Without setting the position with ID3DXSprite, it will use the upper left corner which produces some odd results.

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    To rotate you must rotate from the center of the sprite. Without setting the position with ID3DXSprite, it will use the upper left corner which produces some odd results.

    The clip plane does not matter. BTW in Direct3D even though we may set the clip planes to 1.0f and 600.0f - Direct3D normalizes these so that all values will fall between 0.0f and 1.0f. But there really isn't a need for clip planes in this type of 2D game. The only thing you must remember to do is turn OFF the zbuffer. It has been my experience that many many video card drivers have the zbuffer on by default and not off. This will result in nothing being drawn since most certainly everything will fail the zbuffer test because there is no transformation and in fact no z coordinate at all.

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    Code:
    D3DXMATRIX matIdentity, matOrtho; 
    
    D3DXMatrixIdentity(&matIdentity);
    D3DXMatrixOrthoLH(&matOrtho, (float)m_nScreenWidth, (float)m_nScreenHeight, 0.0f, 1.0f);
    
    m_pD3DDevice->SetTransform(D3DTS_VIEW, &matIdentity);
    m_pD3DDevice->SetTransform(D3DTS_WORLD, &matPosition); //from my previous post
    m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matOrtho);
    
    m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, false);
    call that before you render and it should work fine.

  7. #7
    Registered User
    Join Date
    May 2005
    Posts
    73
    Thnx for all the help guys... will take it to note and try your implementation X PaYnE X

    As for the Z-buffer? I shouldn't use it in a 2D game? I figured I would place my sprites on different z-planes if I wanted them drawn on different layers.

    I.e. Background sprites on farther back z-planes. No good?

    Or will Direct3D handle it automatically by the order in which I draw them?

    Ex:
    Code:
    background->Draw();
    clouds->Draw();
    airplane->Draw();

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    As for the Z-buffer? I shouldn't use it in a 2D game?
    Since you define your FVF for 2D vertexes as D3DFVF_XYZRHW which in turn means that Direct3D will NOT run your vertices down the transformation and lighting pipeline.....then how do you suppose it even has a z coordinate to store in the z buffer? It doesn't.

    If you define your FVF as D3DFVF_XYZRHW, the Z-Buffer is useless.

    Code:
    struct TLVertex
    {
      D3DXVECTOR3 Position;
      float rhw;
      D3DCOLOR Diffuse;
      float u,v;
      static const DWORD FVF;
    }
    
    
    const DWORD TLVertex::FVF=D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
    This is a standard pre-lit 2D vertex. All vertices are assumed to be in screen space - that is they are drawn exactly at the coordinates you place in Position.x and Position.y, just as if you were making a simple 2D game with x,y coordinates for each object.

    Note that doing transformations on any object created with these types of vertices will NOT transform the object when you call Device->SetTransform().

    For instance with the above vertex declaration this code does not scale nor translate the object being rendered.

    Code:
    void Object::Render(float fTimeDelta)
    {
      D3DXMATRIX Scale;
      D3DXMatrixScaling(&Scale,2.0f,2.0f,2.0f);
    
      D3DXMATRIX Trans;
      D3DXMatrixTranslation(&Trans,0.0f,0.0f,100.0f);
    
      D3DXMATRIX World=Trans*Scale;
    
      Device->SetTransform(D3DTS_WORLD,&World);
    
      if (FAILED(Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2)))
      {
          LogFile.FileStream << "Object::Render() - Draw Primitive FAILED" << endl;
      }
    }
    Note that DrawPrimitive will not fail, it just will not render any changes to the object. The object will be drawn as if the translation and scaling had never been applied, because in fact, they haven't.
    Last edited by VirtualAce; 06-08-2005 at 07:26 AM.

  9. #9
    Registered User
    Join Date
    May 2005
    Posts
    73
    Since you define your FVF for 2D vertexes as D3DFVF_XYZRHW which in turn means that Direct3D will NOT run your vertices down the transformation and lighting pipeline.....then how do you suppose it even has a z coordinate to store in the z buffer? It doesn't.

    If you define your FVF as D3DFVF_XYZRHW, the Z-Buffer is useless.
    Ok. Then my question is what if I don't define my FVF? I'm not manually drawing primitives in my code. Thus I don't have a custom vertex struct or a vertex buffer. Instead of drawing primitives with textures applied to them using D3DFVF_XYZRHW I am using a predefined class shipped with SDK called LPD3DXSPRITE.

    I really have no idea how this CLASS implements itself, but it seems nice so I decided to use it.

    Code:
    LPD3DXSPRITE m_Sprite;
    D3DXCreateSprite(device, &m_Sprite);
    m_Sprite->Begin(D3DXSPRITE_OBJECTSPACE);
    
    m_Sprite->Draw(m_Texture->GetTexture(),	&temp->frameBoundary, &temp->center,	&position, 0xFFFFFFFF);
    	
    m_Sprite->End();
    I cannot use the Z-Buffer in this case? Say if I set position as (0, 0, 10)..? Or is z-coord. ignored?

    Thnx for the info on transforms of D3DFVF_XYZRHW. I wasn't aware that you couldn't scale or transform.

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    ID3DXSprite does use the ZBuffer. However in 2d games this is not an issue.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 2d game
    By JordanCason in forum Game Programming
    Replies: 5
    Last Post: 12-08-2007, 10:08 PM
  2. cross platform 2d game questions
    By tuseroni in forum Linux Programming
    Replies: 3
    Last Post: 05-31-2006, 04:13 PM
  3. beach bar (sims type game)
    By DrKillPatient in forum Game Programming
    Replies: 1
    Last Post: 03-06-2006, 01:32 PM
  4. 2D Tile Based Game
    By cboard_member in forum Game Programming
    Replies: 6
    Last Post: 07-29-2005, 01:04 AM
  5. My Memory Game
    By jazy921 in forum C Programming
    Replies: 0
    Last Post: 05-05-2003, 05:13 PM