Building Comanche 3D in less than 100 lines of code (UPDATE)

Hi @Eugene Dakin !

I’m having about the same results. Haven’t looked into Tomas’ code yet, but I suspect the mix of timers and threads is causing the low FPS. Could you run your tests with my original version with memoryblocks and pointers? http://gorgeousapps.com/ABComancheMB.zip

btw. How is your new book doing? :slight_smile:

Okay I’ve googled a bit around and found this as best solution for further speed improvements:

http://irrlicht.sourceforge.net

It’s an open source, x-platform (Linux, Win, Mac OS) 3D engine and as far as I know there was already a wrapper for Realbasic named Franklin 3D. But the website seems to be down and I can’t find anything about this anymore. :frowning:

@Eugene: Have you tried compiled apps?

Hi Alain,

The Xojo Web book is coming along, and is getting big - thanks for asking :slight_smile:

I tried the Comanche 3D version with memoryblock and pointers on the three OS’s, and ran both of them in IDE and compiled mode. These are on real systems, no Virtual Machines. I also added a Frames-per-second measurement to accurately get the refresh rate, and here are the results:

Windows 8.1 IDE: 7 FPS
Windows 8.1 Compiled: 13 FPS

Maverick IDE: 7-8 FPS
Maverick Compiled: 13-14 FPS

Ubuntu 14.04 (32 bit): will not run. The screen appears with the first screen shot in full colour, and then Xojo times-out.

To increase the speed, I suggest using a thread-timer combination. Have the thread perform the lengthy calculations because the thread is extremely fast. Update the Canvas Graphics at a rate of about 30 FPS with the timer, which should give smoother looking graphics. The graphics timer number will need to be adjusted based on each system, and this method would work to improve the ‘feel’ of the game.

This Comanche 3D program looks GREAT!!

Thanks or the update!

Great to hear!

So analysing your benchmarks, I noticed OSX has a slightly higher range and Windows is consistent :slight_smile:

I think that’s what Tomas tried. If I find some time, I look further into this.

LOL.

After trying some troubleshooting in Ubuntu 14.04, I found out the Xojo IDE does not like the method called Update, I changed the method and method calls to Update1 and will do some more troubleshooting.

Found something interesting - maybe something with Xojo in Ubuntu 32-bit?

The method ‘Update’ in Ubuntu wants to default to ‘UpdateNow()’ and will auto-change to this method name. Does anyone know why this may be significant in either Xojo or Ubuntu ?

In the method Raycast, if the entire ‘while i<r-20’ loop is commented, then the program runs fine on Ubuntu. If I uncomment ONLY this bit of code, the program refuses to work:

While i<r-20 i = i + 1 'other large blocks of code here are commented wend

What I don’t understand, is if the i = i+1 is changed to i = i + 10, then the program works (albeit, slowly).

For some reason, the Xojo IDE doesn’t seem to like i = i + 1.

Created feedback 34921

From another place on the internets comes this message.

Just wondering what’s happened to your other products,
Franklin 3D and Franklin audio. The web sites come up as
“Website disabled”.

They will come back eventually. We are in the middle of a huge, long overdue
site update for Paradigma Software’s main site.

The Franklin site got hacked in a big way some time ago, so when we get the
new Paradigma site done we will bring back Franklin.

That was posted by Lynn Fredricks, so if you want to know more about it, you need to ask him.

You can download Franklin 3D from here: http://www.valentina-db.com/downloads/f3d/

Unfortunately doesn’t support Linux (yet?).

I’ve been working on how to tile this terrain in OpenGL. The problem was a full tile is two million triangles and drawing just two of them slows framerate. Instead the tile is broken 4x4 into 16 ‘cells’ and only those cells in view are drawn. There’s still a limit to how many can be drawn, currently it can handle a grid up to 8 cells away from the camera. Depending how the camera’s Far value is set the horizon is either slicing through geometry or cells pop in as you get closer. This is something I really want to improve somehow but if you stay low within the mountains it can be effective.

To further improve performance each cells geometry has medium and low res versions used at distance (mipmap). This part isn’t finished yet, there’s a seam between different res cells, but it can be turned off and only full res cells are drawn which fit seamlessly while keeping framerate somehow.

Thanks to Alain for the maps listing, they’re all included. Now if I could just find a chopper model…

Download elev2.zip 21.4MB from this page
https://drive.google.com/file/d/0B97iUmOCTUYdUm8yZUt6dzNGTGM/edit?usp=sharing
At the very top is the actual download icon/link. You may have to wiggle your mouse for it to show up.

Look in WindowFramingMip3 for a Note with more info.

Works on Mac, should work on Windows with Glu32.dll installed and App.getResourcesFolder edited to return the right folder. Linux will need declare work, not sure.

Looking very nice Will! Running smooth :slight_smile:

Had to change some things for windows:

  1. In Windows enable GdiPlus (for new picture(w,h) to work)

  2. in new EZFont() had to change Monaco to Arial as this font does not exist on Windows

  3. added in the GetResourcesFolder()

    #if DebugBuild then
    'return ? //update these to locate the Resources on Windows
    return GetFolderItem("").Parent.Child(“Resources”)
    #else
    return GetFolderItem("").Child(“Resources”)
    'return ?
    #endif

btw, did you read about the Memoryblock trick to get the BGRA data into a memoryblock without using a RGBsurface? Note that this data is flipped upside down (OpenGl can solve this by changing coordinate systems, but I don’t know the impact on the rest of this)

Dim mb as MemoryBlock

’ get the pixel data, but as it is in BMP it is flipped upside down and in BGRA format
’ the first 54 bytes are the header, so remove them. the rest is BGRA data

mb = texture.GetData(Picture.FormatBMP)
dim BGRABitmap as Memoryblock = mb.StringValue(54, Height * Width * 4)

Not sure it’s usefull, but who knows :slight_smile:

Thanks for tips on getting it to work on Windows Alain.

I had to add one more change to prevent a runtime error on Windows. In the EZFont.drawString I had to add a boundary check with an “if” statement to prevent a runtime error.

  //========================== draw each char/glyph/quad
  dim charIdx As integer
  for i As integer = 0 to sa.Ubound
    charIdx = sa(i).AscB - 32
    
    if charIdx <= glyphXOffset.Ubound then // <<<<< to prevent potential runtime error
      
      x0 = baseCharX - glyphXOffset(charIdx)
      x1 = x0 + glyphXWidth(charIdx)
      vertData.set(0, x0, y0)
      vertData.set(1, x1, y0)
      vertData.set(2, x1, y1)
      vertData.set(3, x0, y1)
      
      u0 = glyphU0Coords(charIdx)
      u1 = glyphU1Coords(charIdx)
      uvData.set(0, u0, 0.0)
      uvData.set(1, u1, 0.0)
      uvData.set(2, u1, 1.0)
      uvData.set(3, u0, 1.0)
      
      OpenGL.glDrawArrays(OpenGL.GL_QUADS, 0, 4) 'g.arrays.drawArrays(0, 3)
      
      baseCharX = baseCharX + charXAdvance(charIdx)
      
    end if 
    
  next

Will, your method of compiling true 3D scenes from voxel data is remarkable, KUDOS! Would you mind if I used some of your ideas and code in my own X3 engine (will give credit where I do so)?

For those who haven’t runned the code yet, here is a sceenshot of what the mountains looks like rendered with the EZGL framework:

Thanks for this, I’ll update my projects :slight_smile:

Yes, this is a very cool insight. BMP format contains raw pixel data perfect for passing to OpenGL! Going the other way with FromData seems to lose the alpha information though, it always comes back opaque.

Anyways I’ve been looking at the format generated by GetData and find it comes in 2 forms: 4 bytes per pixel (bpp) or 3 bpp. You get 3bpp format with masked pictures that are fully opaque and never had their Mask property touched. BMP’s 3bpp format has a fatal flaw being passed to OpenGL, pixel rows are padded out to a 4 byte boundary while OpenGL doesn’t pad.

To turn a Picture that would generate a 3bpp format into one that generates 4bpp all you have to do is access the Mask property; it’s almost a Schrodingers Cat situation. There’s some internal mask object that isn’t created unless needed and if it’s not there you get 3bpp format. But you can’t really check to know it’s state beforehand, you can only touch it to confirm it’ll be 4bpp like so…

[code]if not pic.HasAlphaChannel then //only affects masked pictures
call pic.Mask //touch the mask to ensure 4bpp
end

dim bmpMem As MemoryBlock = pic.GetData(Picture.FormatBMP)

dim pixMem As MemoryBlock = bmpMem.StringValue(54, pic.Width * pic.Height * 4)[/code]

Thanks Alwyn, I’ll add this fix but I don’t understand why it’s crashing. I mean I know drawString is lazy, it assumes the input string only contains ‘ascii’ values 32 to 126 which should work with the UTF8 literals in Xojo. I guess Str() or Format() is introducing higher code points somehow on Windows. Looking over the code there’s a lot more to do to unlazy it.

edit: looking at the screenshot I see commas are missing from the triangle count so Format must be using something other than Chr(44).

The crash occurs in EZFont.drawString at…

x0 = baseCharX - glyphXOffset(charIdx)

where charIdx = 162, and glyphXOffset.UBound = 94. This is on Windows 7 with Arial font.

Not sure if the info helps?

It helps me remember to be less assumptive :slight_smile:

charIdx 162 would come from a string where AscB(s) = 194 which is Â, or maybe it’s part of a multibyte letter. I think it’s the comma that’s messing up which is ascii 44 = &b00101100. 194 = &b11000010, that’s 44 with it’s nibbles flipped. Probably nothing, been watching lots of X-files.

This version has all the Windows fixes implemented so it should work with just Glu32.dll installed.
https://drive.google.com/file/d/0B97iUmOCTUYddWlUWVptb2w1dGs/edit?usp=sharing

Very nice!

On my Windows 7 64bit i5 4GB machine the framerate of the built application is extremely low when the sky is rendered. If I go lower and make the sky disappear, the framerate increases and I get smooth flying, although the framerate is still somewhat low.

I think what’s happening is that when you angle down and don’t see the sky there’s less terrain ‘cells’ in view to draw. In Alwyns picture above there’s 41 cells being drawn at full mesh resolution of 130000 triangles each for a total of 5.34 million triangles. If you’re facing downwards there might be only 4 cells in view and those 500000 triangles will draw much faster. Basically I think it’s the number and size/area of triangles that are the limiting speed factor. Another way to reduce triangle count is to turn on geometry mipmapping from the menu Options > Geo MipMap. Then cells farther away use lower resolution meshes and the average triangle count when looking towards the horizon is around 1.5 million. This feature isn’t finished yet though and you’ll see seams where different resolution cells meet.

Hi,

accidently found this website when I searched for Voxel Space.
I am the author of the website, which motivated this project:
http://simulationcorner.net/index.php?page=comanche
Great work. It is always nice see to inspire people.

Are you interested in the code to extract these maps from Comanche? The other graphics from the game are probably in the same format.