Archive for the Development Category

PyGLy steps into the future

Posted in Development, PyGLy, Twisted Pair with tags , , , , , on 2012/09/21 by Adam Griffiths

I’ve been working quite heavily on PyGLy for the last few weeks and I’m incredibly pleased to announce that PyGLy is now OpenGL 3 clean!

It took more work than I hoped. Not because of PyGLy (it was already pretty good), but Pyglet’s OpenGL Core (3+) support on OS-X, is well… broken.
I had to integrate a patch written by someone else and patch out 2 of the window event handlers.
The main reason for this is that OpenGL Core on OS-X is limited to 3.2, and is Core only (no legacy compatibility).
These changes can be found in my Github repository.

Pyglet isn’t without it’s problems. It is quite heavy weight in places. There is no support for float or 1D textures.
Other problems are it’s usage of legacy calls. These are scattered throughout the code base and prevent me from using even the Label or VertexList classes.
I would LOVE to help with the development of Pyglet… but I find the code… very confusing.
It’s got a fair amount of abstraction. Tracing even a vertex buffer blows my mind.

Regardless, I hope these issues will be fixed soon.

PyGLy Progress

Posted in Development, Twisted Pair with tags , , , on 2012/07/06 by Adam Griffiths

Work on PyGLy is progressing well. The code is better designed and cleaner than I’d hoped, so I’m very pleased.

I’m wanting to keep PyGLy thin, so not much more new functionality will be added. New features will go into higher level projects that sit on top.

I tried some NumPy optimisations with BLAS and other libs, but haven’t seen much improvement. Biggest change was running Python with ‘-O’, which got me another 10 FPS.

Dev continues!

Getting Cocos 1.x / Kobold2D to work with the latest CocosBuilder

Posted in Development, How To, Programming, Rant with tags , , , , , on 2012/03/30 by Adam Griffiths

CocosBuilder is a brilliant tool that helps you rapidly develop Cocos2D applications.

But the latest versions require the Cocos 2.x branch.

Some of us are stuck with Cocos 1.x for the time being. So let’s figure out how to get things going.

Continue reading

Initial release of PyGLy

Posted in Development, Programming, Twisted Pair with tags , , , , on 2012/03/07 by Adam Griffiths

It’s a pretty big day for us, as I’m pushing my labor of love, PyGLy, to GitHub.

PyGLy is a 3D framework developed in pure python.

I’ve been dismayed at the state of game frameworks on Python.

There are a large number of quality 3D engines and frameworks out there. However, there are serious problems with the ‘engines’ out there that have Python bindings.

  • Not truly cross-platform (this is Python FFS!).
  • Not free.
  • Not maintained.
  • No documentation (the worst culprit).
  • Bindings are 2nd class citizens and you still need to code C/C++/Whatever.
  • Don’t work with latest versions of code.

Most engines have bindings created by the community. The problem is these are quickly dumped when the person moves on.

Python only 3D engines seem… well… stagnant.

  • PySoya and PySoy seem to be seething at each other but not really producing much.
  • PyGame is just SDL in disguise.
  • The rest… well they all 404 now.

For the most part, 3D game development on Python is dead.

So, behind the scenes, I’ve been writing my own 3D framework for Python, PyGLy.

“Framework” is an important word there. PyGLy does not force any one methodology on you. PyGLy simply provides functionality to wrap common functionality. Windows, Viewports, Scene Graph Nodes, Cameras. It’s up to you to put them together how you want.

Obviously some things are going to be coupled together. But for the most part, PyGLy just gets out of the way.

At the moment PyGLy is quite small, but it is in active development and already has features that may interest some.

I think the best case for it at the moment is for people wanting to rapidly prototype in 3D but not be abstracted from the rendering process. PyGLy lets you forget about the scene graph and just concentrate on rendering your objects. Rendering is performed via callbacks. You can make any OpenGL call you want in these callbacks.

PyGLy is the foundation of our Python 3D work, so expect it to be actively developed going forward.

The following are some of the things that we’re wanting to add in the future:

  • Shadowing.
  • Scene management (Octree, etc).
  • Cocos2D integration (CCLayer).
  • Separate OpenGL 3+ path.

As we’ve said before, Twisted Pair are true believers of Open Source, so you can find PyGLy on our GitHub repository under a very liberal license.

Animation support for CCTMXTiledMap

Posted in Development, Programming with tags , , , , , on 2012/03/07 by Adam Griffiths

I spent today learning Objective-C and working on a small module for one of our up and coming projects.

The outcome of this was CCAnimatedTMXTiledMap. A class that adds animation support to CCTMXTiledMap in Cocos2D-iphone / Kobold2D.

Twisted Pair are true believers in support Open Source and as such we’ve published the source code to our Github repository.

Python weak references to Methods and Functions

Posted in Development, How To, Programming with tags , , on 2012/03/01 by Adam Griffiths

The ‘weakref’ module in Python cannot store pointers to methods (there are exceptions but basically you can’t).

The following is a module I’ve written to bypass this. It is essentially code from the following sites, but improved by myself for storing them in containers like set([]).

References:
[1] [2]

Continue reading

Installing Pyglet in Mac OS X

Posted in Development, Platforms, Programming with tags , , , , , on 2012/02/21 by Adam Griffiths

Pyglet is a common requirement for many Python applications, a major one being Cocos2D.

But it doesn’t work out of the box. Running a Pyglet application will result in the following error:

OSError: dlopen(/System/Library/Frameworks/QuickTime.framework/QuickTime, 6): no suitable image found.  Did find:

/System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture

/System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture

The following are the steps to take to get Pyglet and PyObjc installed on OS-X (tested with 10.7 Lion).

Pyglet 1.1 uses the Carbon framework, but this is not compatible with 64-bit Python installs. The Pyglet 1.2 branch has been modified to use Quartz, but no releases of this branch have seen the light of day (sigh). We must instead install Pyglet from the Mercurial repository.

The Quartz bindings require the use of PyObjc but the latest versions do not work with Pip. The patches to PyObjc’s setup.py that I’ve seen on the internet do not work for me. The following is the only method I’ve had work.

Remove any existing Pyglet install

pip uninstall pyglet

Install Pyglet from the repository

pip install hg+https://pyglet.googlecode.com/hg/

Edit: The following is no longer needed

We need to install PyObjc for the new Pyglet Quartz API. But PyObjc is horribly broken and the latest version does not install with Pip or easy_install.

We must instead install an older version.

pip install pyobjc==2.2

You should now have a working Pyglet installation.

Shock goes Open Source

Posted in Development, Shock, Twisted Pair with tags , , , , , , on 2011/12/04 by Adam Griffiths

Today marks a historic day for Twisted Pair, as we release the full source code to the Shock C++ Cross-Platform library.

The project files and Socket module are currently missing.

When I get time, I’ll take a day to create the project files for MSVC, Eclipse and XCode.

Look out for PyGLy, our Python graphics library, on GitHub soon.

Pyglet mouse events and rendering

Posted in Development, How To, Programming with tags , , , , on 2011/06/28 by Adam Griffiths

The Problem

I added mouse event handlers to my Pyglet application recently. I found when I moved the mouse over the window, my rendering started to create “ghost” images.

I finally found the solution hidden in the docs.

The pyglet application event loop dispatches window events (such as for mouse and keyboard input) as they occur and dispatches the on_draw event to each window after every iteration through the loop.

So every mouse move (or any other event) triggers Pyglet to call “on_draw”.

But because I’m controlling my own render loop at 60Hz, I didn’t see a need to hook into this event. So I assume Pyglet is attempting to render the scene itself, and it’s failing miserably.

This is really bad design! What if I have lots of events that are seperate? Looks like Pyglet is going to hammer the “on_draw” event.

The Solution?

Well the basic solution is to ensure you’ve hooked into the “on_draw” event and just connect it to your render call. Don’t connect it to your game update logic or you will end up updating everything.

But…

This means your frame rate will vary depending on user input, and may even end up running balls out. Which could turn a simple game into a system hog. My basic application goes from 1% (of 2 cores on a dual core system), to 20% with the mouse moving.

It also means that you need to decouple the rendering from the system update, as each event you have scheduled will trigger an “on_draw” event. If you don’t decouple them, you will render each frame twice!

The Proper Solution?

We need to over-ride the “EventLoop.idle” method as mentioned in the docs.

The code without “on_draw” looks like this:

def idle( self ):
    """An alternate idle loop than Pyglet's default.

    By default, pyglet calls on_draw after EVERY batch of events
    which without hooking into, causes ghosting
    and if we do hook into it, it means we render after every event
    which is REALLY REALLY BAD
    http://www.pyglet.org/doc/programming_guide/the_application_event_loop.html
    """
    pyglet.clock.tick( poll = True )
    # don't call on_draw
    return pyglet.clock.get_sleep_time( sleep_idle = True )

def patch_idle_loop():
    """Replaces the default Pyglet idle look with the :py:func:`idle` function in this module.
    """
    # check that the event loop has been over-ridden
    if pyglet.app.EventLoop.idle != idle:
        # over-ride the default event loop
        pyglet.app.EventLoop.idle = idle

The “on_draw” function also calls pyglet.window.flip() for us, so now we need to do that after our rendering. So add the following (obviously you need to change the window variable depending on what you’ve called it):

# switch out the default idle function for ours
patch_idle_loop()

def render( self ):
    # do render here
    # flip the buffers
    self.window.flip()

And we’re done! No more superfluous “on_draw” events and my simple application no longer spikes the CPU usage when the mouse is moved!

Registering Event Handlers in Pyglet

Posted in Development, How To, Programming with tags , , , , , on 2011/06/25 by Adam Griffiths

The Problem and Pyglet’s own solutions

Pyglet’s documentation suggests a number of methods to receive events.

The recommended method of using @ decorators works for global methods where the event object is known. But if its for a class method or the event object is passed in later, this will not work.

The alternative is to simply over-write the existing handler with something like

window.on_resize = self.on_resize

Unfortunately most of them end up with the following error:

window.set_handler( window.on_key_release, self.on_key_release )
AttributeError: 'Win32Window' object has no attribute 'on_key_release'

This discussion on the developer list explains it. This method only works when the platform’s window class has an existing method to handle the event. And not all events are handled by default, so when you come across this, BOOM!

Even then, when it works this is also a double edged sword. The existing handlers are there for a reason! For example, if you over-write the on_resize method of Window your application will no longer draw (took me a while to figure this out).

So yes, Pyglet’s documentation is really, REALLY, asking for trouble.

The Proper Solution?

Use the “push_handlers” method.

Pyglet automatically detects a method with the event’s name and dispatches the event.
So we can just add methods to our class and we’ll automatically receive the events.

class Test:
  def attachToWindow( self, window ):
    window.push_handlers( self )

  def on_key_press( self, symbol, modifiers ):
    # method name matches the 'on_key_press' event!
    print "Keypress"

Or we can manually specify which events we care about.
If we do this, we must specify the actual function that receives the event.

class Test:
  def attachToWindow( self, window ):
    window.push_handlers( on_key_press = self.on_key_press )

  def on_key_press( self, symbol, modifiers ):
    # method name matches the 'on_key_press' event!
    print "Keypress"

Example of Minecraft style polygonisation

Posted in Development, Programming with tags , on 2011/06/17 by Adam Griffiths

Good walkthrough of rendering a voxel volume from start to finish in a Minecraft style.

It has the following problems however:

  • Single volume, no hierarchy.
  • Lack of hierarchy makes polygonisation harder, it must be done in one sweep.
  • Lack of hierarchy makes modification harder.
  • It performs 2 sweeps of the volume, one to calculate number of primitives, another to create them.
  • The C functions don’t compile in MSVC2008.

But it’s a good source of information on lighting and shader implementations.

Grouping Voxels with Hilbert Curves

Posted in Development, Programming with tags , , on 2011/06/17 by Adam Griffiths

A friend suggested quite a good idea.

Represent Voxels internally using a Hilbert Curve, the same algorithm XKCD used to display a map of IPv4.

Once you’ve got this, you can perform an RLE compression algorithm to it.

 

This paper discusses using Octrees and Hilbert curves to represent masses of voxel data.

RLE? That’s so yesterday!

Posted in Development, How To, Programming with tags , , , on 2011/06/11 by Adam Griffiths

Before writing my RLE implementation, a friend sent me a link to the blist package for Python.

I didn’t see anything amazing on the front page. Makes a 5M size list. Sure, whatever.

What the front page fails to say is that creating that 5M size blist is insanely fast. Because it doesn’t blindly allocate memory like a normal Python list would.

The “blist” list type is faster to add / remove than a Python list, and it supports copy-on-write semantics.

So I’m actually going to remove my cryptic RLE encoding and return to normal 3D array semantics using blists!

Continue reading

Creating Voxel Volumes Quicky in Python Part 2

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

So we created a volume pretty quickly Part 1, we also implemented basic RLE and Position Aware RLE (PARLE).

Read on for a few minor improvements we can make with little effort.

Continue reading

Run Length Encoding in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

The following code is my implementation of RLE in Python. I’ve included a method to modify values without having to decode the entire value.

Please note that this algorithm is inferior to the RLE with Positioning I posted about here.

Continue reading

Position Aware Run Length Encoding in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

I mentioned previously wanting to improve the RLE to include position information. I’m sure it’s already got a name, but I’m going to call it Position Aware RLE (PARLE).

Below is the code I’ve written to accomplish this. I’m sure someone can come up with a more concise way of writing it, but this is the best I can do at the moment.

Continue reading

Creating Voxel Volumes Quicky in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/09 by Adam Griffiths

Creating large chunks of memory is quite tricky in Python because of a number of overheads. I’ve been attempting this myself and have found a fast method to do this which combines a few handy optimisations we would need later on for a Voxel Engine anyway.

Please be aware that the code evolves along the way, so don’t blindly copy and paste the first examples =).

Also, the WordPress theme is cutting of some text. If you copy and paste it, it is still there.

This post is continued in Position Aware RLE, RLE and Part 2.

Continue reading

First Milestone

Posted in Development with tags , , on 2011/03/07 by Adam Griffiths

Over the last week I’ve written and re-written my Python framework about 6 times. Yesterday and today I re-wrote the core messaging framework again and I’ve just gotten to what I would consider the first milestone! Very exciting.

Developing cross-platform C++ projects that don’t require the heap

Posted in Development with tags , , on 2011/02/16 by Adam Griffiths

Cross-platform abstraction is generally done with inheritance. I’ve developed a cleaner method that ditches inheritance but may turn some “purists” off.

Continue reading

Rules for properly structuring and developing a C++ project

Posted in Development with tags , , on 2011/02/16 by Adam Griffiths

There are many different methods programmers have picked up for laying out a C++ project or library.

After a number of years of implementing, interacting and improving C++ projects, I’ve found the following to be the best structure to use.

These design rules and patterns are designed to increase consistency, readability, modularity and reduce programmer error.

Tribute to the refinement of my coding style and practices goes to a number of people I’ve worked with (read: leached their brains), including but not limited to David Hogan, Jeremy Kincaid, et al.

Last updated 2011/02/16

Continue reading

%d bloggers like this: