Page 1 of 2 12 LastLast
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
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    NPOT : No need to re-scale the image or anything like that in order to support NPOT textures, just simply create an image which snaps to the next largest power of two size on both axis, then load your image data into the 0,0 corner and then rescale your texture co-ordinates by the ratio of the new NPOT image size to the Original image size. You waste some texture memory but it's quicker to load the textures (As you don't need to scale them). If all the GTA2 textures are loaded on map startup and nothing is streamed during gameplay, you may as well rescale like you are in order to save wasting memory.

    EDIT : totally ignore that, if you're scaling the images for POT anyway then you won't use any more GPU memory using the method I suggested. it'll be quicker than scaling and you won't have a DevIL (or other image lib) dependancy.

    A Texture atlas would let you save memory and would also be faster when rendering (less texture switching) it's really easy, for the first image you create the biggest texture you can for your hardware (256x256 should be fine for example) and load it into the top corner, then return that images GL_ID and the texture coords that are used. Then for each sucessive image you 'search' your available space in your 'texture atlas' for a clear spot that your image will fit in (so look at the dimensions of existing images, itterating along X and Y until you've found some free space) then copy your image data there, then return the coords that were found for use for the new reference.

    If your search doesn't find a space big enough for the image due to all the other images, you just create another big texture in GL and start the process all over again.

    The end result is a handfull of big textures with all your small textures splattered across them and all your material/texture references are to these images and coord offsets to the actual image data you want.

    There's all kinds of ways of doing it, different optimizations to use etc but the basic principal is sound. Look at light-map construction in a BSP map loader for an example, you can also read up on the design of ID Software's mega-texturing implementation in RAGE. Essentially the same technique but creates super large images in system memory, portions of which are copied to GPU memory when needed. RAGE (tech 5 or whatever) has algorithms (at map compile stage) that try to group required textures together in the mega-texture so when the 'atlas' portion is copied to a normal texture you're using most of the sub-textures for the on-screen geometry. They probably use visbility determination, portals etc as part of the algorithm to optimize the grouping of sub-textures.
    Last edited by phibermon; 30-03-2013 at 06:03 PM.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

  2. #2
    Thank your for your reply. Yes i got 2 good examples actually which create opengl texture from npot bitmaps, one is that DevIL and one is with SDL. They load texture fine but biggest problem for me now is rendering quad which has the newly created texture centered exactly on the quad.

    I even did a simple example with crosshair on screen and rotated the quad on center and then i discovered that texture is not actually centered on the quad.

    The quad itself was "perfect", npot texture was also OK but texture had offset on the quad. But in my case the npot texture must be exactly centered on the quad.

    So have discovered that im unable to center the texture on quad. As you said: "rescale your texture co-ordinates by the ratio of the new NPOT image size to the Original image size"

    I don't care about memory atm, i need to make it work first.

    Im now even unable to find the example i wanted to show you, how the texture is not centered.
    I was so disappointed. I thought i got it finally working but no, again some bug or problem.

    But i would like to make it work. I will at least learn something from it.
    I will try to find the example i made and post a screenshot later.


    EDIT
    It should be like in image B, but atm its like A. Which is bad!
    It should be centered perfectly like in image B.
    Original texture size is 32x18





    By ratio you mean in this case 32 / 32 and 18 / 32 ?

    Since next POT for 32 is 32 (unchanged in this case) and for 18 it's 32.


    Here is the way im doing atm:
    Code:
     
    var texTop, texbottom, texleft, texright:single;
    w,h:Single;
    
    
      texTop:=0; // This shouldnt be 0 i think, must be calculated?
      texleft:=0; // This shouldnt be 0 i think, must be calculated?
      texbottom:=th /getnextpot(th);
      texright:=tw / getnextpot(tw);
    
    
      w:=tw/64;
      h:=th/64;
    
    
    
    
    
    glBegin( GL_QUADS );
             // Top-left vertex (corner)
             glTexCoord2f( texLeft,    texTop ); glVertex3f( -w/2, -h/2, 0 );
    
             // Bottom-left vertex (corner)
             glTexCoord2f( texRight,    texTop); glVertex3f( w/2, -h/2, 0 );
    
             // Bottom-right vertex (corner)
             glTexCoord2f(  texRight, texBottom); glVertex3f( w/2, h/2, 0 );
    
             // Top-right vertex (corner)
             glTexCoord2f(texLeft, texBottom); glVertex3f( -w/2, h/2, 0 );
    
       glEnd();
    If i modify either texTop and / or texLeft then i can move texture to center.
    But then it looks pretty bad, like squeezed together a bit or something.

    "tw" and "th" are NPOT image width and height, assigned on image loading!
    In this case they contain: 32 and 18.

    This code causes things look like in image A.

    I divide by 64 because every tile in GTA2 is 64x64. Main gfx. Every object like this roadblock is placed on the tiles of size 64x64.

    It seems everything should be calculated. But whats the correct math?
    I will try to find some example on net.

    Texture centering is the only problem atm.
    Last edited by hwnd; 31-03-2013 at 01:51 PM.

  3. #3
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    Ok, that should actually work, your understanding is correct. however if you're getting A with that exact code then there's somthing else at play here, whilst implementing this solution I assume you turned off the image scaling you previously implemented?

    Step thru it with your debugger, Ensure that just before your GL_QUADS call that texbottom and texright are what they are supposed to be, in this example texbottom should be 1 and texright should be 0.56.

    I can assure you that an image of 18x32, stored in a GL texture of 32x32 (none scaled, origin at 0,0) rendered with tex coords (0,0) (0.56,1.0) would be mapped onto your quad of any size. if your source image was red with a 1 pixel blue border, you'd see that blue border tight against every quad edge.

    (A) is exactly what you'd get if you loaded a 18x32 image into a 32x32 texture and rendered with tex coords of (0,0)(1,1) you'd have a 'gap' along one side where the X coord of 1 (Which should be 0.56) is causing the unused part of the texture to be rendered, 'squashing' the original texture (not offset as it appears) so that it's mapped across 0.44 of the width of the quad.

    Debug this exact example, ensure that texright=0.56, if it's right then that is very strange indeed, let me know and I'll do my best to help, if needed I'll make you a GL1.x example you can use as a reference
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

  4. #4
    Ok, here is the image i use for testing.




    As you see it already as offset. But how GTA2 centers them anyway then?
    It must somehow compensate that offset.

    One idea i had is to go thru the image, ignore all black pixels and center rest of the image in new image. Black pixels in GTA2 are always used for transparency.
    So i can ignore them. But such image processing will slow things down i guess.
    I dont know.

    I want to rotate these things around, thats why it must be centered, if its not then it will look ugly when rotating and it will do it not correctly. For just moving around the offset doesnt matter for me.

    OK, very "hacky" solution is ignore all this and leave it as is and just rotate and move as needed. If rotation with offset moves sprite away from correct position on map then just move it back. Not very good but if i will give up i will do it.

    Seems the code im using is used widely:
    http://gitorious.org/racr/mainline/b...c/r_opengl.cpp

    So it's not the code but actual GTA2 sprites that are done in so stupid way.


    I have a c++ code from friend who created texture atlas with all sprites packed together in 2048x2048 sheet. Just like you suggested.
    All the odd sizes of sprites in it, directly from GTA2 files and he uses them with no problems.
    Automatic uv coord generation etc. Dunno exactly what he does there.

    Have to ask or look at the source more closely. I could do this already but i thought i will get it work in simpler way. His code is not easy one.

    For some reason i don't like texture atlas things, i think its too complicated for me.


    EDIT


    Maybe instead of centering actual quad he centers the sprite itself?
    Sprite W, H, and offset thingy. Centering images is easy, at least in 2D.

    This would work in my case for map editor i think.

    But if we talk about game collision then he shoots a ray in 4 directions from ped center and tests for collisions with nearby obstacles / walls. So actual sprite quad is not used in collision testing.


    Dunno.
    Last edited by hwnd; 31-03-2013 at 03:32 PM.

  5. #5
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    If the source image is exactly this, but it's stored as NPOT, then it's almost certainly *supposed* to be offset from the center due to it's use in the game (try some other images, try some cars etc). If not then there simply must be additional information in the game data somewhere that gives you the true image size.

    The point is that you shouldn't have to remove any pixels, if it's NPOT then why didn't they save it clipped to the visible pixels in the first place? why did they waste space? and if so, where's the additional information telling them what the usable portion of the image is?

    Removing black pixels is not a good idea, you can't be sure that the original artist didn't actually have some blank pixels down one side, this can't possibly be the solution because why would they have this additional costly step in a commercial game when they could of just stored the image without unused pixels?

    Again, if this is the source image then it's supposed to look like (A) (with transparency) in the game, your solution is correct, it's correctly mapping the source image you posted to the quad only by modifying the texture coods. it's the source image that has the blank space, not as a result of your calculations.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

  6. #6
    I think you are almost there, but it's unclear why some other also have offset. Like peds:
    Right side has offset:



    In my friends renderer he deals with "alignment"
    He draws peds with alignment like this:

    Code:
       if (align){         VBO.Add(Vector3f(pos.x+w/2,pos.y+h/2,pos.z),Vector2f(texEntry->U2,texEntry->V2));
                VBO.Add(Vector3f(pos.x+w/2,pos.y-h/2,pos.z),Vector2f(texEntry->U2,texEntry->V1));
                VBO.Add(Vector3f(pos.x-w/2,pos.y-h/2,pos.z),Vector2f(texEntry->U1,texEntry->V1));
                
                VBO.Add(Vector3f(pos.x+w/2,pos.y+h/2,pos.z),Vector2f(texEntry->U2,texEntry->V2));
                VBO.Add(Vector3f(pos.x-w/2,pos.y-h/2,pos.z),Vector2f(texEntry->U1,texEntry->V1));
                VBO.Add(Vector3f(pos.x-w/2,pos.y+h/2,pos.z),Vector2f(texEntry->U1,texEntry->V2));
    }
    He does some addition and dividing. "Pos" struct is (X,Y,Z) position to draw ped at, "W" is ped sprite width (NPOT).

    I should try to make minimal app with this VBO and use my texture, maybe it actually solve this.
    Im not sure.



    EDIT

    Ok, i think you are correct that this actually should be like this.
    if you look at the ped above, it's centered. I tried some other peds and objects.
    They seem to be centered enough.

    I think that's it. It's just supposed to be like that.

    Another ex:
    Black borders but c. car is centered:



    Thank you for helping.
    Last edited by hwnd; 31-03-2013 at 04:02 PM.

  7. #7
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    it looks like VBO in this example is a class he's created that constructs a GL VBO. his sucessive .Add calls are equivlent to your glvertex3f + gltexcoord2f calls, pos would be the sprite position on the map, w/h are the size of the quad that is rendered (note that he's actually creating two triangles here to make a quad.

    but without knowing how his w+h are calculated and how the texEntry U1,V1,U2,V2 values are created, I can't give you any more information.

    I've looked up on GTA files and rendering, I've found :

    http://brain.wireos.com/?p=1673

    A GTA 2 .Sty parser (and looking at that, are you parsing .sty files or have you converted them to textures you're using?)

    and

    http://gtamp.com/gta2/tools/

    which contains a link to gta1-gta2-tool-source-code.7z released by jernej, inside that archive there's tons of code dealing with GTA1 and 2 data files.

    I can't be certain without extensive study, but his STY editor does seem to suggest that there's additional offset information that comes with each sprite defintion.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

  8. #8
    Quote Originally Posted by hwnd View Post
    Here is the way im doing atm:
    Code:
     
    var texTop, texbottom, texleft, texright:single;
    w,h:Single;
    
    
      texTop:=0; // This shouldnt be 0 i think, must be calculated?
      texleft:=0; // This shouldnt be 0 i think, must be calculated?
      texbottom:=th /getnextpot(th);
      texright:=tw / getnextpot(tw);
    
    
      w:=tw/64;
      h:=th/64;
    
    
    
    
    
    glBegin( GL_QUADS );
             // Top-left vertex (corner)
             glTexCoord2f( texLeft,    texTop ); glVertex3f( -w/2, -h/2, 0 );
    
             // Bottom-left vertex (corner)
             glTexCoord2f( texRight,    texTop); glVertex3f( w/2, -h/2, 0 );
    
             // Bottom-right vertex (corner)
             glTexCoord2f(  texRight, texBottom); glVertex3f( w/2, h/2, 0 );
    
             // Top-right vertex (corner)
             glTexCoord2f(texLeft, texBottom); glVertex3f( -w/2, h/2, 0 );
    
       glEnd();
    If i modify either texTop and / or texLeft then i can move texture to center.
    But then it looks pretty bad, like squeezed together a bit or something.
    The problem of this code you had is that you have only been moving texTop and/or texLeft but not texBottom and/or texRight. So instead of moving texture you have actually been scaling it.
    You should have changed your code like this:
    Code:
     
      texTop:=0; // This shouldnt be 0 i think, must be calculated?
      texleft:=0; // This shouldnt be 0 i think, must be calculated?
      texbottom:=textTop + (th /getnextpot(th)); //Bottom edge is always position of top edge + height
      texright:=texLeft + (tw / getnextpot(tw)); //Right edge is always position of left edge + width

  9. #9
    Quote Originally Posted by SilverWarior View Post
    Code:
     
      texTop:=0; // This shouldnt be 0 i think, must be calculated?
      texleft:=0; // This shouldnt be 0 i think, must be calculated?
      texbottom:=textTop + (th /getnextpot(th)); //Bottom edge is always position of top edge + height
      texright:=texLeft + (tw / getnextpot(tw)); //Right edge is always position of left edge + width
    Thanks, but does it matter? I changed like you told me but it looks same.
    But anyway, its good if somebody else with more knowledge takes a look at this.

    User137

    I know that nxPascal supports the stuff, but i wanted to work out "my own" so i understand what must be done to support and draw such textures normally.


    Edit: wow, i just now noticed the example you made.
    Thank you very much for this!!
    Every bit of such thing helps and motivates me.

    Thank you again!

    So now if i apply the animated texture to 3D quad, it will still work?
    Last edited by hwnd; 31-03-2013 at 07:51 PM.

  10. #10
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    Quote Originally Posted by hwnd View Post
    Thanks, but does it matter?
    Not for a single image, but in a texture atlas for example you will need to do as SilverWarior stated, obviously in such a scenario your textop + texleft would be non-zero
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

Page 1 of 2 12 LastLast

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
  •