Gaming with Xojo, seeking advice

Forgot a declare was in there. I think it’s just the Lib name that doesn’t work on windows, maybe it should be “OpenGL.dll”, or simply “OpenGL”.

The gluLookAt call applies the transform to position a camera in space looking at a specified point, but that transform could also be generated using the built-in OpenGL methods.

And gluLookAt is only needed for perspective, it’s a design flaw it’s being used when in canvas mode where OpenGL.gluOrtho2D applies the transform. You can comment out the lookAt line and canvas mode should still work.

[quote=34950:@Nona Suomy] // Draw the shark
g.texture.bindto(1)
g.draw2DRect(me.Width/2, me.Height/2, sharkleft.width, sharkleft.height)
The seabed sprites got drawn correctly and shows up, but I can’t seem to get the shark to show up.[/quote]
draw2DRect doesn’t apply texture coordinates and so it ends up using the last texture coordinate (which is probably a transparent pixel) for all 4 vertices of the rect. Instead use drawRect2DTex which is the same thing but with those texture coordinates.

Window3 is only Canvas and Window3GL only OpenGL. Maybe you commented out Paint in one but were running the other?

Ah, got it working… thanks Stuart.

Simply had to download and install glut32.dll, and then changed the code from

Soft Declare sub gluLookAt lib "OpenGL.framework" (eyeX as Double, eyeY as Double, eyeZ as Double, centerX as Double, centerY as Double, centerZ as Double, upX as Double, upY as Double, upZ as Double)

to

[code]
#if TargetWin32
Soft Declare sub gluLookAt lib “Glu32” (eyeX as Double, eyeY as Double, eyeZ as Double, centerX as Double, centerY as Double, centerZ as Double, upX as Double, upY as Double, upZ as Double)
#endif

#if TargetMacOS
Soft Declare sub gluLookAt lib “OpenGL.framework” (eyeX as Double, eyeY as Double, eyeZ as Double, centerX as Double, centerY as Double, centerZ as Double, upX as Double, upY as Double, upZ as Double)
#endif[/code]

Hope you don’t mind, but I’ve posted an updated version of your project that runs on Windows here.

On Windows 7 X64, the sprites on the Canvas flickers so much, it is completely unusable. With the OpenGL version I also get a smooth experience locked at 60fps, without a single flicker.

Same here on Windows 8-64, framerate 63-65 fps.

Well, I moved my game over to OpenGL - thanks to stuart s’s “ezgl”. I am having problems with adding rotated missiles and haven’t figured out how to replace the new rotated sprite with the old one efficiently. You can see the issue if you continually fire the missiles by bashing the same key over and over. Other than that, the animations are much, much better.

I think the inefficiency in my logic is that I created two pixmaps (one for normal, another for mask). I then rotate both, draw them both to two pictures (p, pmask) and merged them with p.applymask(pmask). Once that is done, I do:

g.texture.storeimagealpha(ridx, p, p.mask)
g.texture.bindto(ridx)
g.draw2drecttex(missile(n).x + xoffset, missile(n).y, 62, 62)

ridx is the index of the missile sprite in the ezgl sprites “bank”. The bottleneck seems to happen at two places. It happens when I do draw the pixmapshapes back to p and p.mask. The other bottleneck seems to happen when I replace the old sprite in the bank with the newly rotated one:

g.texture.storeimagealpha(ridx, mpic, mpic.mask)

It’s Friday night, my mind is out there in third base somewhere. I’m sure there is a much more efficient way to rotate sprites using pixmapshape, convert it back to picture and then replace the index picture with the rotated picture. Isn’t there a rotation method in OpenGL to bypass all this mess?

It looks good. You should throw it on the App Store and sell it for .99 and you will sell many!!

LOL, I have a long way to go before I can even consider making it available for a price. This is very much a learning project for me and it’s been a blast.

On a separate note, I did resolve the bottlenecks I mentioned earlier using:

g.texture.bindto(ridx)
g.pushmatrix
g.xform.translate(missile(n).x + xoffset, missile(n).y, 0)
g.xform.rotateZ(angle * 360 / 6.28318)
g.draw2drecttex(-31, -31, 62, 62)
g.popmatrix

The only problem now is that my missiles continually spin around… :wink:

Great little gem you have created, Stuart.

I think I am done testing non-OpenGL vs. OpenGL. Hands down, OpenGL is the way to go. Here is the latest test. Change to the “Under the Sea” scene. I’ve loaded the game field with over 200 fishes, all swimming at random speeds (1 to 3). I tested this on regular Canvas and the game crawled. As you can see, OpenGL handles the animations/number of sprites without even breaking a sweat.

Nona I can’t download the app from the link. Is it just me?

Weird, I have no problem downloading it. You can download it manually:

http://koualo.com/beta/typecon1gl.zip

Thank you to everyone who offered suggestions and gave advice. A special thanks goes to stuart s - for his work on ezgl. His ezgl framework made creating 2D games really easy, and I have not even explored half of what it can do. I’m still looking forward to Alwyns upcoming tutorial. I have also tested my app on my 27inch Thunderbolt display with my MacBook Pro and even at full screen, the app (the “Under the Sea” scene) ran absolutely fine, even with all those sprites running around. The other scenes were not optimized, so it slows down in parts where I did not pay much attention to. In either case, running fullscreen on my thunderbolt display without stuart’s ezgl was not even an option as the performance was totally unacceptable.

This has been a great learning experience/opportunity and I just want to extend my great appreciation to everyone in this thread. This concludes my test.

No problem. Feel free to modify/repurpose/refactor/repost. I found a newer version of the framework and hope to post it in a few days.

To eliminate flicker Windows needs some changes I didn’t code for. From memory: set Canvas.DoubleBuffer True, Canvas.EraseBackground False, and everywhere invalidate is called pass False as the EraseBackground parameter.

This did the trick to remove the flicker, thanks Stuart.

Very impressive how you illustrated how to get speed gains with OpenGL. Will definitely be useing some of your ideas in my graphics programming.

Stuart, I read your response to my private message but I’ll answer here in case others are interested. While initially testing ezgl, I was using pixmapshapes to rotate my missiles, but as noted, the calculations/updating the texture bank was extemely expensive and slowed the game to a crawl. I then saw that you were translating and rotating your sprites in your example using methods available in OpenGL, so I adapted my missiles to using those. It worked great and the missiles rotates and flies without any performance hits.

As for my question about replacing existing textures in texture bank, I found that replacing an existing texture with a new/different texture is also very inefficient an can slow down the game if done in a tight loop. I wanted to know because I did not want to pre-generate and preload all the bombs/bubbles with the different letters. I was thinking that I can just generate the bombs with the correct letter and replace the “template” bank index with that generated texture. In the end, and I have not posted the latest version of my game, I ended up just pre-generating (making a copy of the texture, adding letter and letter mask to the texture) all of the letters, numbers and punctuations and loaded them to the texture bank before the game starts. This solved the performance issue for the other parts of the game, but it felt “dirty” to me since I now have about 60 or so pre-generated textures in the texture bank instead of having just a few of the templates for the bombs/bubbles. But I don’t see any other way to do this without having a performance hit.

Finally, before you finish updating the next ezgl, consider adding a property/method to keep track of the textures by name. Right now, to keep my sanity in check, I have a “pair” property that stores the actual name of the texture and its index in the texture bank:

      g.texture.storeimagealpha(count, p, p.mask)
      currentsprites.append(pname:count)

This way, I can get access to the texture’s bank index by calling its actual name for binding purposes (instead of wondering what index goes with what sprite). Other than those two minor irritations, ezgl is aboslutely a joy to work with. If texture management is added, I think ezgl will be a very nice addition to Xojo for OpenGL development (not just gaming).

Thank you for putting this together.

Here’s an update of the game prototype. I’ve added a few more sprites in to make the explosions appear more realistic and “cooler.” I also fixed the bomb drop lags/bottleneck issue so now you can play it in full screen mode. I still need to fix the starting laser firing and ending positions, but that’s not a big concern atm. I also need to incorporate Stuart’s new missile trajectory calculations to the “Under the Sea” scene so the laser beams don’t curve.

Overall, OpenGL is not bad. It’s just sprites management that is a pain the arse… :wink:

If someone with a windows machine wants to test and have glu32.dll installed, please let me know if my OpenGL implementation also works under windows. I don’t have access to a Windows machine at the moment. :frowning:

EDIT: NVM, windows version does not work. Just a blank surface.

I’m far from knowing proper texture management but for a single scene I’d pre-load all necessary textures if possible. So like when the rolling hills scene starts load all of the possible textures needed. When the scene changes is when to swap textures, that doesn’t feel dirty to me but loading all textures for all scenes would.

If the problem is the time to load a scene takes too long thats storeImage(). 99% of it’s time is taken in scanning the Picture to a MemoryBlock and Alwyn has posted optimized code for doing that.

The fastest way I think is to pre-generate all MemoryBlock data and load it from a file on app start (or maybe string constants could work). So you start off with formatted data for all hundreds of textures but only pass in the 60 or so a scene requires. A time vs memory tradeoff.

I don’t really understand the use of a name. I always use references or possibly an index to track things, names are only for the user. So I’m not picturing how this would work exactly. I think a dictionary.

[code]//loading
textureNameMap = new Dictionary

g.texture.storeimagealpha(count, p, p.mask)
textureNameMap.Value(pname) = count

//binding
g.texture.bindTo(textureNameMap.Value(pname))[/code]
This works if you always load the entire set of textures with an empty (new) dictionary. If you’re swapping only some you’ll also need to check and remove old names with the same texture bank index.

Here’s an updated version of ezgl. Some methods moved or have name changes, like g.draw2DRectTex() is now g.draw.rectSolidTex(). glSurfacePlainCanvas is a no frills version of glSurface with canvas style projection as default. storeImage isn’t optimized and glBlend needs refactoring but I don’t know when I’ll get to it.

An issue I noticed is that colors are more saturated in OpenGL. Not sure why this happens, is it some color profile in the picture, an OpenGL blending mode or switch.

Left is Canvas, right is OpenGL via ezgl.

Stuart, thanks for the update. I will get to testing it out this afternoon when all of my normal work is done. The reason for the “names” of the sprites is because the sprites are automatically pre-generated and added to the texture bank. I have no idea which index belongs to which sprite as they might not be in the same order depending on the scene. This is why I was asking that you include something like a dictionary that contains the bank id and the name of the texture so the bank id can be retrieved using its name. Ideally, this would be added as a parameter to “storeimage/storeimagealpha” like:

g.texture.storeimagealpha(bankidx, texturename, texture, texturemask)

And then you would have a method like:

g.texture.bindto(getbankindex("targetUppercaseL"))

This is what I have been doing, but since you are the guru behind ezgl, I thought I’d ask you to add this feature in to make it easier to manage auto-generated sprites. A small and simply game like my prototype does not have any issues with texture load time, and managing sprites is not really an issue. But if I were to make a more complicated game, sprites management will sure be necessary.

I am also following Alwyn’s post about speed improvements very closely. Are you going to incorporate his findings into ezgl, or should I implement that myself in your new version of ezgl? As for the colors, I too noticed the saturation. But for this particular game, I happen to like the saturation. :wink: