Thread: Back to the drawing board

  1. #1
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607

    Back to the drawing board

    Well as most of you know I've been working on a 2D/3D tile engine in Direct3D. Unfortunately I've learned that there are several issues with my design and structure that are making it more difficult than it should be.

    So much to my chagrin, I'm trashing the code and starting over. However, I probably will keep the sound engine portion so all is not lost.

    The reason for all of this is I came across several articles concerning pixel by pixel scrolling. I already knew how to do it with one tile, but did not put two and two together to get how you do it with a tilemap.

    Well now I finally understand and I've tried it in the old DOS BC45 first. It absolutely flies. The code in DOS outperforms the DirectX which clued me in that using Direct3D for 2D might sound ok, but its really not much of a benefit. It is true you can do lighting rather easily, but its not easy to scroll since you do not control the rendering - only the grid.

    I'm going back to my DirectX module and simply getting two pointers - one to the back buffer(secondary surface) and one to the primary surface. I'm going to blit to the primary surface via assembly language because I've tested it and the assembly is faster than the hardware blitter. Don't ask me how this is possible because I simply dont know.

    I will post the game here as soon as I have a working build. Mind you that with the new algorithm I will probably have to slow it down a bit because the scrolling is so fast.

    Happy coding and thanks to those who helped me with my questions concerning the old engine.



    I'm going to attach a sample of the DOS exe with its test bitmap so that you can see what I'm talking about. This is nothing special, but I'll tell you that if you add a small bit of code to the main loop and tiles and a tilemap - along with code for multiple layers - you could very easily make a game with it.
    Last edited by VirtualAce; 02-29-2004 at 04:56 AM.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Here is the archive - it wouldn't let me attach a message after posting. Once you post, even if you edit your post, it wont let you attach files. Hmmm.

    This is very simple, just extract the zip into its own folder. The bitmap must be in the same folder as the exe.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Weeee!!!!

    That was fun!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ok, here is an updated version with mouse support. The bitmap for the mouse was not designed as a mouse cursor so it's not pixel perfect at the edges.

    Use the mouse to scroll around. You can only scroll so far in each direction. It allows you to scroll around a virtual enlarged 320x200 area. There is only 1 tile so far, but its an example of what I'm talking about.

    This also shows transparent pixels using the mouse cursor. Only the relevant pixels are rendered so the ugly square around the bitmap is not shown.

    There is 1 line of distortion at the top, but I'm not sure where its coming from.

    Press the LMB to exit.

  5. #5
    Registered User
    Join Date
    Jul 2003
    Posts
    110
    Arg I keep dieing to the ninjas...

  6. #6
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    I don't understand why you need to be so incredibly concerned with speed when using 3D accel and just simple bitmap rendering.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I'm not really Silvercoord. The problem was every time I scrolled it was nearly impossible to get the bitmaps to look right. You really need pixel by pixel control of the screen. Unfortunately when you have D3D render the tiles, you have no control over the actual pixels.

    So I scrapped the Direct3D idea and just used my scrolling algo in a DirectX environment. It works much better and it's just as fast. That is really all my point was. I posted this exe snippet simply to prove the scrolling actually works and looks very good.

    In D3D I was basically creating a tri out of each quad on the map and then selecting the texture for that quad based on the tile map. It worked beautifully until you needed to scroll the thing - because by having D3D render the tiles as quads, you are doing nothing more than reducing yourself to scrolling tile by tile instead of pixel by pixel.

    I'll give you my D3D version if ya want so you can see what I'm talking about.

  8. #8
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    I really still don't understand why you can't just render the ENTIRE world of tiles and just rotate and translate the world

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Because it is not 3D anymore. Previously I was using D3DTLVERTEX which basically tells Direct3D that the vertexes have already been pre-transformed so rotation would not have helped.

    You would have to see the code in action to understand why doing this with Direct3D is actually harder than just coding it in 2D.

  10. #10
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    hmmm, I don't know a ton about rendering with the d3d libs, but just because its 2d doesn't mean you can't use 3d. IF I was doing it with OpenGL, I'd just have a static downward looking view in 3D and I'd render the whole tilemap, and I'd just update the position to get it to scroll from side to side.

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Which would work because your using the entire rendering pipeline and what lies outside of the frustrum does not get drawn or gets clipped. But I'm not using the entire pipeline. I'm basically telling Direct3D, hey I've got some pre-transformed vertexes and here they are. Then I send the vertexes to Direct3D after I create a tri out of em, select the texture based on the camera position in the tilemap, and let D3D render the thing.

    Actually I'm rendering the pre-transformed vertices as triangle strips since it's faster but that really doesn't add weight to my argument here.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Here is the render portion of my code:

    Code:
    int TileEngine::Render(int offset_x,int offset_y)
    {
    	
      D3DTLVERTEX Vertex[4];
      Vertex[0].color=D3DRGB(1.0f,1.0f,1.0f);
      Vertex[1].color=D3DRGB(1.0f,1.0f,1.0f);
      Vertex[2].color=D3DRGB(1.0f,1.0f,1.0f);
      Vertex[3].color=D3DRGB(1.0f,1.0f,1.0f);
    	
      //Set texture coords
      Vertex[0].tu = 0.0f; 
      Vertex[0].tv = 0.0f; 
      Vertex[1].tu = 1.0f; 
      Vertex[1].tv = 0.0f; 
      Vertex[2].tu = 0.0f; 
      Vertex[2].tv = 1.0f; 
      Vertex[3].tu = 1.0f; 
      Vertex[3].tv = 1.0f;
    
      //Set rhw factors
      Vertex[0].rhw=1.0f;
      Vertex[1].rhw=1.0f;
      Vertex[2].rhw=1.0f;
      Vertex[3].rhw=1.0f;
    	
      //Tell D3D we are rending the scene
      D3DDevice->BeginScene();
      
      //Set render state
      D3DDevice->SetRenderState(D3DRENDERSTATE_FILLMODE,D3DFILL_SOLID);
    
      //Set Texture
      D3DDevice->SetTexture(0,SampleTexture->GetSurface());
    
      //Set scroll amounts
      int screen_x=offset_x;
      int screen_y=offset_y;
    
      //Set upper left corner tile to correct start in tile map
      int tile_x=(screen_x>>6),tile_y=(screen_y>>6);
      int start_tile_x=tile_x;
      
      //Iterate through height of screen
      while (screen_y<ScreenHeight)
      {
        //Iterate through width of screen; account for offset for scrolling
        screen_x=-offset_x;
        while (screen_x<ScreenWidth)
        {
          //Make a 2 tris at current screenx,screeny
          //Quite simply, a quad
          Vertex[0].dvSX=screen_x;
          Vertex[0].dvSY=screen_y;
          Vertex[1].dvSX=screen_x+64;
          Vertex[1].dvSY=screen_y;
          Vertex[2].dvSX=screen_x;
          Vertex[2].dvSY=screen_y+64;
          Vertex[3].dvSX=screen_x+64;
          Vertex[3].dvSY=screen_y+64;
    
          //Draw the quad as a trianglestrip
          //Specify to Direct3D this is a D3DTLVERTEX
          //No transformation performed by D3D
          D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
    			 D3DFVF_TLVERTEX,
    			 Vertex,
    			 4,
    			 0);
         
          //Increment screen_x by width of tile
          screen_x+=64;
         
          //Increment position in tile map by one tile
          tile_x++;
        }
        //Move down one row in tile map
        tile_y++;
        
        //Reset tile_x to left side of viewable tile map
        tile_x=start_tile_x;
        //Increment screen_y by height of one tile
        screen_y+=64;
      }
       //Tell D3D we are done
       D3DDevice->EndScene();
    
       
       return(0);
    }
    The problem is that with my method, offset_x will often times be within the visible screen which cause the entire grid to be drawn from that point. This causes blank tiles at the edges of the screen.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Going back....Way back
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 51
    Last Post: 06-05-2008, 10:43 AM
  2. Slow drawing code
    By tjpanda in forum Windows Programming
    Replies: 5
    Last Post: 05-09-2008, 05:09 PM
  3. Projects board
    By VirtualAce in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 12-13-2004, 09:33 AM
  4. Board back online
    By webmaster in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 08-08-2002, 10:16 PM