PDA

View Full Version : G.T.A.2 Map Editor



hwnd
24-01-2013, 10:03 PM
Hello all.
I decided to show my project here finally. I have been working on it already 5 years or so.
Started somewhere in 2008. Because GTA2 is my one and only most favorite game i still work on this thing.
I have been rewriting it many many times, i had different problems with it, specially the picking blocks with mouse, i tried (i think) every picking method there is in OpenGL and finally found a nxPascal with it's picking code and my problems were solved. With lot's of invaluable help from User137. Thank you very much.

Reason for doing this project is that it's good way to discover new ways of doing things in Delphi (Pascal) and OpenGL and discover and learn old / new things and most important, it's fun. It's my favorite game as i said.

There are lot's of features to add, but the top thing for me is to add lighting to editor like in original map editor for it (it uses DirectX). The rest is easy.

I have plan to add support for GTA (i.e GTA1) also, because they use similar data formats. Very few people play GTA1 but it's also very fun game, although with a bit poor gfx. But i has some things that GTA2 doesn't have like motorcycles which you can drive.


Editing / adding Map objects, map zones, sounds, tile animations etc, many cool and interesting things will be added.

You can see many of the videos on my YouTube channel: www.youtube.com/user/jw200 (http://www.youtube.com/user/jw200)

Latest video shows the status of the newest renderer

http://www.youtube.com/watch?v=WnmRZu1ZN6k

It has problems with 4 slopes currently. At least i didn't see problems with other slopes so far.
This is easy to fix. The picking is working in that vid, but i didn't show it.

Im focusing right now creating a simple GUI for editor now in Delphi, the i can slowly build up from there.
Atm it's just form with rendered map because i wanted to make core things to work first.
I.e cam movement, flat (transparent faces), tile flipping / rotation, debugging slopes etc.

Yesterday i made the picking to work on whole map, instead of initial X: 0..15, Y: 0..15 range.
Easy thing.
There are few things to complete with picking, slopes and flat faces (i noticed that some faces need special handling). It's a matter of just adding few boolean operators to code (and, or, not).

There is lot's of room for optimizing and speeding up both the rendering and picking.
For ex: rendering is done currently with glBegin glEnd. These i will replace with vertex arrays later.
Hopefully i must not mess with my vertex constants again to use vertex arrays.
glbegin glEnd is just easier to debug my verts.

I am developing this thing in Delphi 7 Personal or Turbo Delphi 2006 and using only freeware components, no shareware involved! Also im using few dll's made in C++, to allow Delphi to use neat things like std::map etc.

There is lot's to write about this thing, but i will add more later. Just keep looking my thread here and the first post also for updates.

Please post your comments, ideas, thoughts etc on this project.


Thanks for reading!

Carver413
25-01-2013, 12:20 AM
very nicely done, love the music

hwnd
25-01-2013, 09:33 AM
Thanks. I thought that people will say "remove the music". But i think silent videos are not very good.
Next vid hopefully shows more stuff and is longer.

hwnd
29-01-2013, 11:24 AM
Just posting this as log.

About these 4 slopes, actually they are just are copy of one slope of same type. Just with different rotations.
It's tricky because they can have different shape, if slope has LID face then it has one shape, if it doesn't have LID then it has second shape or form.
I completed one slope, now i will just mathematically rotate it (thanks to nxPascal great and neat code again) but rendering of these slopes is also tricky, including picking. I saw that when messing with these 4 slopes i messed up drawing of some faces for other slopes.
The block (or slope) drawing code tries to be general for all slopes. But if there is bad boolean logic, it messes up other faces. The code is also pretty messy atm. I must rewrite it. The whole logic is there just few boolean functions returning me "true" or "false" and some logical boolean ops like "and "or" "not".
It's very boring stuff to work on, but i must fix this asap. How the map is rendered and how the picking works depends on this stuff.

Now i gtg to work.

Bye.

User137
29-01-2013, 02:22 PM
You didn't post about the boolean logics as code :) But you can msg me in Skype/MSN later if want to.

hwnd
29-01-2013, 09:13 PM
The logic is pretty tricky there. It's hard to figure out things if code is badly formatted and contains lot's of commented out lines of code from debug time. In my case this quickly builds up and i have source where most of the space is wasted by commented out lines. So i started to rewriting this thingy and that's the reason why i wanted to init nxPascal with button (actually menu item later). So i can slowly move on with GUI. And at the same time continue with rendering part.

And that initializing stuff stopped me. I will try to make this work first. I will let you know how it goes.

Of course im not rewriting this from 0 again, it's just i wanted to move on with GUI and move the existing code to this fresh GUI and at the same time cleanup and debug my code.

Also from the video above it's possible to see that flat (transparent) faces bug, graffiti on the walls, Z fighting (flickering). Not a big problem but just looks bad for eyes. Nothing else.
I have to add some very small value to flat vertices, like 0.001 or 0.01 or something like that.

hwnd
30-01-2013, 01:52 AM
Little log again.

I worked on the editor GUI and added many things and debugged at the same time.
I added the docking tiles panel where the tiles will be drawn later (on the grid) and some tile info (like small selected tile preview). For docking panel i used old but working component DockPanel from http://www.torry.net/pages.php?s=79

(DockPanel is a component which was originally created for the open perl IDE. This release has been modified to be substantially easier to use, requiring virtually no code to actually impliment it, and a few new features including tabposition, and Tabtype (Icon or strictly text). This produces a docking style similiar to that which is seen in Delphi, and Homesite.)

Does it's job very well and it's very easy to get up and running. Whats even better, it saves it's positions. I don't have to do anything. Also made the menu items to show and hide the side panels, including tiles panel. Made the shortcuts to work.
Messed with FormShortCut handler to handle any shortcuts or things except the 4 arrow keys. I will handle these by my own:

procedure TfrmMain.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
var Key: Word;
begin

if MenuToolbar.IsShortCut(Msg) then
begin
Handled := True;
end;

Key := Msg.CharCode;

//We handle arrow keys by our own
if Key in [37..40] then
Handled := False
else
Handled := True;
end;

I need this so that arrow keys will not mess with components on the form like some Listboxes or buttons, in old versions of editor i had this problem. Arrow keys were messing up everything.
This handles the issue for me.
Also i figured out why nxPascal didn't receive a Key values in GameLoop. That was that shortcut thingy again.
Now it works and i can move my camera movement to gameloop now.


That's it for now. I must wake up early so i will go to sleep.

hwnd
03-02-2013, 06:57 PM
I was surfing whole day on he net and found a good tutorial how to make dynamic and more than 8 lights with opengl.
I downloaded the example, messed around with it alot to understand what he is doing.
He used simple .obj model for lighting effect but i slowly added my own test vertex coords from map editor and i got it working with my vertices. The results look very very promising for me, im very happy with results so far.

I believe i can show lights like these in my editor very soon:
http://img853.imageshack.us/img853/683/lights2w.png
http://img72.imageshack.us/img72/1940/edtrlights.png

hwnd
08-02-2013, 09:44 PM
Nothing much to write atm but i took a small break from this thing. Currently im working on that "logic" that draws the transparent faces (walls) and with some slopes that had problems previously, fortunately there is only 4 of them that need special handling when rendering them.

Im making them work face by face. Easier in that case. Not writing all out and then debugging.
Found more lighting examples, but i must review each of them, find their pros and cons and find one that works at the best in my case.

hwnd
10-02-2013, 08:27 PM
Worked a bit on generation of minimaps (map thumbnails) (256x256 in size). Few examples:



http://imageshack.us/a/img812/8905/img2io.pnghttp://imageshack.us/a/img580/1426/img4xk.png


http://imageshack.us/a/img11/9296/img1u.pnghttp://imageshack.us/a/img267/7456/img3j.png


It's not final ofc. I noticed some small problems with it. It's skips some things.

User137
10-02-2013, 09:30 PM
It looks cool, but why so red/yellow city? 8)

hwnd
10-02-2013, 10:12 PM
Actually the maps are not yellow, just minimaps, just the way i generate colors, i take some color and then take into account the actual Z of the X,Y,Z loop and doing "COLOR or Z" logical op. And take into account the "ground type" at current X,Y,Z This results the "yellow" minimaps.
Now if i look at them i think they are too yellow.

I work with 64x64 tiles, there can be max 991 of them. Its very slow to actually loop through entire map and resize all textures to 1x1 pixel and draw bmp, this way it would match colors of actual map but i have to find a faster way of doing this. I did some quick tests. Of course i did all in one X,Y,Z "triple" loop. Alot of repeating.

Will try something else later.


Also i made the camera move to work with mouse dragging on the minimap. Even on the scaled down version of minimap which i needed very much, because 256x256 on the form is way too big.
Very simple math. Sadly i didn't figure out this by myself but thanks to one open source fpc project. But it works perfectly.

hwnd
12-02-2013, 03:37 AM
Found a bit of motivation to fix bug with rendering of flat (transparent) faces. Marked as arrows:

http://imageshack.us/a/img163/6696/flatfaces2.png
http://imageshack.us/a/img692/184/flatfaces1.png


What i have to do for rendering and picking such faces is to add additional vertex coords for all slopes.
When i do picking i have to check if face is flat or not and process specific vertex data.
I tried this method on few slopes and it worked fine.

Also i fixed today the flickering of flat faces (graffiti) on the walls. Added a 0.001 value.

EDIT: also added minimap to editor and navigating on the map when moving small rectangle on the minimap with mouse. Minimaps are not yellow now, i still have to tweak it but not much.
That's all for now. Gtg to sleep.

hwnd
15-02-2013, 11:38 PM
I finally fixed problems with slopes 49-52. All there is now with slopes is to add flat faces (not all slopes can have them) and add picking code back.
Some slopes do not have flat faces but i must verify each slope in GTA2 to actually see how it renders each slope flat faces.

Also i added the LID shading (fake shadows) which do look pretty good.
Arrows show the thing.
http://imageshack.us/a/img109/4193/shading2j.png

http://imageshack.us/a/img26/3041/shading1.png

User137
16-02-2013, 12:27 AM
Do you have rendering order for transparent surfaces? With Z-buffer alone they would show up bugged depending on camera angle.

hwnd
16-02-2013, 10:49 AM
I guess you mean Z fighting? I had these problems, it was very ugly when i rotated the cam and i solved it with small value (0.001) added / subtracted from either Z or X vertex coords and now they don't flicker.
The faces are drawn with that tiny offset but it's very hard to see anything unless you look very close to the flat face.
And no, i don't have any specific order of rendering.

Atm, im trying to draw zones (areas) with nx.CreatePlane with specific colors and alpha (so you can see through it).

phibermon
16-02-2013, 12:40 PM
It depends on how the type of transparency if you need to sort transparent meshes, it's hard to tell from the screenshots if the textures are fully blended with an 8 bit alpha channel (requires sorting, think an additive blend of a fire particle system) or if pixels of a certain colour are discarded (results in 'sharp' edges where the transparent coloured pixels would meet the textured pixels, so no actual blending of Source Colour to Destination, does not require sorting).

For extra FPS in any renderer, you should render front to back to minimize overdraw (zbuffer discards fragments before they're rasterized if they're behind what's already been written(drawn) to the buffer(Screen).

For a top down view on a planar world (like GTA2 maps) you probably wouldn't save much to make sorting a worthwhile option as very little is rendered behind visible geometry. However if the camera is looking out across the map from an FPS like perspective then you'll benifit from sorting before you render each frame.

I see that the visible portion of the map in your editor is clipped to a quad that is centered on the cameras position, are you also able to render the map clipped to the cameras view frustum? I think it'd be awesome if you could walk around the map in first person!

phibermon
16-02-2013, 12:55 PM
oh and btw to render your minimap, you could use GL Framebuffers and then as a pre-process before you start the render loop, put your camera into orthographic projection, place it in the middle of your world, set the width and height to the bounds of the world and then render the whole lot into the Framebuffer (yes might take a fraction of a second to complete but you don't need to do it every frame). then you have a texture (or renderbuffer etc) in truecolour of your entire map that you can render as a textured quad (or blit the render buffer etc). You might want to exclude things from this map render pass that you don't want visible on the map, like say walkways across roads that might result in spidery grid like patterns on the image.

hwnd
16-02-2013, 02:15 PM
Hi. Thanks for your replies.
Yes, map rendering is limited, because i can't draw whole map at once. Fps goes down to 1-2 then.
I was thinking about walking around in city as in FPS games, but i don't know how it will look like. Because all blocks are 1*1*1 units in size. Some guys made a conversion for GTA San Andreas but i have to tell you, it looked very bad. At least for me. These blocks (maps) are not meant for FPS style. Maybe it will look better, if you create a race game with some "lowrider" and then drive around with camera almost on the ground but 3D car physics is not for me.

What i want to do is make the ped walking around in the map, actually i already have it but without any collisions.
I have collision code also, but just have been lazy to include it.

However i will try to look again at the map with low camera position (ground view) and how it looks.
Maybe if i scale blocks up a bit, it will look better. I haven't tried that yet.


The minimap method you posted is ok for game actually. But i found that original editor actually updates minimap as you remove / add / modify stuff (blocks) on the map.

But i will use your idea for game minimap. So when game loads it's stuff, it will create minimap and renders it on some plane.


EDIT:
I added displaying of zone names, the info it displays of course will be modified later.
This is just a test.
Got some neat text code from http://wiki.delphigl.com/index.php/wglUseFontBitmaps

User137 It would be nice to have that 3D text thingy in nxPascal.
I know you have fonts and stuff, but there is no functionality for 3D text that always faces the camera.

And i can now display 3D text that's facing cam always, without glut.
Few examples with zone names:
http://img521.imageshack.us/img521/7585/zonenames.png


Also thanks to neat InRange() function of Delphi i can only draw strings that are currently in visible range of map.
Also thanks to nx.DrawScaled() i can draw neat planes for zones:
http://img405.imageshack.us/img405/3905/zonearea.jpg

User137
16-02-2013, 05:26 PM
It would be nice to have that 3D text thingy in nxPascal.
I know you have fonts and stuff, but there is no functionality for 3D text that always faces the camera.
Sorry, not having easy answer to this. There are many ways you can draw 3D text with nxPascal, i can tell a few:

1) Using gluProject() you can transform 3D coordinate into where it's located on the 2D screen. Then you can draw the font in 2D ortho mode (nx.Enable2D()). There is nx.GetViewDetails() which will get you the OpenGL view details needed for gluProject() call.

2) If you want truly 3D text like that guard name, and floating combat text like that:
http://static.ddmcdn.com/gif/wow-guide-4.jpg
you could use a little matrix math. This could be simpler and more efficient if you use the nxPascal camera class, instead of relying on OpenGL matrix commands. To turn rendering towards camera, you would first read the camera rotation matrix and invert it. Multiply camera with the inverted rotation matrix. Then there's matter of drawing the font... 3D coordinates are usually in smaller scale, 1.0 meaning roughly 1 meter, whereas 1.0 in 2D is 1 pixel. So that must be drawn centered (there is draw function for that) and scaled smaller.


Yes, map rendering is limited, because i can't draw whole map at once. Fps goes down to 1-2 then.
Also about minimap, you could render it to framebuffer once, and then draw only the framebuffer afterwards. It's just 1 texture in practise, and wouldn't hurt FPS at all. I tried to show some use of framebuffers in the demos.

hwnd
17-02-2013, 02:01 AM
Ok, i will try.

Any ideas how to handle textures that are not POT? Not 16x16, not 32x32, not 64x64.
But like 30x26, 8x64 etc.

How to make opengl accept them and center them on the quad to draw them properly?
If every texture like this has black background (for transparency) and if i go through each images background and find a pixel that is not black and if i copy all non black pixels to memory to create texture from, will this work?

Will it be very slow?

I need to handle such small non POT textures because GTA2 uses them for sprites like peds, map objects, guns etc.

User137
17-02-2013, 02:29 AM
Non power of 2 textures work by default on nxPascal. I can still remember the key issue there used to be

glTexImage2D(GL_TEXTURE_2D, 0, intFormat, sizeX, sizeY, 0, Format, GL_UNSIGNED_BYTE, Data);
I used to have intFormat 3 or 4, but it should be GL_RGBA or GL_RGB if no alpha channel. There were no other special tricks to make them work ;)

hwnd
17-02-2013, 11:53 AM
But what about OpenGL itself, i have read that he doesn't like such textures very much.
And some guys were getting black textures instead of actual textures on some cards.
But i also have read that GL 1.1 should support them. Dunno what's true and what's not.

User137
17-02-2013, 03:10 PM
You can read the limitations on wiki:
http://www.opengl.org/wiki/NPOT_Texture
Bottom line: "All newer hardware can handle NPOTs of any kind perfectly."

While i still had that white/black texture bug myself because of 3, 4 thing, i implemented the TQuadTexture class. It divides the texture into power of 2 texture parts. There's also 2 different loading options for textures:
toScale: Loads image into power of 2 texture, and scales to nearest match. For example 400x900 would round to 512x1024.
toFitScale: Loads image into power of 2 texture, and makes the size to current or higher match. This actually doesn't scale, but leaves black gaps on the outside area. Each texture has separately SizeX, SizeY, Width, Height, where Width/Height is the actual image size, and SizeX, SizeY is texture size. So nx drawing functions still know how to deal with them.

QuadTexture - Reserves near exactly the needed area from memory, pixel perfect.
toScale - May cause slight blurring, pixel perfect data is propably lost, memory efficient.
toFitScale - Keeps pixel perfection but reserves more memory than QuadTexture, propably not very usable on 3D-models.
(no option at all) - Pixel perfect, memory efficient non power of 2, if card supports it.

Super Vegeta
17-02-2013, 03:21 PM
About getting black textures when trying to deal with non-POT stuff, I had the same problem until I began to include this in my texture loading code:
glPixelStorei(GL_UNPACK_ALIGNMENT,1);

hwnd
20-02-2013, 10:28 AM
toFitScale - Keeps pixel perfection but reserves more memory than QuadTexture, propably not very usable on 3D-models.

Why not very usable on 3D models?
I tried these options and best seems to be toFitScale.
The other one blurs too much.

All my 3D models are just small "planes". For ped i created this:

model.CreatePlane(2,2);

2,2 is ofc too big for ped, it's just for testing purposes. Later it will be even smaller.

But loading NPOT textures from file seems to work fine.
Will try later how to supply img data from memory to it and how it renders them.

User137
20-02-2013, 02:30 PM
Why not very usable on 3D models?
Because often times 3D models UV maps rely on coordinate range from 0..1. If Image Width is 257 then texture's sizeX would be 512. So right side of the texture has black stripe. That obviously cannot be used as a repeating texture, and the usable UV range would be closer to 0-0.5.

edit: Ah it's actually not black stripe. It will clamp with border line like that right side image:
http://i.msdn.microsoft.com/dynimg/IC142381.gif

hwnd
22-02-2013, 02:10 AM
Here i rendered a transparent ped. The lines around him are "little" blocky.
Is it possible to somehow tell OpenGL to smoothen these curves, so they don't look so blocky?
If it's not, i can live with that, but i decided to ask just in case.

The black behind it, is very basic fake shadow.
It has large offset because ped is dead and floating in air. This i just a test rendering.
The shadow should be transparent a bit also instead of complete black.
Shadow is practically same quad rendered with offset and with glColor3f(0,0,0);

http://img521.imageshack.us/img521/9231/blockytransp.png

Here is far view of ped
http://img843.imageshack.us/img843/8071/farview.png

User137
22-02-2013, 04:33 PM
You can make the shadow transparent with alpha color: glColor4f(0,0,0, 0.6);

Not sure if this is what you are after, but the smoothening of texture's alpha edges is done with:

glAlphaFunc(GL_GREATER, 0.008);
That means that only color with alpha value greater than 0.008 is rendered.
If you set it like (GL_ALWAYS, 0), it would draw the whole texture as smooth as it is, also fully transparent pixels with 0 alpha.

hwnd
23-02-2013, 04:46 PM
I will leave that sprite rendering for a while. I get tired and bored working on one thing for long time. Instead i worked on some other things.

With Ctrl+G shortcut it's possible to navigate to any X,Y coordinate on map.
I use simple Delphi function: InputBox to get coords from user. Temporary thing i guess.
Later i will use my own dialog i think.

Instead of instantly going to X,Y location it goes there smoothly. This will be optional of course.
First it goes fast and when arriving to specific X,Y it slows down until specified X,Y is exactly in center of the cam. And when camera is moving to that point and user clicks on minimap it stops moving.

Because slow PC im unable to make video, it's smooth in editor but not smooth while recording video.

hwnd
27-02-2013, 10:59 PM
Found a bit of motivation to work on editor a bit again.
I was bored. So i took old picking code and copy-pasted this to my latest editor source.
Works fine as it did previously. I wish i could make other things work so easily (by just copy pasting).
I don't have very much motivation to actually work on the flat faces again, there are few to add..

I will add selection boxes in. I actually had working implementation that drew them very nicely.
Will try to copy paste as much as i can. I had problems with selection going negative, i thought that glTranslatef will not accept negative values, but actually it did. Dunno where i stopped.
But the code had some neat things already implemented so i will not reinvent it again, there is no point if it works.

Ñuño Martínez
09-03-2013, 06:02 PM
First, nice job. I was reading and looking the videos for a time and I like it.

I'm wondering if it can be used for games other than GTA2. I mean create new games.

hwnd
11-03-2013, 02:12 AM
Thanks.

I have plan to add support for GTA1 but very few people actually play it.
But there are some other similar games.

I want to add a simple ped to map renderer and walk around on map, with collisions etc.
Just for fun. If i can get this work, i will add more things maybe. If it's not gonna be a game, then it would be like preview of map ingame that you just created, without actually running GTA2. So you can see preview of the map like in game.

But atm im taking a break from this editor project. Im not the guy who can work on one thing for very long time "in one row". I need to do some other things and then come back, everything helps, maybe even getting away from pc for a while, work on my car, just walking outside etc. I get my motivation this way.
Atm i don't have any of it to work on this editor. But i will get it back soon and then i will continue.

Instead i work on new script compiler for GTA2. It's a combination of C++ and Delphi.
Very interesting to code. And it works pretty well already, GTA2 is happy with them.
Ofc i can only compile simple scripts atm, nothing complex like IF..THEN..ELSE or WHILE etc.
Im starting with basics.

hwnd
25-03-2013, 12:22 AM
I wanted to work on this thing again and once again, taking a break from project helps.
I found good tutorial and example for handling NPOT textures here:

http://lazyfoo.net/tutorials/OpenGL/08_non_power_of_2_textures/index.php

So i took some NPOT textures from GTA2 and and they all are rendered correctly.
I have to use DevIL with Delphi and additional DLL's but the result is awesome.


What's even more important and awesome for me is that these are all quads rendered with OpenGL and textured with NPOT textures. This is exactly what i wanted.
And if i understand correctly they all are centered. It was very hard for me to make work, but that example solved this.

Im not sure if i can get rid of the DevIL but if yes, tell me.
I was so excited so i even didn't properly read the source and what it does exactly.
If it's possible to get rid of it, i will use nxPascal stuff.

Here are few examples
http://img854.imageshack.us/img854/850/npottex.png

Carver413
25-03-2013, 12:12 PM
in newer versions of opengl textures need not be powers of 2 to work. I create many textures on the fly and none of them are powers of 2 and they render fine.

Rodrigo Robles
25-03-2013, 12:32 PM
in newer versions of opengl textures need not be powers of 2 to work. I create many textures on the fly and none of them are powers of 2 and they render fine.

I read somewhere that although non power of 2 textures are supported, the power of 2 will get better performance. I would like to know how much better performance...

User137
25-03-2013, 02:27 PM
If it's possible to get rid of it, i will use nxPascal stuff.
Yes nxPascal supports NPOT textures. There should also be demo that shows drawing 2D centered, and it allows rotation point be anywhere in (or out of) the image. Demos use POT texture sizes only because they are most compatible, but you can freely edit the images in Paint/Gimp or other and any size would work.

Also the link you gave http://lazyfoo.net/tutorials/OpenGL/...ures/index.php is not actually using NPOT but it's putting small picture into larger 1024x256 texture with black pixels outside. That's not best way to handle it, although as i have mentioned before, is also possible with nxPascal through texture options...

Carver413
25-03-2013, 05:19 PM
I read somewhere that although non power of 2 textures are supported, the power of 2 will get better performance. I would like to know how much better performance...
I read somewhere that opengl actually expands these internally so they end up as power of 2 anyway. the advantage would be in the passing of smaller texture or maybe thats where the slowdown occures. best practice of course would be to try to put them on a single texture and map them properly

hwnd
25-03-2013, 10:13 PM
I have old PC with old gfx card ATI Radeon 9550. And i want to support old hw and os starting from Windows 95. Better don't ask why. I love the old stuff and software. I dunno, if nxPascal GL code supports W95, with the latest possible OpenGL dll in it. I will try with my editor. I don't use any shaders or anything in my editor and "biggest" textures are 64x64.
Just the sprites from GTA2 files are different, like 16x78, 2x28 etc. I don't use any texture atlas, they seem to be too complicated for me.

Te DevIL actually seems to have bug or im just not doing enough or doing something wrong but NPOT .bmp files are completely screwed when rendering them with same code. PNG works fine. I havent tried the pure pixels from pointer. Will do this later, hopefully it will work.

phibermon
29-03-2013, 02:17 PM
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.

hwnd
31-03-2013, 01:00 PM
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

http://img163.imageshack.us/img163/4470/offsetbug.png



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:


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.

phibermon
31-03-2013, 02:54 PM
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

hwnd
31-03-2013, 03:09 PM
Ok, here is the image i use for testing.


http://img255.imageshack.us/img255/3727/testos.png

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/blobs/7aff302684bca21d803c7f439f4b44958647dffe/src/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.

phibermon
31-03-2013, 03:41 PM
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.

hwnd
31-03-2013, 03:54 PM
I think you are almost there, but it's unclear why some other also have offset. Like peds:
Right side has offset:

http://img803.imageshack.us/img803/2497/offset2.png

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


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:
http://img213.imageshack.us/img213/4828/carcpp.png


Thank you for helping.

phibermon
31-03-2013, 04:07 PM
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.

phibermon
31-03-2013, 04:11 PM
Only just saw your Edit, brilliant :D I'm really happy that I could of helped but feel free to post any further questions you might have and I'll do my best.

And I also know why there's black borders, there's additional animations for sprites, like car doors opening etc and if you were to go thru all the images (such as a ped walking) you'd probably see that all the pixels get used eventually across all the frames of animation etc

because animations must be stored in an array of images of exact dimensions, you'll have some frames that don't seem centred etc

hwnd
31-03-2013, 04:18 PM
The brain.wireos sty reader is the one i use because he wrote this for me. And the code is so fast.

And thanks to this im able to render these sprites and stuff. But yes for emergency lights on cars etc, its a bit complicated but nothing impossible i guess. Atm i just want to render sprites/game objects on map.

But npot textures scared me. But now it seems OK.

Btw, just for the info, from the STY docs:

"5.1 Sprite Graphics Data
Sprites are stored as uncompressed 256-colour graphics upto 32 pages of 64K each. Each page is 256x256 pixels. The maximum size of a sprite is 128x64 and the minimum is 2x2. The width and height can have any value inbetween as long it is an even number."

User137
31-03-2013, 05:50 PM
I know you are still using bit of your own texture loading, but i'll still give short example how nxPascal would do NPOT. You can download Delphi source and exe here. I made it as simple as possible but based on the game template:
https://docs.google.com/file/d/0B7FII3MhcAHJSFZXMkNlYWRvLW8/edit

There is no scaling of any kind, demo loads in 119x53 texture with 12 patterns in 6x2 grid. There is SkipWidth and Height of 1 because i drew it quickly with a green 1 pixel wide grid, which i had to take off because bi-linear rendering makes the grid show when drawn.

To summarize key points:

n:=tex.AddTexture('anim', GetPath('textures\anim.png'), true);
tex.SetPattern(n, 19, 26, 1, 1);
...
pattern:=(pattern+1) mod 12;
nx.DrawRotate((i mod 30)*15.0+20, (i div 30)*15.0+20, pattern, 0, 0.5, 0.5);
// I drew 1000 of these patterns, 30 per row, each centered around coords 0.5, 0.5 of the pattern, that's exactly in the middle.

phibermon
31-03-2013, 06:49 PM
well filtering a texture atlas is always going to give you issues like you describe, keeping a transparent border around sub-textures is the usual generic solution, GL_CLAMP_TO_EDGE won't help you as you're not necessarily addressing the texture up to it's edge for all sub-images.

Caveats you must accept for the performance gains of a texture atlas.

I'm working in OpenGL 4.x currently and I don't support anything less than 3. I did that specifically because I didn't have to jump through all the hoops. I'm guaranteed to have NPOT support, guaranteed to have uniform buffers, tessellation stages on 4.x hardware blah blah blah

it's so much less of a headache than GL1.x GL2.x, GLES etc

And it's only a matter of time before GL2.x is about as common as Glide (3DFX) plus the next itteration of GLES will be in the GL3.x/4.x style.

If you're working on projects with epic timescales, you've got to plan 3/4 years ahead. If you don't then you end up like GLScene with almost no ability to switch to the current versions (GL3 is old now) except a significant re-write of many parts.

I mean look at all those epic game titles from the 90s, games coming out in 1997/98 that ran in DOS!

You've got to think ahead, I'd advise anybody to throw GL1.x and 2.X out of the window immediately (pun intended) and work in a GL3 core profile at the very least. Doesn't matter if your card doesn't support it, that's what Mesa is for. And if you miss immediate mode functions for debugging purpouses, use a delphi/lazarus form with your window to display stuff or just re-implement immediate mode functionality on top of VBOs and shaders, I did that and never looked back.

SilverWarior
31-03-2013, 06:49 PM
Here is the way im doing atm:


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:


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

User137
31-03-2013, 07:03 PM
I'm working in OpenGL 4.x currently and I don't support anything less than 3. I did that specifically because I didn't have to jump through all the hoops. I'm guaranteed to have NPOT support, guaranteed to have uniform buffers, tessellation stages on 4.x hardware blah blah blah

it's so much less of a headache than GL1.x GL2.x, GLES etc...
I have plans for that, it's just lots of work... I already rewrote the shader classes 2 weeks ago so the "concrete basing" is already set tight 8) Building the renderer and all the shaders won't be easy though. Basically the 2D drawing code from programmers part will hardly change at all. Instead of nx.DrawRotate(), you'll just propably get nx.renderer.DrawRotate() with same parameters. The plan is to have polygon queue which adds and adds stuff, and then draw all of them at once. On change of texture, polygon mode (triangle/quad), or shader program change it will render the queue and start over again. That stuff should be invisible for the programmer. I would also be able to support uniform light arrays for example, in theory at least. Almost can't wait to get writing the shaders, just that true game programmer is also a gamer himself that is the major issue ::)

hwnd
31-03-2013, 07:42 PM
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?

phibermon
31-03-2013, 07:47 PM
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

hwnd
31-03-2013, 08:12 PM
in a texture atlas

Ok, if i will ever create my own game, i will try to use texture atlas.
The most difficult thing with texture atlas is calculating correct texture coords to get specific sprite.
But i will investigate this later.

User137
31-03-2013, 10:20 PM
So now if i apply the animated texture to 3D quad, it will still work?
You have 2 ways. If drawing the quad yourself, get pattern texture coordinates with this function:

tex.GetPatternCoords(var x,y,w,h: single; pattern: integer)
Notice that w, h are width and height, not x2, y2. You can get those with x+w, y+h. It will get the coordinates from texture which was previously set.

Or if you want to use the nx.DrawRotate() or others in 3D that is possible. But you have to deal with problem of 2-sidedness and camera, possibly lighting aswell (2D-drawing functions don't use normals). nx.rs.CullBack:=false should be set if you want it 2-sided. When setting the camera right you might find that useful... especially if you try to place it on ground and it's actually facing down, you can't see it and wonder why it's not working. The nx 2D drawing functions consider 0,0 coordinate be top left corner, whereas in 3D world positive Y goes vertically up. So first of all your image is upside down, and camera should be rotated around X axis before rendering. Then the scale of things, where normally 1.0 match about 1 meter, is only 1 pixel in those drawing commands. So they would appear gigantic and should be rendered smaller using the functions that include scale in parameters.

hwnd
08-04-2013, 09:38 PM
Didn't notice your reply here. Thanks for the info. I will test these things when i get back the motivation.
I am pretty tired lately and slightly sick because of the cold weather etc, i don't want to see the computer for a while now.

hwnd
15-04-2013, 09:42 PM
User137 or anybody.

I have a third party OpenGL app, actually GTA1 map editor from 1998, maybe uses OpenGL 1.1 or something, dunno. What's interesting in it is that it creates very nice minimap from map. I see that minimap uses same colors as actual map and any changes made in actual map are immediately visible on minimap.
Its a C++ MFC app, there is no source available.

Also it has option to also draw or not to draw transparent tiles on minimap.
This makes me think that it actually draws scaled down tiles, but how he does it so fast.
Thats the key question.

Any ideas how it creates that minimap? It seems that it draws actual map in small size somehow, like scaled down someway. But all minimap colors are same as in actual map and i would like to do the same in my editor.

In opengl, what could be used to create such minimaps? I dont think that it draws whole city twice, one in actual size and one like scaled down version. Or does it?
And its fast, changes in big map are immediately modified on minimap also.

I once tried drawing all tiles in 1x1 pixel for minimap but something was very slow. But it gave me same colors like in actual map.

EDIT: ok i remember, drawing 1x1 pixel tiles for 256x256 minimap was slow.

But one idea i have atm is to have big global list where all the current (LID) tiles are, actually their ID numbers and only these that are currently used will be scaled down to 1x1 and drawn with StretchDraw and not all.

I just need something fast.

SilverWarior
16-04-2013, 08:52 AM
I can think of two posible solutions for this:
1. Draw the whole map into some chached texture (render texture), then render visible portion of the map inside your windows and finally draw that whole texture scaled down to fit the minimap size. But this might not be nest solution especially if you have large map as you would require huge texture and scaling down such texture could lead to large inacuracies.
2. Calculate and store average color for each posible ingame tile. Then use that store information to determine the color value for each of the pixels for minimap texture (each tile is represented as single pixel). Since you are changing one tile at a time you would only need to update one pixel at a time.

User137
16-04-2013, 03:59 PM
SilverWarior has good tips. I would do 2) to hold 256x256 colored vertex array for the pixels. Render it into texture as a 256x256 grid, that's what framebuffer demo in nx is about. It might be a little complicated demo though. You can optimize it by having a boolean variable "minimapChanged". Every time you draw to tilemap it is set True. Then every half second check if it's True. If it is, then set it False and generate the minimap texture again. For actual map drawing you're only drawing 1 quad per frame. Change texture coordinates based on where the camera is.

edit: You can draw the whole map as is into framebuffer, if you want to make it simple and memory efficient. It will just take longer time to render. But then you can zoom the minimap with texture detail, depending on the texture resolution used on minimap. 512x512 would still only show you 2x2 area of 1 tile, but it's much more detail than 1 pixel.

And, what it means to draw into texture... Think if it as drawing the whole map onto your screen in ortho mode. Scaled exactly in area of texture resolution 512x512 if that's what it is. You should definitely test by rendering it on screen first to see that the boundaries are right, and then switch to render it to texture.

SilverWarior
16-04-2013, 04:46 PM
I would do 2) to hold 256x256 colored vertex array for the pixels.

Why bothering with veticles if you can simply do this with normal pixels. You can always stretch that texture to fit the desired size if needed.


You can optimize it by having a boolean variable "minimapChanged". Every time you draw to tilemap it is set True. Then every half second check if it's True. If it is, then set it False and generate the minimap texture again.

Why not change minimap texture as soon as you do any change to the map? Since you are usually changing one tile at a time this means that you only need to change one pixel or smal portion of your map if it is generated from map-specific mini sprites. I mean there is absolutely no need to redraw the whole map but only change the relevant part of it.

As for your suggested approach that is more suitable to be used inside a game where map changes are more rapid (unit movments etc.) but in map editor there is no use of that.

User137
16-04-2013, 04:57 PM
Oh you mean altering the texture data directly. Well, you might have glTexSubImage2D() (http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage2D.xml), but i don't have experience of that.

With normal methods you aren't able to change just 1 pixel, but render the whole minimap. Besides when you're editing the map you are watching the main screen where cursor is. By the time you move your eyes to minimap, with 500ms interval it would already be updated. And in the playing mode the minimap is normally not changing. Or if it, you can have an additional transparent map texture for dynamic objects.

I just uploaded new nxPascal to SVN, with change to framebuffer demo. I had previously left it with window size locked to framebuffer size 512x512, but now it works with any window size, to emphasize the fact that screen buffer size has nothing to do with texture size.

SilverWarior
17-04-2013, 11:35 PM
Oh you mean altering the texture data directly. Well, you might have glTexSubImage2D() (http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage2D.xml), but i don't have experience of that.

To be honest I also don't have much expirience with this, especially on OpenGL level. I did try once achiving this using Aphyre Sphinx TAsphyreLockableTexture which provides you with acces to each pictures pixel if needed but I don't know which OpenGL cal the Asphyre Sphinx makes for this to work.
Another way would be to simply use ordinary TBitmap to store minimaps data and then render this butmap on screen (many graphical engines alows doing this).



Besides when you're editing the map you are watching the main screen where cursor is. By the time you move your eyes to minimap, with 500ms interval it would already be updated.

@User137 if you need 500ms to change your eyes focus from one point on the monitor to another you gotta be getting realy old :D
Plese don't be ofended by my previous statement but 500ms is enough for average human not ony change the focus of his eyes from one point to another but to even turn his head for about 30 degres.
Also you have to asume that user decides to change his eyes focus at the same time he decides to do a mouse click. And since it takes a bit of time from the pint when you decide to do mouse click and actually do it your eyes could already be on the half way to destination focus point.



And in the playing mode the minimap is normally not changing. Or if it, you can have an additional transparent map texture for dynamic objects.

Yes using multiple layers for ingame minimaps is quite often especially if the minimap background is made from series of so caled minisprites.

User137
18-04-2013, 05:07 PM
if you need 500ms to change your eyes focus from one point on the monitor to another you gotta be getting realy old :D
Plese don't be ofended by my previous statement but 500ms is enough for average human not ony change the focus of his eyes from one point to another but to even turn his head for about 30 degres.
Also you have to asume that user decides to change his eyes focus at the same time he decides to do a mouse click. And since it takes a bit of time from the pint when you decide to do mouse click and actually do it your eyes could already be on the half way to destination focus point..
That was just an example :P Main part is still that you shouldn't do the texture-memory update in the event of mousemove, but at the beginning of render function, all changes at once, and only if there are changes. 500ms is just an example, might aswell be 100ms. Take a look at Starcraft 2 editor for example. While you are painting terrain and moving mouse rapidly, no changes to minimap are done. But if cursor is on 1 spot for about 500ms or release mousebutton, then update happens. These are just optimization tricks for when they are needed. Like if your minimap means actual polygon rendering of the whole world, with light environment and everything.

hwnd
28-07-2013, 03:20 PM
Working few days already on this thing. Today i messed again with selection boxes and noticed that Delphi 7 either has bug or it just has to be that way..

Here is snippet from drawing of block selectors:

glTranslatef(

Iff(frmMain.XPositive,(selcount2+selx), (-selcount2+selx))-0.5, // 1

Iff(frmMain.ZPositive,(selcount+selZ), (-selcount+selZ))-0.5, // 2

Iff(frmMain.YPositive,(selcount1+selY), (-selcount1+selY))-0.5, // 3


);

You see comments there 1..3 at the end of the lines. So at the 3 comment you see the comma?
Delphi 7 compiles without any error, which is strange, but if i put anything after the comma, it will give error, "too many parameters".


My D7 is very slow for some reason and hangs when compiling, then wakes up and runs my project, maybe i will have to format my laptop again.
So i decided to look how fast the compiling is done in XE.
I must say that even heavy XE on my old poor laptop here is faster than D7 IDE.
Dunno how that could be.

So i opened this project in XE and this immediately generated error that there is too many parameters, he saw the comma there.

So what is this? Bug or hidden feature? D7 just ignores commas, if there is no actual values after such "final" commas?

I didnt notice that comma was there, its a XE which pointed me to that.

SilverWarior
28-07-2013, 03:57 PM
My D7 is very slow for some reason and hangs when compiling, then wakes up and runs my project, maybe i will have to format my laptop again.

Maybe you wanna check your antivirus software. If you have residental protection on and in depth heuristic scanning enabled and your final exe contains quite some resources in it, it could take a while before antivirus finish scanning it (it actually extracts the resources from your exe and checks them seperately).

It is posible that your are slowly running out of free disk space on your system partition whoich could lead to files which are saved in Temp folder to be higly fragmented which could lead to slowdowns. D
efragmenting your hard drive might improve this. Also as a general note I recomend having athleast 1GB of fre HDD space on your primary partition or in case of dynamic alocatable page file size even more free space. I ususlly have fixed size of page file set to 150% size of my RAM.
Having fixed sized page file could mean great difference on Windows XP as the pagefile tends to become realy fragmented othervise.
Another thing that might lead to such problems is partially damaged sector on your hard drive which is causing slowdowns.

hwnd
28-07-2013, 04:11 PM
I dont have any AV, this lap. is too slow and old, if i install one of these and it starts scanning and watching in background, it will take years to compile each time.

I have divided the HDD to 2, part. C: has 37GB (14.3GB free) and part. E: 37GB (30.2GB free).
Sometimes reinstalling Delphi helps me.

But i will try to find out what it is later, have to do backups first.

MarcoCestari
28-07-2013, 05:04 PM
Try Andy's IDE Tools if you don't use them already.

http://andy.jgknet.de/blog/

hwnd
28-07-2013, 06:31 PM
I have Speedup installed.

What about the actual problem i posted? Is this Delphi bug or feature?

User137
29-07-2013, 12:23 AM
It's a buggy feature. This compiles on D7

function test(a, b, c: integer): integer;
begin
result:=a+b+c;
end;

procedure test2();
begin
test(1, 2, 3,);
end;

hwnd
31-07-2013, 09:42 PM
Ok, thanks. So im not the only one.


Btw, i compiled simplest app using nxPascal, game loop etc in C++ Builder 6.
I know, noone probably uses it, but i have personal version around and decided to try.
BCB is able to compile / link Delphi units. I had to do some minor tweaks (the BCB code converter is a bit buggy) but it compiles and links fine.

Had to replace #include "dglOpengl.hpp" with "#include <GL/gl.h>"
But it works fine. I dont use shaders or other fancy stuff. So its enough.


Got my nice black window :)

I have plan to rewrite my editor in C++ Builder because of all the nice stuff C++ has, vectors, templates, auto_ptr etc etc.

I got game loop to work and thats the most important thing.
And even more important for me, all the timing code (fixed fps) etc.
I dont know how to code it properly.

So i have the power of nxPascal and power of C++ / STL at my hands.
I wanted to try and do this for a long time now.

I once tried this, but got so many errors and i gave up.
Now i found that i actually already had some generated .hpp and .obj files from nxPascal sources and decided to try again.

Add files carefully to C++ Builder project and compile each time and link.
Finally it compiles everything and no unresolved things or such.

Had to of course derive from nxPascal classes like in Delphi. But again this was also very good learning step. C++ is not new to me but alot is unknown for me. Because im more of a Delphi guy. Doing this "porting" is good exercise.

EDIT: cube is rotating on the screen :)

I can still use all the code of yours, nxTypes etc, only difference is that instead of Pascal syntax i have to use C++ syntax, all the stuff is available. GetMouseRay etc etc.
Ofc. after you do some major updates, i have to rebuild fully.

User137
01-08-2013, 01:31 PM
I have plan to rewrite my editor in C++ Builder because of all the nice stuff C++ has, vectors, templates, auto_ptr etc etc.

On defence of pascal language, it has all those features aswell. Vectors - TList, inc(pointer_variable) etc. I cannot say about templates, generics whatever, it is my assumption they exist in some form in FPC, but i don't use them.

If i understood right, you are somehow using pascal-compiled object files with C++, then just making header files for it? This might not be crossplatform way at least, not even 32-64-bit compatible. But if you create something that could be shared in public, i could let you upload to new folder in SVN trunk. (I cannot say that i would be able to test it though :/ )

hwnd
01-08-2013, 02:34 PM
On defence of pascal language, it has all those features aswell. Vectors - TList, inc(pointer_variable) etc. I cannot say about templates, generics whatever, it is my assumption they exist in some form in FPC, but i don't use them.

I know, i like Delphi more, its compiler is faster than BCB6. I can modify something in my Delphi project src and run and see the results immediately, Delphi compiler is so fast (talking about D7 here). The more recent version the slower the compiler is.
In BCB its pretty slow. I know it has to compile also alot but still its faster than i guess the BCB2009 and newer.
Whats really bad in case of BCB6, the TBX and TB2k do not work well in it. I get lots of out of memory access violations and BCB6 IDE just crashes and doesnt allow itself to close.
There seems to be no free replacement for TB2K / TBX addon. Just the ugly default TToolbar and TMainmenu. But with TBX its possible to make alot nicer interfaces.
For my script compiler i use Delphi and im able to use TBX there, all working smoothly.

Also it works fine in CodeGear BCB2007 but it doesnt like the BCB6 for some reason. Too bad..

And to be even more honest with you, im not sure if i will convert it to BCB.
I could and already use some DLLs made in BCB for texture caches etc, using STL stuff in DLL. And using in my editor project.

All works fine.
I have to think about it.


If i understood right, you are somehow using pascal-compiled object files with C++, then just making header files for it? This might not be crossplatform way at least, not even 32-64-bit compatible. But if you create something that could be shared in public, i could let you upload to new folder in SVN trunk. (I cannot say that i would be able to test it though :/ )

Yes, BCB generated .hpp and .obj files from Delphi DCUs and links them into exe.
I wish Delphi could link PURE C++ .obj files / libs into its exes. And if this would allow to link stl stuff in, i would be very happy.

But atm we must use DLL's, at least they invented DLLs.

To be honest in my projects i dont care about crossplatform. GTA2 is only for WIN32 so is my editor.
And also i dont make games so much. At least currently.
Im not very much interested in latest XE4 also, it has some new and maybe even crossplatform things in it. But i dont know. I havent read about this. I know it should support 64bit but i dont have such computers. People talk pretty bad things about latest versions. People constantly leaving or laid off from Embarc. etc. Bad things going on.
I have seen many articles from real ex. people from inside Embarc. talking about how bad things inside Embarc. actually are.

I miss the good "old" Borland.

If you would want to include this BCB version in svn, then i will have to make it more clean and more professional. Atm its quick and dirty. But i guess it wont hurt to add BCB version there.

hwnd
02-08-2013, 03:49 PM
Any ideas how implement undo redo guys?
I have tried several Delphi units for undo/redo, even with command patters and state machines. Even dig out some website archives for SHAREWARE (!) Delphi units for creating undo / redo and mailed to authors of them to get the units for free (without much hope for any response).
Etc.

I got them but nothing works for me. I see "lots" of examples that use simple TBitmap.SaveToStream method.
Its neat and easy way to make undo / redo.

But how about 3D map editor like this?
Map is 256x256x8 (W*H*Z), i only draw small portion of it (20x20).

I guess i have to invent "gamemap.portion.savetostream" command.

Whole uncompressed map takes 6MB of disk space, depending how complex map is. But 6MB is minimum for empty map.
So saving whole map each time is not way to go. it would work for small tilemaps / tilemap editors, but not in this case.

One way would be just save all the blocks in current view but if camera moves, then what to do?
I tried that without moving cam, it seems to work, its buggy a bit, i just cant think clearly atm why its buggy, i have to eat and come back to this.

When camera moves i guess i have to remember the offset to the place where previous undo / redo was made or something and undo / redo in that area, or make some record and in record make a member called XYZpos for storing the start position of the area where the changes were made, dunno something like that maybe.

Map has so easy format, i didnt know that making a undo/redo will be so difficult for this.
I have read that if you dont think about undo/redo at the first time you create your app, integrating later any of the algorithms for undo/redo will be difficult.

So i guess here i am.

I could modify my rendering function if i could reorganize my map array somehow.

This is where i need your help / tips / tricks / ideas how to do it.
Even some pseudo code would help i guess.

Thanks.

User137
02-08-2013, 06:12 PM
Few ways come to mind. All solutions consist primarily of array or list of undo operations. But what each operation is, may differ:
1) Compress the map using TCompressionStream and TDecompressionStream. Your data size per undo-operation might go down to some number measured in kilobytes.

2) Just save the action what was done, not whole map (unless necessary). You can make base-class TUndoAction, and inherit from it like:

// Some action where you select rectangular area, and move it in some direction...
TMoveUndoAction = class(TUndoAction)
public
selEnd, selSize, moveDelta: TVector3f;
procedure Execute; override;
end;

// Free tile-painting for map. You might need to save the entire map for this, so you can use the TCompressionStream
// to write in TMemoryStream.
TPaintUndoAction = class(TUndoAction)
public
map: TMemoryStream;
procedure Execute; override;
end;
You get the idea, there can be lots of kinds of undo operations, some of which may not be related to tiles at all. And i'm not sure what all your editor can do.

hwnd
02-08-2013, 06:31 PM
Ohh, you gave me great idea about compressionstream.. Thanks.
I did a quick test atm, official large map fully compressed is 1.23MB.
It contains lots of cubes / tiles. After 7z: 343KB

Empty map, compressed 273KB.
And now compressed with 7z: 385 bytes lol.

This map format contains lots of 0. Thats why 7z is able to compress it so well.
I will try with compressionstreams..

Yes maps must be first compressed with specific way, before game is able to load them.
For undo its not needed.

This of course probably will be the easiest solution. Just take whole map and compress.
And if i limit undo count, maybe it will even work.

Atm i would like just to have undo / redo for tile "painting".

SilverWarior
02-08-2013, 07:57 PM
Making Undo/Redo function laregly depends on how you want to track theese changes.
If you are tracking changes for each cube seperately then I would suggest creating dynamical array of special records which will contain cube position, old and new state of it.
If you are tracking changes of several cubes at once (making cube shaped hole in your terrain) then I you can euther use similar system as above with the only difference that you now have seperate arrays for each undo/redo action. Or you can create some kind of submaps (array smaller than the whole map array) which will store previus state of the map section before it was changed.

hwnd
02-08-2013, 08:57 PM
Yeah, for each individual tile making undo / redo seems easy, but if user makes lots of changes, then he must wait alot before undo reaches the stage where he started to draw these tiles.
I tried and its very slow.

Its better to create group of undos.
And i have found idea to create stack_of_[tile+tile_coord]_lists

In c++ something like this: stack< list<unsigned long> > undolist;
Actually instead if unsigned long there was a simple struct (record) which just contains tile_id and its XYZ coordinate.
This way each modification is actually a group. Pop a list from stack, loop through each of its item, get XYZ and tile ID. Put these tile_ids back at these XYZ coords on map. And do this for each LIST item in stack.

Atm im trying to implement this system. Undo first.
Dunno how to do this in Delphi without generics but i will try this in a DLL again.
I already can successfully receive and send block_data to / from C++ DLL.

User137
03-08-2013, 05:37 AM
You could save a new undo-point of the map when there has been at least 2 seconds of no mouse-down events (but mouse must have been clicked at least once for undo saving to happen). That way you can reduce the amount of undo storing, and you wouldn't need to save undo-point in the mouse-down event, which would always make a small lagspike.

hwnd
20-08-2013, 07:13 PM
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.

SilverWarior
20-08-2013, 08:51 PM
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. :D

User137
20-08-2013, 09:49 PM
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.

hwnd
24-08-2013, 09:21 PM
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?

SilverWarior
24-08-2013, 11:42 PM
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.

hwnd
25-08-2013, 08:18 AM
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):

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.

User137
25-08-2013, 02:35 PM
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().

hwnd
25-08-2013, 03:37 PM
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.

User137
25-08-2013, 04:14 PM
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:

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.

hwnd
25-08-2013, 04:28 PM
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.

hwnd
10-09-2013, 08:05 PM
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.

SilverWarior
10-09-2013, 09:38 PM
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...

It is posible that your graphic card on your laptop doesn't natievly support all the graphic functions your application is using and therefore graphical engine fals back to use software rendering which is being done by CPU itself.

User137
11-09-2013, 01:21 AM
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.
That is the standard way to render all models, to reuse same vertex indices if possible. I'm not sure if this is helpful at all, but here is code generation for cube, plane, sphere and torus models with face indices, each with segment parameters:
https://code.google.com/p/nxpascal/source/browse/trunk/src/nxModel.pas#1733

I don't understand how the TRSI demo works, OpenGL shouldn't be able to handle that kind of vertex record

TVertex = record
{ Position }
Pos: Integer;
{ Normal }
Nrm: Integer;
{ Texture coords }
u, v: Single;
end;
Index for position, normal and textures is always the same, you can't customize it. This seems more like a "guideline" structure to build real array later that OpenGL will then use. I'm trying to keep away from having 2 instances of model arrays in memory, and only have that which OpenGL uses.

A cube for example cannot share all the 8 vertices it has. Because in the corner points there are 3 different variations of normals and texture coordinates. So the amount of vertex/normal/uv-indices that cube has, is 6 faces * 4 vertex_per_quad = 24. That would be drawn with either 6 quads, or 12 triangles. And no, vertex indices will not speed up rendering, it will be as fast as vertexarrays using the coordinates directly. But you can save some memory with indices, especially with models that have smooth triangle-connections such as sphere. That's 1 of the sweet cases where all the vertices can be linked together.

hwnd
11-09-2013, 08:17 PM
Ok, i will use vertex arrays. I already did this on the copy of editor in my laptop but i dont have it near me atm.
Lighting demo just uses that custom record to make things "easier"
http://www.pascalgamedevelopment.com/showthread.php?13408-Dynamic-Lightning-with-lot-of-lightsources

I have plan to use this later on my editor for lights.
Only version i have found that doesnt use 3D textures or some special function that only new hardware supports.

The demo is not made by Micronix, unless he is the same person. Original author specifically states in included readme.txt that unless you have really new hardware with 3D textures available then you can make this easier, but for the ones who dont have this this is the way. But if Micronix wouldnt post it, i would never have found this one.

I really like this lighting demo. Best i have found.

hwnd
17-09-2013, 08:18 PM
Yesterday worked a bit on the thing again and finally took decision not to mess with minimap anymore and use the "ground_type" flag from map to actually build some usable minimap.
Works and looks pretty well:
http://i3.minus.com/iFtIhziUoahv3.PNG

Blue is water obviously. Green is field, gray are pavements, and darkgray roads.
I tried to find better method, but they are too slow.
This current one is fastest.
Tried to get average color for tiles, but its too slow, because of ~500 tiles loaded for map.
If not more.. But colors were much better but algorithm needs rewriting.

Maybe should make sheet of tiles and get average colors of that?
I have seen something like this done in one open source Delphi game. I even downloaded src from svn. But still i dont understand everything in it.
Editor src.
https://code.google.com/p/castlesand/source/browse/#svn%2Ftrunk%2FKaM Editor

User137
18-09-2013, 01:43 AM
Is the map like 3D with different layers, or flat plane of tiles? If there are layers, it might at least look best by finding the "roof-block" and plotting its color. You can get roof-block by starting searching from sky/height-max level downwards, until you meet a block that is non-empty. (And you could cache this information for later use in a byte-array)

As for color averages, OpenGL can do that for you. If you for example wanted to draw a roughly blurred map of 32x32 world, using only every second tile of it:
- Initialize a 16x16 texture with GL_LINEAR.
- Plot every second tile to it.
- Render the texture with any size quad.
(Obviously this is just a bad example. It'd be better to use 32x32 texture for full details.)

But also some simple algorithm if you have to do it manually:


For-loop through tiles from 0 to MapWidth-2, 0 to MapHeight-2:
color.R:=(col[x,y].R + col[x+1,y].R + col[x,y+1].R + col[x+1,y+1].R)*0.25; // Average Red
// Same for Green and Blue channels

SilverWarior
18-09-2013, 01:09 PM
Maybe should make sheet of tiles and get average colors of that?

That is exactly what you should do.

SilverWarior
18-09-2013, 01:18 PM
I have seen something like this done in one open source Delphi game. I even downloaded src from svn. But still i dont understand everything in it.
Editor src.
https://code.google.com/p/castlesand/source/browse/#svn%2Ftrunk%2FKaM Editor

Wait that is the souce of Knights and Merchants remake.
I have been in contact with lead developer (atleast I think) some time ago (exchanging some ideas and expirience) and I got impression that he was verry open in making discusions about the game, how certain things works etc. I even got a few tips and suggestions from him about something compleetly different.
So I suggest that you just go and contact him or other developers if you don't understand some ascpects of their code. I'm quite sure all of them will be able to offer their help to you.

hwnd
18-09-2013, 08:13 PM
The world is 256 * 256 * 8 (X,Y,Z) always, just the blocks and their faces matter. Some faces are textured some not.
I only check for AIR blocks that contain no faces, this speeds things up a bit.

Map has 8 "layers" (0..7) in Z coord, from top to down. Its a top down view game.

Looping through ~500 tiles and getting TBITMAP for them and then doing pixel stuff on them is pretty slow.
Maybe i should reuse the actual texture data i already created from tiles. Instead of doing another read for same tiles second time.

I once talked about here how one GTA1 editor shows so nice minimaps. It only works on Win9x. Fails on NT with "Failed to create empty document". MFC app. I will try to get the BMP of minimap and analyze that. Maybe i will figure out how he is able to create minimap so fast or at least whats the tehnique, will try to analyze some area of minimap and actual tiles that are used in map at the same place.

User137
18-09-2013, 11:15 PM
You can calculate once at beginning of program what color each tile type means. Then it becomes very fast to just use that color table for each map tile. What still remains is refilling the texture when map updates.

hwnd
21-09-2013, 12:24 AM
Ok, i did stupid mistake. And i got better and faster average color calculation using scanlines: http://www.delphimaster.net/view/2-1180783872/all#PageTop

I was calculating this for every pixel 64x64 and in a third loop. Thats why it was terribly slow. I really should not code at nights and after the work when im very tired.

Now i just get avg color for each of the 992 tiles and store it in a 1D array of TColors:

tileColorIndexes: array[0..991] of TColor;
Later i just loop through map and set minimap pixel color according to: tileColorIndexes[tile_id];

But i still have to optimize a bit. Just do reading tiles once, not twice. But anyways, here are the results using average colors. Amazing how good the minimaps look right now.
I still have to think about the logic for the transparent faces (tiles), so here is one with transparent disabled and second one enabled. The first one with lots of black pixels is the disabled transparency version.

http://i1.minus.com/jbaBwpWlzEbqGI.PNG

Second
http://i4.minus.com/jbp6CV6TRHqEpG.PNG

hwnd
08-03-2014, 12:44 PM
EDIT: Nvm, got it working it seems. Was looking over my code, thinked a bit and removed one line: pnlRenderMouseMove(Sender, [ssLeft], X, Y);
from MouseDown.. event. Because it messed up some things and i just now discovered that i actually implemented better thing in MouseDown.

Basically calling "pnlRenderMouseMove" even in MouseDown was needed for selectionboxes to clean up, so after single click anywhere on map there will be only one selectorbox.




Strike that all.
Working on this thing again after very long break.
I have some problems with selectorboxes. It basically works, but it picks the objects behind the selectorboxes.
It probably has to do with objects Z ordering or something.

It goes through the selectorobjects and picks the tiles behind it.
I can detect the coordinates of the picked selectorbox cube and face of it but for some reason it goes through the selectorboxes. I tried to "pick" them first (by moving code for picking on the top of the code for picking map cubes) and then actual map cubes but it didnt change anything.

I tried to set glDepthMask(FALSE); and true, nothing changed. Just worse.

Im doing the picking like in nxPascal picking demo. Spheres at specific position, if ray touches spheres i loop through selector vertex coords.

Any ideas what should i try? So if ray hits the selectorboxes it will not go behind them.
Here is pic with arrow, behind the arrow it picks the map cubes (the blue / yellow ones). But it shouldn't.


http://s7.postimg.org/8y7amf1a3/arrowat.jpg

User137
11-03-2014, 01:11 AM
I did find in some apps that calling mousemove in mousedown is acceptable solution. But it has to be last line of the MouseDown event, and you would change it to

pnlRenderMouseMove(Sender, Shift, X, Y);
But you got it working without it so i would not suggest re-adding ;)

hwnd
12-03-2014, 10:35 PM
Ok, but still i have problems with selectorblocks.
I have some ideas why it goes through the main tiles, probably because of that selectorblocks "spheres" and map blocks "spheres" that i use for picking are in same place.

I can detect if selectorblock is under mouse and when its not, but its not enough. I guess i have to check if selectorblocks are the first ones under mouse or are they "lower".
Some kind of Z sorting is needed or something.

Im not sure.

SilverWarior
13-03-2014, 08:18 AM
How about splitting picking code into two stages:
1. You do checking to see if your mouse is over selectorblock (only checking those sphere that are used for detecting selecboxes. If your mouse is over selectorblock you end here else you go to second stage. In order to achieve better optimizatio you may add aditional logic check to see if secetor block colision is even needed (depending on your editor implementation you probably won't need this at all times) if not you simply skip to second stage.
2. Here you do checking to see above which map cell is your mouse.

hwnd
13-03-2014, 09:02 PM
Well if you look at this that way then its already is 2 stage. Well kinda...

One piece of code is picking map blocks and second below it is picking selector blocks.
Its just copy/ paste of picking code with slight modifications for selector blocks.

I dont know if you meant that but if not then i should try it. Have to think a bit.
Its almost perfectly working atm but just 1 (ok in worst case 2) problem(s) still exist.

I will devote more time to this today, maybe whole night and will try different things.

hwnd
14-03-2014, 10:10 PM
Seems that i got it:
Here is the small pic (thanks to Greenshot and Paint.NET for neat features):
http://s27.postimg.org/y3derebg3/arrowfix.png

You see arrow and dotted lines. The dotted lines just show how the selectorblock looks like below (!) main map block(s) tiles.
If you could see through that (ER) tile below mouse cursor you could see one of the faces of the selectorblock (in this case BOTTOM face).

And the problem was, it "picked" or detected that face and didnt move selectorblock to the position where this white mouse cursor actually is.
Because it "picked" that bottom face, it "saw" that coordinates are same and didnt move it.

Now i used nxPascal picking demo pieces to actually make it work. I was thinking about distances and surprisingly it seems to work fine. Tried different angles and stuff..

with intersect do
d:=hypot3d(rayPos.x-x, rayPos.y-y, rayPos.z-z);
if d < nearD then
begin
nearest:=i; nearD:=d;

I use value of "d". I take one "d" (D1) value from picking of main map blocks and second (D2) from the picking of selectorblocks.
So if D1 < D2 then cursor is probably on some side of the selectorblock and not on the top (LID face) of it. If D1=D2 then its on the top of the LID face.

I will do some more checks to really make sure it works in all cases.
Then i can continue with other stuff.

EDIT: I could just move selectorblock to the actual clicked position, no problem. But this way i cannot "pick" selectorblocks from any position (air or ground). This now works and the above stuff i explained seems to work.

2 weeks and finally, working solution. Again thanks to nxPascal. I couldnt do anything without it. Thank you User137!

hwnd
21-03-2014, 10:30 PM
In original editor when you hold down Shift key and right mouse button at the same time and move your mouse either up and down or left and right then you can zoom camera in and out.

I move mouse up, camera zooming IN, i move mouse down, its zooming OUT.
Also if i move mouse to the left its zooming in and if i move to the right, its zooming out.

I tried to implement this in my editor but i dont understand how it calculates the zoom value according to mouse X,Y coords.
I can make it work for either up/down or left/right but not for the both of them.

Atm i can zoom in and out with mousewheel, but i would like to make it possible to zoom in / out without mousewheel also.
Because i cant say something like:

camera.z=camera.z-mousex
camera.z=camera.z-mousey


also tried this in MouseMove event:

Editor.ZTranslate:=(editor.mx-x-y);

Not good and not correct at all.
Any ideas? How hard it can be?

EDIT: Nvm, as usual, after posting question, the solution comes by "itself".
mouse.c code here helped me:
http://www.sgi.com/products/software/opengl/examples/win32_tutorial/

ZOOM feature was unused, i tried it and it did exactly what i needed. Ported the mouse coord saving (oldmousex, mousemove, mousedown etc ) to my editor and it works.

How i found it? Googled for: zoom := zoom + mx; gltranslatef

hwnd
03-05-2014, 05:01 PM
Whats the proper way to draw objects with vertex arrays?
Is it better to do this before every single object drawn:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// draw my single object here
// gldrawarrays

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);


Or just do once this at the beginning of drawing every object (all objects)?



glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
for i:=0 to num_objects do begin
// draw all my objects
// gldrawarrays
end;

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);



Whats the better (in performance) to do this?

Im currently using vertex arrays and not drawing that much of objects but still i get 25% CPU usage.
I dont know what causes this CPU usage.

I will try to pinpoint this of course in the meantime, but maybe the vertex array "order" is important.
Thats why i asked


EDIT: one thing i noticed, sometimes CPU usage is 25% sometimes 0.
In the same place of map.

I dont have any antivirus or something. But i do have enabled debug info and stuff.
I decreased visible range by 1, will see if that reduced the CPU usage.

User137
03-05-2014, 05:30 PM
You should change the states just once in that code. All called gl commands slow program down if only a nanosecond, but if constantly repeated they can build up larger lag. But that doesn't seem to be reason for your fps issue, as i assume you already tried both ways?

hwnd
04-05-2014, 05:41 PM
I actually tried "once" method. This seems faster i guess because i call these only once. I also dont see the point enabling/disabling them for every block.

But now i discovered that my vertex array version of DrawBlock eats up my RAM. And it gets very slow.
I will restore the DrawBlock from backup and will test if that removes the "memory eating". If yes, then i did something wrong (with sleepy head).

I thought its the map saving procedures that writes invalid map and when loaded damages memory somewhere etc. But the maps are binary equal to original editor maps.
Commented out "DrawBlock" and bug went away. So it is somewhere inside it.

hwnd
04-11-2014, 10:41 AM
Its been a while when i worked on this thingy.

I once wrote here how original editor uses low resources.
http://www.pascalgamedevelopment.com/showthread.php?15030-G-T-A-2-Map-Editor&p=100842&viewfull=1#post100842


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 quickly put together simplest opengl app without nxPascal that uses FormPaint event instead of any (game) loop or timer.
In FormPaint i do

glDraw(); // Draw the scene
SwapBuffers(DC); // Display the scene

In FormResize i do


...
glDraw;
FormPaint(sender);

and CPU usage is small, practically zero. Of course i havent tried to render big map yet, just simple rectangle.
While i resize the form, then the CPU usage goes a bit up and as soon as i stop resizing it goes back to 0.

I think original editor uses same approach with the DirectX.

Because when you modify any block in map, for example change the slope type, then you wont see updates immediately, but later when you do something else.
So it seems its not re-rendering whole scene every frame but only when you click somewhere or change something else.


It may be calls "Paint" event when needed only.


So question is, is this do-able with nxPascal? And at the same time still keep same framerate on all PCs and so the picking also works as needed?


I ask this to reduce the CPU usage which is high, even if you dont do anything. Rendering just makes it go high.

hwnd
16-02-2019, 04:11 PM
Whoah.
Last post from 2014. Time passes quickly.

Was lurking around here, searching for OpenAL Delphi stuff.
Im still working on it.

I have bunch of versions on my hdd's and dvd's.
There are few things added to editor. I dont work on this thing full time.
Sometimes i get tired of all the programming stuff and i need to do something else.
Now i picked it up again.

Dunno when it happened but i figured out the camera rotation problems with mouse and kbd movement.
All this now works ok.
There are animated tiles also. Although the editing of animations is not working atm.
My primary point was to make tile animations work and they do work at the same framerate as GTA2 ones.
There are some more animated things needed, like power pickups, weapons etc... First i must draw them and then animate.

Also some lighting work is done, my primary purpose of the editor is to make it compatible with WIN95 so no shaders for lighting.
Why?? Because i love old op. systems, WIN95 is cool. Love sitting in there.


I managed to figure out how to get like 60 built in OpenGL lights on screen at once and enable and disable them/change their properties.
But usually maximum i need on screen at once is something like 10-15, usually less.
So i can say that the lighting is okay.

I have a code where i added a ped to the city and i can walk around the city.
Collision detection only works on right side of the buildings, have been lazy to implement more.
This is my way of doing things. It motivates me to see "half" working thing and then i can always finish it later.
For me half working thing is more motivating..

Now i mess with OpenAL delphi wrapper and trying to add some sounds to map.
They are "scripted into game", i will not parse scripts atm but i add some sounds by hardcoding (taking data from script).
Like birds on the trees or tower clock ticking.

I want to test 3D sound. So if i walk away from clock then the ticking fades away..

There are no new videos currently.
Im just working on different things and trying them out.


I have idea to actually rewrite it from scratch, using modern Delphi ((10.3 atm), generics etc..), also latest OpenGL with shaders and VBO.
So i can render whole city with 60FPS etc etc.

Will see..

JernejL
17-02-2019, 10:26 AM
Dude, i had a hiatus from gamedev here, and totally missed your whole thread,. This is cool work that you are doing, any gta modder / thinkerer gets special respect from me, i've been digging thru those files and formats for way too much, and i know how convoluted they can get at times, even tho the game looks really simple.

IF you want, i'd like to help you out on your project with my knowledge, afterall i did write the last modern tools for modding gta2 ( https://gtamp.com/gta2/tools/ ) and i also released my sty editor source code, if that still interests you (gta2 sty and gta1 g24 file formats are also very similar, plus i still can help at a lot of strange quirks that you might encounter, like the whole crazy pallette and car delta systems of gta1 and gta2 ).

I've also been a fan of classical gta games since forever, and have my own project that is essentially building a similar game from scratch, as due to limitations of those 2 engines, they can never be brought into modern times with high resolution remastering, plus i think the game mechanics of those games can work really well for a massive online multiplayer game. My game is making really good progress lately, so if you wanted to collaborate on that too, i invite you to contact me, i could use some help.

Project: https://www.pascalgamedevelopment.com/showthread.php?5442-Top-Down-City-Topic-Reboot/page3

Ñuño Martínez
06-03-2019, 01:00 PM
If both you collaborate, that would be result in a greater project.

JernejL
11-03-2019, 06:48 PM
I hope that he messages me, our projects definetly have some large overlap.

hwnd
26-05-2019, 06:07 PM
Hello Jernej

Im still here.
Just noticed that you posted. Month later but..

Any updates on your game?

JernejL
16-06-2019, 10:33 AM
Yes, while i have not published a lot, the game is progressing althru slowly, i've done a lot of optimizations and under the hood stability fixes, i will have a update soon.

Let me know if you need any help with your project, like i said i can still help you a lot with gta1 file formats, if you wish to make importers for that for example.

hwnd
30-06-2019, 07:45 PM
Hi.

Nice, thanks for the help!
I have few questions but they can wait a bit.

I have a tile picker which supports transparency in tiles. So user can see transparent tiles as transparent before even using them.
Also its possible to "Search" specific tile with its index, to avoid lots of scrolling.
Useful if you remember commonly used tiles in specific .sty file.

Currently im implementing unlimited Undo/Redo. Unlimited is not the primary thing here but its just the way it is.
It basically worked but i found few bugs and issues.

Now i remodeled the whole thing. Will see how this one will work. As im now typing this reply here im working on this thing..
In next reply i will let people know how it worked out..

hwnd
21-09-2019, 08:57 AM
Anybody knows is it possible to use shaders without actually using modern GL rendering context?
I mean use some shader code with for example: OpenGL 2.0 ?
Confusing but i have seen some old "legit" OpenGL code with some shader stuff in it.
Or its not possible because of "context" ? I mean older context can't deal with modern stuff and modern code can't affect the old 1.1 commands?
Lets say my app is using 1.1 API only and i want to add shader lighting into it. Not possible?

SilverWarior
21-09-2019, 11:11 AM
From what I can read around internet:

If your app is really using 1.1 API then you will have to fall back to https://en.wikipedia.org/wiki/ARB_assembly_language
But if you are already using Open GL 2.0 then you can already use https://en.wikipedia.org/wiki/OpenGL_Shading_Language

JernejL
21-09-2019, 02:09 PM
You can use glsl in parallel with all existing api, you just turn shader on and off with a function.