Results 1 to 10 of 121

Thread: G.T.A.2 Map Editor

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    How to properly handle key presses in game?
    After a long break i decided to take another look at adding ped(s) to map editor or any demo i work here.
    But problem is that if i detect the key pressed (either VK_LEFT or RIGHT) or whatever the ped starts moving always with some delay.

    I mean:

    1) I press the up key (forward movement)
    2) It waits for few secs and then starts moving
    3) I release the key and press again..
    4) Again it waits for 1sec or 2 and then starts moving.

    Same with rotating, first the small delay then the rotation.

    Why is that? its in nxpascal code and in my non nxpascal code.
    I have to look how i did it in nxpascal version, ie where i was reading the input..

    EDIT1:
    Ok, i found the src and i handle input in formshortcut event.
    For some reasons in old versions of my editor the gameunit keypressing code didnt work.
    Or stopped working after doing something in graphicsunit or main.pas
    I dont remember.

    How to properly handle input?

    I got the movement to work for ped, i mean with sin/cos and it walks in direction he is looking but the delay at the start of the moving/rotating is really bad.

    In the meantime i will try with fresh src from nxpascal and gameunit keyhandling.

    EDIT2: also it must always move, even if i press rotation key when he is moving. But he stops.

    In my non nxpascal demo i use form.keydown and timer with interval of 16ms.
    Thanks.

    EDIT3:
    As expected, in fresh source and gameunit keyprocessing everything is smooth and nice.
    No delays.
    So i guess keydown/keyup are not for games.


    Actually its mega smooth. Looks so great, i can rotate ped with arrows and walk around, it doesnt stop when rotating and walking at the same time.
    Just like in original game.

    What do you guys think, coldet will be able to get the collisions for me?
    The vertices are so simple and each block face is made of 2 triangles in my vertex data.
    Each slope has own vertices but because many slopes have lids, then lids are same and use same vertices, i dont share them ( i know i could to reduce my vertex data unit size even more, atm its 322KB).

    Coldet had recently a update with useful example.

    Probably not all the blocks on whole map must be checked but only those that are near to the ped. But since my visible are of map is just 15x15 (x,y) blocks + Z maximum 8 blocks i probably could check all these blocks in visible range.
    I dont care about speed atm, i just want quick and dirty to test, if it works, then i will try to make it better.

    It will never probably be full game, i just want to walk around and have collisions.
    Last edited by hwnd; 20-08-2013 at 08:19 PM.

  2. #2
    Quote Originally Posted by hwnd View Post
    So i guess keydown/keyup are not for games.
    That is right. Using OnKeyDown and OnKeyUp is not good idea for games as it relies on Wndows messages. And since redrawing of the window which is in the end also done using Windows message which has much higher priority it means that the OnKeyDown/OnKeyUp messages gets processed much later.

    Most game engines register their own Keyboard hook (catch key presses on system level - even before Windows message for key press is generated and sent to active application) which alows you to handle the key presses with your own system which doesn't necessarly relies on Windows messages.
    Actually using keyboard hook you could cause huge havoc on the computer as you can force system to generate wrong Windows messages for key presses.

  3. #3
    OnKeyDown or OnKeyUp are fast enough for games. It is the only method i've ever used for key handling, and i have never seen any lag. If you can show code or something, we could check where the real slowdown is. As you said yourself, you didn't have the problem until you changed something small in code.

  4. #4
    What could be the reason for slow rendering?
    I mean i cant render over 14x14 tiles (i disabled everything else) just rendering lid faces with vertex arrays.
    Its smooth and very low cpu usage with 14x14 range (14 blocks in X and 14 blocks in Y direction). And of course Z, which can have max 7 tiles (layers), i only draw if layer block is textured.

    But if i try to render even more cpu usage gets higher and higher.
    Dunno if octree could help but what else could i try?

    How to render more with 0 or very low cpu usage?
    Original editor has always 0 cpu usage, only when you change block or move mouse or rotate the scene it gets a bit higher and after that its 0 again.
    Dunno how they did it. Its 1998 VC++ MFC app and DirectX.

    I used SetFrameInterval(33) in game.create;

    I used Sampling Profiler for Delphi and it shows that DrawBlock function is the slowest.
    There i just draw all the faces.
    OpenGL state changes are also there. Like glEnableClientState etc..

    Edit: actually even slower function is the function that calculates the UV coords for tiles (95.5%).
    I only hard coded default rotation/tile coords. Rest is calculated. Here i guess some kind of "lookup table" would help ?
    This function is called for every block and every face.
    Basically "each frame".

    Any ideas how to speed different things up?
    Last edited by hwnd; 24-08-2013 at 09:28 PM.

  5. #5
    Quote Originally Posted by hwnd View Post
    How to render more with 0 or very low cpu usage?
    Original editor has always 0 cpu usage, only when you change block or move mouse or rotate the scene it gets a bit higher and after that its 0 again.
    I would gues that they might be rendering the whole scene into some chached texture and then finally rendering that texture to the screen.
    By doing so they need to recreate the sceene only when there has been some change done to the map or when you change your viewport. This could save lots of computational time.

  6. #6
    Hmm, i am familiar with caching textures but how is rendering to cache done?
    I dont need code but just some tips how i could do it.

    I looked again, it renders area of 23x23 tiles and CPU is 0. I cant render over 15x15 when cpu gets already used. Strange. And i render only LIDs, for debugging purposes i disabled every other face.


    I love how original editor uses resources, only when needed. It seems also it updates its cache when user modifies map, i mean when you change slope type from combobox then slope gets changed visually only when you click on map.

    And it uses only around 28MB of memory, where my editor takes over 100MB because i use the whole 3D array of [8,256,256]. They also optimized that somehow. Only rendering specific blocks or just cache. Maybe they dont even use so big array at once but just parts of it and modify array at runtime (just the modified chunks).

    Too bad they dont want to release the old stone age but useful code (just ignoring requests).

    Lots of things. I have lot to improve. 100MB is too much i think.
    I was thinking about display list but it also must be managed somehow, because its editor, blocks gets changed and if i dont update display list after modification, then the changes wont be displayed. But changes must be immediate and i have read that updating display list often kills the performance.



    EDIT:
    Ok i used gDEBugger now and it shows clearly that i have too many OpenGL calls:
    8910 calls per frame in my example. FPS is ~30, because i set it to this.
    The bar in gDEBugger is almost red, the top caption says there 10K.
    So i guess 10000 frames is max and anything over that is "crazy".
    If i have ~9000 calls and its in red area then its too much

    Is ~9000 too much or not? I guess it is. I dont know, because i dont know how much normal application would use.


    If i remove all draw commands CPU usage goes to 0.
    I have to look at my code how to reduce the calls.

    EDIT2:

    I pinpointed where my primary resource eater is.
    This is it. Thats the way i draw blocks (position them):
    Code:
        for ii:=y1 to y2 do
        for jj:=x1 to x2 do
        begin
          glPushMatrix();
          glTranslatef( 1.0 * jj, 0.0, 1.0 * ii );
          for zz:= 0 to 7 do
          begin
             Inc(scene_rendered_blocks);
             glPushMatrix;         
    
              // Render all here!
               DrawBlock(gmp.makecoord(ii,jj,zz), gmp.maparray[gmp.makecoord(ii,jj,zz)]);
    
              glPopMatrix();
            glTranslatef( 0.0, 1.0, 0.0 );
          end;
          glPopMatrix();
        end;
    x1-x2, y1-y2 are the 15x15 range.

    Started to comment out different things and this is the place i get highest cpu usage and i looked in gDEBugger that they are called alot.
    glTranslatef and glPushPopMatrix are the primary things that eat my cpu.
    Im not surprised anymore if i increase 15x15 area the cpu goes up.

    I know in C++ we have CML and GLM to get rid of these commands and use library functions but is there similar things for Delphi?

    There must be way to draw cubes / things in correct coords without glTranslatef and glPushPopMatrix.

    In the meantime i will try same thing in C++ with CML or something.
    To see how it looks and how it eats cpu using third party lib.
    Last edited by hwnd; 25-08-2013 at 09:36 AM.

  7. #7
    You could change your DrawBlock function to
    DrawBlock(ii, jj, zz);
    then do all the glTranslatef() stuff inside it (no matrix operations at all would be in these for loops then). Also multiplying with 1.0 does nothing I'm not sure compiler is smart enough to remove it, maybe if you put all optimizations on.

    I'm also guessing that loop further bottlenecks the performance inside DrawBlock().
    Last edited by User137; 25-08-2013 at 02:37 PM.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •