Archive for wtf

Using gl_VertexID without any VBOs.

Posted in How To, Programming with tags , , , on 2013/02/03 by Adam Griffiths

Normally, gl_VertexID is the index of the currently rendered vertex element.

When you provide indices (GL_ELEMENT_ARRAY_BUFFER), gl_VertexID should match the value provided. Ie, the gl_VertexID value can repeat if you render the same element multiple times.

 

I say “should”, because this is NOT correct when you haven’t provided any VBO data.

This means, that if you are rendering using nothing but a shader and a GL_ELEMENT_ARRAY_BUFFER, the gl_VertexID will NOT match the indices you provide, and will instead be a sequence from 0 -> N.

The solution is to use a single VBO and use glDrawArrays.

 

Personally, I consider this a bug.

Advertisements

Adobe Air hanging when using SDK but not when packaged

Posted in How To with tags , , , , , on 2013/01/30 by Adam Griffiths

I just had an issue during the development of an Adobe AIR Application.
When using Flash Pro CS 6, the application hang in certain situations for 5 odd seconds.

I found a few peculiar quirks:

  • Packaged builds didn’t have the problem.
  • Moving the project to a different directory fixed the problem.
  • Clean checkouts of the source didn’t have the problem
  • Re-creating the project in Flash Pro CS 6 didn’t fix the problem.

The console was printing the following messages

Breakpoint not set; No executable code at line ###

It turns out the problem was old breakpoints that don’t exist anymore.
There’s not trivial way to remove all the breakpoints (the button was greyed out!).
The easiest way I found (on OS-X) was to do the following:

vi ~/Library/Application\ Support/Adobe/Flash\ CS6/en_US/Configuration/Debugger/AsBreakpoints.xml

Remove all the breakpoint entries in the XML.
The file should look similar to this:

<?xml version="1.0"?>
<flash_breakpoints version="1.0">
</flash_breakpoints>

This resolved the issue.

Adventures in Kivy

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

So here is a semi-live blog as I delve into Kivy.

Mission #1: Attempt to resize the default window

Ok let’s start at the start.

We first create an object that inherits from App. Done.

Ok, and the examples all return a widget from the App’s build() method. So we don’t over-ride __init__… ok… thats… unique.

Perhaps the widget is the window if it is returned from the build() method?

Widget is not the window. Widget returned from build() is added to the window. So… where is the window created?

Window docs state the window has a constructor that lets you set the window size. Ok, cool. But we don’t create the window… so.. we can’t use the constructor… sigh.

Ok, Window has a static accessor.

kivy.core.window.Window = None

No comment on what is stored here but I assume it’s the instantiated window. It doesn’t mention when it is set… handy!

Only 1 window allowed. Ok… weird. Well… let’s try that.

import kivy.core.window.Window
AttributeError: 'module' object has no attribute 'window'

Awesome…

Let’s scour the code.

Screen capture of Kivy window module

No Window.py file……… how far does this rabbit hole go.

Ok, let’s check out the __init__.py file in the window module.

class WindowBase(EventDispatcher):
 '''WindowBase is a abstract window widget, for any window implementation.

So… window base is in there. Feel free to scream now.

So we can get this by importing kivy.core.window and just leaving the class off the end.

import kivy.core.window
...
def build(self):
    print kivy.core.window.Window.size
    return None
(800, 600)

Ok sweet, thats our window.

So let’s change its size.

def build(self):
    print kivy.core.window.Window.size
    kivy.core.window.Window.size = (1024, 768)
    print kivy.core.window.Window.size
    return None
File "/Users/adamgriffiths/Workspace/VirtualEnvs/progress_quest/lib/python2.7/site-packages/kivy/core/window/__init__.py", line 243, in _set_size
 if super(WindowBase, self)._set_size(size):
 AttributeError: 'super' object has no attribute '_set_size'

FFFFFFFUUUUUUUUUUU

Ok, so after some googling we find this post about the relationship between the App and Window classes.

His solution is to pass the size as a command line parameter……….. LAME. That kinda throws the whole configuration settings thing out the window.

Looking through the Kivy code we find this block inside their base window class’ __init__ method.

if 'fullscreen' not in kwargs:
    fullscreen = Config.get('graphics', 'fullscreen')
        if fullscreen not in ('auto', 'fake'):
        fullscreen = fullscreen.lower() in ('true', '1', 'yes', 'yup')
    kwargs['fullscreen'] = fullscreen
if 'width' not in kwargs:
    kwargs['width'] = Config.getint('graphics', 'width')
if 'height' not in kwargs:
    kwargs['height'] = Config.getint('graphics', 'height')

Ok, so we can try and set it via the global config object.

So let’s add that to our App class.

def build_config(self, config):
    config.adddefaultsection('graphics')
    config.setdefault('graphics', 'width', 1024)
    config.setdefault('graphics', 'height', 768)
    config.set('graphics', 'height', 1024)
    config.set('graphics', 'width', 768)

Run the code and……

(800, 600)

……. sigh

So let’s put some debug INSIDE kivy and see what is happening. We’ll also force it to pull the ‘graphics’ setting and ignore kwargs.

if True: #'width' not in kwargs:
    kwargs['width'] = Config.getint('graphics', 'width')
print kwargs['width']
if True: #'height' not in kwargs:
    kwargs['height'] = Config.getint('graphics', 'height')
print kwargs['height']

And the output…

800
600

…. calm blue ocean…. calm blue ocean….

Ok… google…

Hmm.. ok, this post on the kivy-users forum (because documentation is for lusers) shows a similar method.

They use the Config module directly instead of the config object passed to App….. because….. they’re not the same? Well.. let’s try it anyway.

from kivy.config import Config
Config.set('graphics', 'width', 1024)
Config.set('graphics', 'height', 768)

And our output

(800, 600)

Ok, weird because the window HAS ACTUALLY CHANGED SIZE.

Whatever. We’re all living in crazy-ville atm so let’s just pretend everything is normal.

So let’s move that inside our build_config() method.

def build_config(self, config):
    Config.set('graphics', 'height', 1024)
    Config.set('graphics', 'width', 768)

And the output

[INFO ] Kivy v1.1.1
[INFO ] [Logger ] Record log in /Users/adamgriffiths/.kivy/logs/kivy_12-03-22_40.txt
[INFO ] [Factory ] 102 symbols loaded
[INFO ] [Text ] using <pygame> as text provider
[INFO ] [Loader ] using <pygame> as thread loader
[INFO ] [Window ] using <pygame> as window provider
[WARNING] [Window ] Unable to use <pygame> as windowprovider
[CRITICAL] [Window ] Unable to find any valuable Window provider at all!
Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6

(╯°□°)╯︵ ┻━┻

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.

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"

Amnesia… really

Posted in Uncategorized with tags , on 2011/05/28 by Adam Griffiths

Amnesia is a game I can’t play.

I’m not ashamed to admit that. There are a number of games I can’t play. System Shock 2, Doom 3, Blair Witch, the list goes on.

Anyway… Amnesia… I bought it because Thomas Grip is a friend of a friend of mine and I wanted to support him. But I’ve never even installed it.

I was telling a few friends about Amnesia last night. They were pretty excited by what I said.

I wake up this morning, Amnesia is in my Steam Favorites list……….. but how? It wasn’t in there before! My computer was off when I got home so I can’t have done it myself.

But there it is, between Alien Swarm and ArmA 2… seriously… wtf…

A good case for mandatory castration

Posted in Rant, Uncategorized with tags , , , on 2011/04/20 by Adam Griffiths

Murtle76 not only hates a game he didn’t bother to play, but insists that he isn’t insulting or annoying anyone…

%d bloggers like this: