News:

Simutrans Wiki Manual
The official on-line manual for Simutrans. Read and contribute.

Hardware accelerated display, OpenGL back-end & Simutrans 3D

Started by eddielexx, January 02, 2010, 03:38:33 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jamespetts

In the context of Simutrans, "besch" refers to an underlying type. For example, an individual vehicle in the game has a vehicle object. That vehicle object has a pointer to a "besch", which is the type of vehicle (for example, a Routemaster 'bus). The "besch" object, of which there is one for each type of vehicle, will have information about that particular vehicle's capacity, power, maximum speed, etc. - all of the things that are the same for each type of vehicle. The vehicle object, meanwhile, will have data about the vehicle's schedule, its current position and speed, the goods/passengers on board it at present, etc. - all of the things that do vary between types of vehicle.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Markohs

That was very useful, thanks james!

Dwachs

My guess would be 'besch' = 'Beschreibung' = description / descriptor.
Parsley, sage, rosemary, and maggikraut.

prissi

Back to images. The images in simutrans are never uncompressed.

The are darked and rescaled and recolored with player color in PIXVAL* data; But not in any common format, teh format is rather (word=16 bit)
skip pixel, length of next data (in words), data word, skip pixel (until w>pixelw)

Look for recode or display_img_xxx (some of them do player color recolering on the fly). You could just add another entry to this structure pointing to a RGBA 16 bit image, which is always generated on load time.

Markohs

Ok, thanks you all for your comments! Working on this now, should be doable, I think the way to go is to create a new resourcemanager for ogre that instanciates the textures on demand, using the functions prissi pointed out. I wasn't aware of the player coulours he pointed, also. Soon I'll know more. :)

http://www.ogre3d.org/docs/api/html/classOgre_1_1ResourceManager.html

Markohs

#180
This is being even harder than I expected. Simutrans models the world as quite a lot of different objects and structures, and the render code just uses all that information and renders it when necessary, taking all that information in consideration.

Even a basic object object like a tree is quite complex, considering it has different images that vary on seasons.

My initial aproach of maping initial 2D images to each tile on map creation/loading and leave them static looks poor now, and not sufficient. To do a complete 3D port of the game will require keeping in sync current simutrans objects with the 3D versions, expanding the currrent objects (baum_t,  gebaeude_t,....) with new functionality, or just with some listener code and subscription.
I don't got a clear idea yet of how to make all this, got to think a bit more on it.

Getting the raw images it's no problem, I've done some coding there already and it's doable no problem.

Just stating this to see if anyone has any idea to share. ;)


Edit: I entered panic too soon, ofc I need way more code to display objects, I just focused too soon on see some results fast, it's not possible. Forget what I wrote. ;)

prissi

Actually, how to compile the branch. The makefile has no preparations on Ogre or whatsoever?

Markohs

#182
mmm.. no, I get an error uploading the vcxproj file, because it's windows CR and the svn rejects it(I know there must be a workaround to make this work but didn't managed to do it yet), but my settings are (replace the paths according your installation):

include_path:
C:\code\CEGUI-SDK-0.7.5-vc10\cegui\include;C:\code\bzip2;C:\code\zlib-1.2.3\include;C:\code\SDL-1.2.14\include;$(OGRE_HOME)\include\OIS;$(OGRE_HOME)\include\OGRE;$(OGRE_HOME)\Samples\Common\include;$(OGRE_HOME)\boost_1_42;%(AdditionalIncludeDirectories)
library_path:
C:\code\zliball\static32;C:\code\bzip2;$(OGRE_HOME)\lib\$(Configuration);$(OGRE_HOME)\boost_1_42\lib;C:\code\CEGUI-SDK-0.7.5-vc10\lib;C:\code\SDL-1.2.14\lib;%(AdditionalLibraryDirectories)
libraries linked in:
SDL.lib;SDLmain.lib;CEGUIBase.lib;CEGUIOgreRenderer.lib;OgreTerrain.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;zlibstat.lib;advapi32.lib;ws2_32.lib;libbz2.lib;OgreMain.lib;OIS.lib


it should compile in linux even I didn't really tried it.

it uses SDL,CEGUI(for basic mouse support, I'll maybe drop that dependency and use just SDL) and OGRE

You can download the binaries (liboost is a prerequisite but gets shipped with ogre) for windows or linux in:

http://www.ogre3d.org/download/sdk/
http://www.cegui.org.uk/wiki/index.php/Downloads

Also, when you generate the executable, you should unpack http://dl.dropbox.com/u/30024783/simu3dfiles.zip in the simutrans directory where you have a working simutrans installation (without the simu3dfiles prefix)

prissi

#183
As you are still early in the project, and after looking into the requirements I start to doubt if Ogre is really a good choice. Especially requiring boost will kick out many plattforms, like Haiku (due to gcc 2.95.xx). Also requiring 200 MB of libraries does neither sounds very performant nor giving small distribution packages ...

Maybe one could consider Irrlicht, as this is even more portable (even on Solaris and with software renderer), has a null device usable for servers, uses anyway 16 bit textures, is smaller and claims to be faster ... but there are of course other still like sauerbraten/cube2 http://sauerbraten.org/,

But in the end it will depend on how easy and performant is the integration with the simutrans world model, i.e. with the current mixture of dynamic stuff (pedestrians, vehicles) and scenery. It seems nearly all engines wants to maintain their own scene. Then it boils down on how well they handle millions of tree objects and changes to them.

I think one needs to create a map including billboard trees and some roads and compare the engines again. Preferable over one year including a full season cycle with trees spawning/dying and so on to finally decide.

Btw, nearly all houses in pak.german64 are rendered by a single program. The are very detailed, but reducing them to a simple texture and a simple shape seems possible when the next stage is required.

Markohs

#184
Quote from: prissi on June 15, 2011, 10:17:03 AM
As you are still early in the project, and after looking into the requirements I start to doubt if Ogre is really a good choice. Especially requiring boost will kick out many plattforms, like Haiku (due to gcc 2.95.xx). Also requiring 200 MB of libraries does neither sounds very performant nor giving small distribution packages ...

Well, the requred dll's are about 16 Mb only, it's the SDK that are about 200 Mb in size.

About libboost and Haiku (had no idea that OS existed still :) ) you are right, I didn't even think on that.

If they have no libboost, it will break compatibility on them, libboost is mainly used for threads support afaik. Is there any other plattform affected about this? I'm talking about plattforms with OpenGL or Direct3D support, ofc, that requisite is not avoidable I guess.

Quote from: prissi on June 15, 2011, 10:17:03 AM
Maybe one could consider Irrlicht, as this is even more portable (even on Solaris and with software renderer), has a null device usable for servers, uses anyway 16 bit textures, is smaller and claims to be faster ... but there are of course other still like sauerbraten/cube2 http://sauerbraten.org/,

I'll have them a look, yes you are right. I didn't coded so much and I binded myself to Ogre maybe too early without evaluating the alternatives.

Quote from: prissi on June 15, 2011, 10:17:03 AM
But in the end it will depend on how easy and performant is the integration with the simutrans world model, i.e. with the current mixture of dynamic stuff (pedestrians, vehicles) and scenery. It seems nearly all engines wants to maintain their own scene. Then it boils down on how well they handle millions of tree objects and changes to them.

Yea but that's a inherent idea of any 3D engine, the engine has to "own" the world model, to be able to load/unload the objects/textures/materials when necessary to the videocard, I think there is no way to avoid that, even using bare OpenGL requires you to fetch them to the library, and using openGL directives to "modify" the loaded world.

Quote from: prissi on June 15, 2011, 10:17:03 AM
I think one needs to create a map including billboard trees and some roads and compare the engines again. Preferable over one year including a full season cycle with trees spawning/dying and so on to finally decide.

Btw, nearly all houses in pak.german64 are rendered by a single program. The are very detailed, but reducing them to a simple texture and a simple shape seems possible when the next stage is required.

Ok, I'll proceed like that, get to the point that this code is able to render some spreites and compare with other engines.

BTW, excuse me for my poor english, I try to express me clearly, and undestand you the best I can. :)
EDIT: According to http://en.wikipedia.org/wiki/Haiku_%28operating_system%29 they menction they will support GCC 4 in a future release. This sounds a bit strange, Solaris has the same ABI since Solaris 2.5 and binaries are executable even today's version 10, dunno why operating systems developers don't follow this scheme to mantain backwards-compatibility. Well, not the point, through.

prissi

Actually the solaris compiler is pretty incompatible with gcc and C99 and would have (at least when I was programming for real Suns in 2000) surely choked on boost; maybe even simutrans back then.

The problem with an OO operation system like haiku or MacOS is, that is actually very tightly bound to the object modell of the compiler. Very simple example is the old old 68k MAC need pascal strings while windows/GEM used C-strings. That is the origin why mac new line is 13 instead of unix 10 or windows 13 10 ...

But back on topic: I think performance will be deciding factor. boost will not run (or will not be favourable) on small machines like smartphones where 16 MB of DLL in 128 MB main memory can make a difference; but then those machines might anyway not be able to run any big 3D game at all.

From a little more googling it seems like Orge is the windows of the 3D libs, large, loaden with features, but neither small nor fast (and imho not so nicely documented). Irrlicht claims speed, sauerbraten memory footprint. But first lets get something to work within Orge as you have it already working; it appears to me that all libs use quite similar concepts, so switching might be not too bad if needed.

Markohs

This must be trivial for you I'm sure, but I've been debugging this for some time and I don't see my error, I extract the images and plant them on a square of image[bild].base_w x image[bild].base_h, I "extract" the shape with the following code:


void display_get_base_spritebuffer(unsigned bild,unsigned short* buff){

if (bild < anz_images) {
PIXVAL *src,*dst;

/* src=images[bild].base_data + images[bild].base_y*images[bild].base_w;
dst=(PIXVAL *)buff;*/

src=images[bild].base_data;
dst=(PIXVAL *)buff+images[bild].base_y*images[bild].base_w;


KOORD_VAL h=images[bild].base_h;

if (h<=0)
return;

do {
uint16 runlen = *src++;
do {
// first, transparent pixels
while(runlen--){
*dst++ = 0x8000;
}
// colored pixels:
runlen = *src++;
while (runlen--)
*dst++ = *src++;
}
while ((runlen = *src++));
} while (--h);
}
}


And I get the following result:

http://dl.dropbox.com/u/30024783/Untitled.png

What am I doing wrong, is that working as expected? why images "deform" on the top and the bottom while the middle part remains good, are they mean to be drawn on a "diamond" and not on a regular square?

VS

#187
Apparently it's not as easy as dumping a buffer.

It's clear that images that fill 100% of width are unchanged, but the others are distorted terribly. Parts of images that fill 100% look ok, but are still shifted, with wrap-around. (I do know these images, heh)

My guess is that you get some part of in-memory compression horribly wrong. I think each scanline has a start/end offset of some sort. The shear-like effect would then come from (not?) shifting the scanlines in the whole buffer by some missing spaces. The effect is then cumulative since you have one continuous buffer... And since the middle part of image is usually widest, it is not distorted that much or less.



edit: I hope it's easy to understand, it's past midnight here, I'm terribly tired and forced to still work mentally ::( Family uncaring for their deadlines but technically disabled, yay.

edit2: Yes, after you take into account the (variable) spacing on sides, an average image "content area" could be roughly diamond-shaped, especially on bottom. That's just an after-effect though.

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

Markohs

#188
Thanks VS, I'm sleepy too hehehe ;)

At the end I managed to fix it, it caused the effect you menction. I was ignoring the initial xoffset, so I was drawing a image of size x,y in a buffer sized x+num,y+num, that was originating the deformation No, I was ignoring the x_start coordinate exactly like you said. :) I also manged to get the alpha blending working.

Thanks a lot!

The "correct" code is:


void display_get_base_spritebuffer(unsigned bild,unsigned short* buff){

if (bild < anz_images) {
PIXVAL *src,*dst;

src=images[bild].base_data;
dst=(PIXVAL *)buff+images[bild].base_y*images[bild].base_w;


KOORD_VAL h=images[bild].base_h;

if (h<=0)
return;

for(  sint16 y=0;  y<h;  y++  ){

PIXVAL *line = ((PIXVAL *)buff) + (y*images[bild].base_w);
uint16 x=images[bild].base_x;

uint16 runlen = *src++;
do {
// first, transparent pixels
while(runlen--){
line[x++] = 0x0000;
}
// colored pixels:
runlen = *src++;
while (runlen--)
line[x++] = (*src++ | 0x8000);
}
while ((runlen = *src++));
}
}
}


And now looks a bit better:

http://dl.dropbox.com/u/30024783/Untitled2.png

prissi

Its may comes to late, but there is a code in patches which exactly converts an images into a rectangular bitmap ... (dump_png.diff)

Markohs

oh, I see... hehe :)

Well, anyway I was still having problems with some images, but here is a hint I found in that diff:

uint16 width = max( 192, besch->pic.w+besch->pic.x );

The problem it's for example the bild number 8 if I recall correctly, that had x=0,y=0,width=10,height=10, that should be a image that fills in a 100 PIXVAL buffer, but no, accounts for a total of 128 pixels after the RLE decompression. That caused me some segmentation faults, strange.

Maybe that 192 magic number is the min size of a buffer, I'll have it a look, wanted to compile a pak myself and look at the pak creation utilities code to understand it better.

But well, bitmap extraction is more or less done, now I'll move to the next part, extracting a bitmap of the whole dinge, because the image cutting that's done for simutrans objects doesn't apply to simutrans3d objects, for example those large office buildings that fill 2 or 3 tiles should mean just one 3D billboard, not 3.

Working on it. :)

Markohs

Quote from: prissi on June 15, 2011, 02:03:39 PM
Actually the solaris compiler is pretty incompatible with gcc and C99 and would have (at least when I was programming for real Suns in 2000) surely choked on boost; maybe even simutrans back then.

Yeah, but that's the compiler per se, I was talking about the binary, You can execute a binary compiled in a Solaris 5.1 machine in a actual solaris 10 machine, without doing *NOTHING*, they are completely compatible backwards, it even executes SunOS 4.0 binaries, given they were compiled for sparc, not motorolla or another chip.

Quote from: prissi on June 15, 2011, 02:03:39 PM
The problem with an OO operation system like haiku or MacOS is, that is actually very tightly bound to the object modell of the compiler. Very simple example is the old old 68k MAC need pascal strings while windows/GEM used C-strings. That is the origin why mac new line is 13 instead of unix 10 or windows 13 10 ...

Yea, didn't think on it, you are right, didn't knew about the pascal lines and MacOS. But even Apple is a good example of backwards-compatibility, if even sold dual processor machines when they changed from motorola to powerPC, to be able to execute old applications, for some time.

Well, sorry about the oftopic, I'm a sysadmin and I like old machines. ;)

Quote from: prissi on June 15, 2011, 02:03:39 PM
But back on topic: I think performance will be deciding factor. boost will not run (or will not be favourable) on small machines like smartphones where 16 MB of DLL in 128 MB main memory can make a difference; but then those machines might anyway not be able to run any big 3D game at all.

From a little more googling it seems like Orge is the windows of the 3D libs, large, loaden with features, but neither small nor fast (and imho not so nicely documented). Irrlicht claims speed, sauerbraten memory footprint. But first lets get something to work within Orge as you have it already working; it appears to me that all libs use quite similar concepts, so switching might be not too bad if needed.

I have to agree with you, I'll try to arrange the code in a way that allows to switch the rendering engine code wiithout much effort, you made me curious about Irrlicht now, I'll have it a look.

And no, Ogre3D has not a great documentation. Most of the info I need I find it on the wiki tutorials or the forums.

prissi

So from documentation I like Irrlicht more ...

But on topic: Maybe first only model tree as billboard, as they will probably stay as those even ingame. But for hoses, I think real modells are needed. Some stations are in ravens renders. You can find them on my hp:
http://www.physik.tu-berlin.de/~prissi/simutrans/ for instance Almuthof Station.rar Not sure how much polygon this is though. But the shape is simple enough I think.

Markohs

#193
 Well, the diference is not so huge, compare:

http://irrlicht.sourceforge.net/docu/classirr_1_1video_1_1_i_texture.html
http://www.ogre3d.org/docs/api/html/classOgre_1_1Texture.html

One thing I liked from what I read of irrlicht appart from speed and lower memory footprint was:
Quote
Extreme stability. Most libraries for realtime applications crash when the user does something the library programmer did not expect. This is different in the Irrlicht engine. It prints out a warning to (debug-)log and continues, always trying to keep on running.

This can make the development smoother, and the project more stable. I experienced quite a lot of crashes from ogre already, and well, they are not suposed to happen if you code things right, and catch exceptions, but well, maybe it's too picky.

Also, from what I saw so far, Ogre renders look way better than irrlicht ones.

We'll see, the only way to know is trying, I'll implement terrain + sprites + models with both, and then we can compare.

Markohs

Quite a piece of art that station. This starts looking very nice, having some problems with blender textures importing, I completed a "learn-blender-in-an-hour" youtube video watching session. :)

prissi

I think with Irrlicht, one could stay with 16 bit bitmaps, this could really make a difference. At least hen thinking of simutrans 15 bit pak files ...

But since you are the only one so far go ahead. I am pretty sure soon you will know more about 3D programming than any of us here ;)

Markohs

#196
Quote from: prissi on June 18, 2011, 09:46:01 PM
I think with Irrlicht, one could stay with 16 bit bitmaps, this could really make a difference. At least hen thinking of simutrans 15 bit pak files ...

Ogre supports 16 bit bitmaps too, that's not a problem.

Quote from: prissi on June 18, 2011, 09:46:01 PM
But since you are the only one so far go ahead. I am pretty sure soon you will know more about 3D programming than any of us here ;)

Well, I try to, prissi, learning a lot this last month, I just had some 3D theory plus OpenGL basics  from the degree in computer science, not that I'm really a expert in 3D, but learning.

About Irrlicht, I think I'll end deciding to use that engine for the project, but first I want to end what I started, to make the decision based on solid motivations. :)

But I also know you prefer Irrlicht because it's german/austrian software!! ;) (joking)

A screenshot of the progress so far (coudn't code much since I had to spend quite a lot of time to learn how to use blender, had no idea :) )

http://dl.dropbox.com/u/30024783/Untitled3.png

Markohs

Can anyone translate me this from german please? :)

   /**
   * Dies ist der Zeiger auf den Besitzer des Objekts.
   * @author Hj. Malthaner
   */
   uint8 besitzer_n:4;

alexbaettig

I hope that helps,

* This is the cursor on the owner of the object.
Besitzer = owner

VS

Pointer to object owner.

I guess "pointer" should be understood somewhat loosely though ;)

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

Markohs


alexbaettig


Markohs


prissi

Looks very nice concerning that most came from 2D 15bit bitmaps! Maybe the shadows are a little deep?

Markohs

Yea, I was making some tests on lights, I have to get the ambient light brighter. :)

Right now I'm concerned on the effect the transparent pixels create, they fade from white to the pixel colors, and generates strange effects:

http://dl.dropbox.com/u/30024783/Untitled5.png

I'll see what can I do to fix it.

prissi

Well, I think for your project best would be trees without shadow. Then the white borders would be fine. Maybe just modify the graphics a little. YOu can look into the pak64 svn for the images. SInce the shadows are very dark pixels in a rectagular pattern, those could be even removed when creating the images in memory. Try the following code for decode_img():


/**
* decodes an image into a 32 bit bitmap
*/
void bild_besch_t::decode_img(sint16 xoff, sint16 yoff, uint32 *target, uint32 target_width, uint32 target_height )
{
// Hajo: may this image be zoomed
if(  pic.h > 0  && pic.w > 0  ) {

// since offset is implicit within image, do not "xoff += pic.x;"!
yoff += pic.y;

// now: unpack the image
uint16 *src = pic.data;
for(  sint32 y = yoff; y < pic.h+yoff; y++  ) {
uint16 runlen;
uint8 *p = (uint8 *)(target + max(0,xoff) + y*target_width);
sint16 max_w = xoff;

// decode line
runlen = *src++;
do {
// clear run
p += runlen*4;
// color pixel
runlen = *src++;
if(  runlen==1  &&  src[runlen]<5  &&  *src==0  ) {
src += runlen;
p += 4*runlen;
max_w += runlen;
}
else {
while (runlen--) {
// get rgb components
uint16 s = *src++;
if(  max_w>=0  &&  max_w<target_width  &&  y>=0  ) {
if(  s>=0x8000  ) {
// special color
*p++ = 0;
*p++ = rgbtab[s&0x001F]>>16;
*p++ = rgbtab[s&0x001F]>>8;
*p++ = rgbtab[s&0x001F];
}
else {
*p++ = 0;
*p++ = ((s>>10)&31)<<3;
*p++ = ((s>>5)&31)<<3;
*p++ = ((s)&31)<<3;
}
}
max_w ++;
}
}
runlen = *src++;
} while(  runlen!=0  &&  y<target_height  );
}
}
}

Markohs

Thx for the code, integrating it now, I managed to fix the white near transparency, it's due the way the 3D engine handles the bitmap, it scales it to a bigger scale, and since I was using 0x7FFF as a transparent color, taht was "transparent white", what made the transition to not transparent pixels start on pure white, changing it to 0x0000 made the trick, they start from black and look way more natural.

Looks like this now:

http://dl.dropbox.com/u/30024783/Untitled6.png

I'll tell you when the code is integrated, I have some things I've been thinking about how to integrate 2D and 3D items on this simutrans3D versions and hear your oppinions.

Soon more, thanks. ;)

Markohs

#207
Well, the thing I wanted to comment to all developers is:

Right now I think there are 2 ways implement the Simutrans3D project, one is a complete back-wards compatible version and the other is a more pure 3D version.

The basic problem are the sprites they are not so easy to move from the 2D version to the 3D version, because some problems arise:

1) Positioning the sprite: I see various approaches to this subject, on the begginging I thought on just planting the middle of the tile, like this:



This doesn't really work most of the times, because most of the times, the sprites are like this:



I could place them on top of the green circle I marked, and than whould work, if the camera was facin one of the four isometic angles.

Another option is placing the sprites allways on top of the white line, on the point closer to the camera, that whould look better, but the floor whould show up a lot.

As a conclussion, sprites won't show up good ever, only from the 4 fixed isometric camera angles. That makes me consider limiting the camera to those 4 points of view, and to not offer a free camera at the moment.

2) sprites have more problems, like for example the bitmaps that have 2 layers of images, the base and the "after" one, that happens on bridges or stations for example, that I know, prom pak128, one bridge fabio made:



The images without road are meant to be painted after the road, and the possible vehicle, are drawn. This is doable in the 3D space I  think, maybe playing with the render passes or the Z-Buffer ordering, I have to investigate this further, but it certainly makes things quite harder. 3D shapes do not suffer from that problem.

3) As prissi pointed out, current simulated shadows are a problem too, but I could maybe try to detect them and remove them.

And maybe more problems I can't think about now.

So, my main idea was just porting the game making an exclusive usage of 2D shapes, and open the door to add 3D models for every item, like vehicles, buildings, gradually, because I think we maybe lack enough artists to make 3D versions of all the items, and it whould be cool to just being able to play pak128, for example, just with 3D rendering. I think this is possible, and I'd like to make it work. Even thought what whould really be amazing is a full 3D world, but lots of code and artist creations are needed for that still.

The blender files from some simtrans images I saw already are a huge help, but require work to plu into the game, they require to be transformed into a single mesh, scaled to correct dimensions and the materials have to be changed lightly. They require work, artists work.

So well, I just wanted to share this tought and hear of any of the coders/artists ideas, anything is welcome. :)

jamespetts

I have some doubts that using a 3d engine to render 2d sprites will be much of an improvement on what we already have - in my view, we'd be better off with the option (selectable at the pakset level) of either using a full 2d engine or a full 3d engine. Something half-way between the two is likely to be worse than both.

Note that almost all Pak128.Britain graphics were made from 3d models and should be relatively easy to make into 3d models for the game if there is an easy exporter for Blender.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Markohs

 I get your point, makes sense, maybe I should focus 3D and just leave sprites for basic items like trees or pedestrians. More comments? :)