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
    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.

  2. #2
    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.

  3. #3
    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.

  4. #4
    Multiplying by 1 actually does hard work. It positions all the blocks side by side. If i remove it all blocks are on top of each other.
    One idea i had is to use some list with all blocks already with correct X,Y,Z coords translated mathematically and just let opengl draw them. Just a rough idea. I still will need gltranslate i guess, dunno.


    And i found now that displaylist increased performance alot.
    33% CPU with area of 33x33, using vertex arrays and drawing only lids.

    With 23x23 its around 3-7% which is fine for me.

    Now i need some ideas, how to rebuild display list after map array modification so it will render the changes?
    Just gldeletelists and create new list after each mouse map manipulation?

    Edit:
    my idea, have some list (vector, tlist) with all the needed blocks and coordinates. If user modifies block it will get added / removed / modified. And make_displaylist function just loops through all these blocks and positions them.
    And in draw() i just call that list.

    If i modify map, again loop through block list and make new display list.
    Dunno if it will work.
    Last edited by hwnd; 25-08-2013 at 03:49 PM.

  5. #5
    Try TDisplayList on nxPascal maybe, it's designed for easy updates and stuff. You could have 1 displaylist for each chunk, to minimize performance impact on updating just certain part. (I mean map could be divided in like 8x8x8 block sections or something, not displaylist for each individual block)

    glTranslatef( 1.0 * jj, 0.0, 1.0 * ii );
    is same as
    glTranslatef( jj, 0.0, ii );

    Also if you are using nx models with Render(initialize: boolean) procedure, you could try doing the initialization manually if you repeatedly render same block. You just have to keep track on when model changes and initialize new one when needed. I'm right about to do that optimization on my pgd game entry right now. Related functions are model.SetPointers, EnableStates and DisableStates.

    edit: It came down to:
    Code:
              if _otype^.model<>lastModel then begin
                model[_otype^.model].SetPointers;
                lastModel:=_otype^.model;
              end;
              model[_otype^.model].Render(false);
    I enable model[0] states at beginning of loop, and disable states at end. States are same for all models here so they don't need to change inside the loop. However i didn't gain FPS boost so it's back to drawing board.

    edit2: My issue was in materials. I've updated nxPascal SVN because of change to material handling. Because my models have flat faces they were all in unique groups. Therefore it changed material for every face... not anymore.
    Last edited by User137; 25-08-2013 at 05:01 PM.

  6. #6
    Like i said a while ago, i was unable to make models for my editor so it was easier to create vertex data by hand and just use opengl calls to render them. I would use model structure but only if i can port my vertex data for all 63 slopes to your model struct.
    So atm, no nxmodels are used. I should try make model from 0 in code again, it was long time ago, when i tried. I even have your private messages where you tried to help, i will have to look. I remember also that i got blank screen, i didnt fill all needed things up i guess.
    EDIT: ahh, it needed some indices or something, this is were i got stuck. I was too lazy to create these, i have 63 slopes, it will be pain i think. Dunno. Will try.

    I will look at the TDisplayList.
    Last edited by hwnd; 25-08-2013 at 04:33 PM.

  7. #7
    Strange thing is that on my current PC (not laptop) i have no CPU usage on map editor, all faces are drawn.
    But in my laptop which only has 16MB of video memory, it uses CPU, not alot but around 20-30 depends...

    If video mem is too low for gfx app this means Windows or something makes the app to use CPU also?


    And another question.
    Atm, i have lots of repeated vertex coords for all the slopes (blocks). The unit file size is 322KB. I was able to reduce it to this size with help of User137. Gave me great suggestions. Before that it was something like 1.6MB or something.

    I would like to make it even more smaller.
    And was thinking about only use unique vertex coords. Many blocks that need same vertex, is pointed to one vertex, so one vertex is not duplicated for each block that needs it.

    And also use glDrawElements, and maybe even interleaved arrays.
    Drawelements is in core from v1.1, so shouldnt be a problem on old hardware.


    Will this speed up my rendering also a bit?

    Here is example, how some vertex data is linked / pointed to other array element.
    http://pastebin.com/jpGTg9b3

    Copy/paste from TRSI lighting example.
    Last edited by hwnd; 10-09-2013 at 08:17 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
  •