Blog

Python: Creating a Class with Dynamic Set of Members

When defining a class in C++, the only way to vary set of it's members is to use conditional compilation:

class CMyAwesomeObject {
#ifdef __OPENGL
    void bind(void) const {
        // ...
    }
#endif
   // ...

}; // an annoying semicolon

But Python is a dynamic language, and we can modify classes on-the-fly, e. g. add new methods:

class A:
  pass

A.mymethod = lambda self: self.something
A.mymethod.__name__ = "mymethod" # otherwise `print A.mymethod`
                                 # would output smth like
                                 # `<unbound method A.<lambda>>`

But there is also a way to control class members being defined right in the definition of a class.

For example, you do positively can write something like this:

class myAwesomeObject:
  if locale == "en-GB":
    def getColour(self):
      return self.RGB
  else:
    def getColor(self):
      return self.RGB
Add a comment

Read more: Python: Creating a Class with Dynamic Set of Members

How Primitive WebGL Is?

I was much disappointed when I started to learn WebGL and here I will tell why.

WebGL Public Wiki page about differences between WebGL and OpenGL tells us that the differences are:

  • problems with non-power of two texture support
  • behavior of vertex attribute 0
  • no double-precision floating point support
  • no 3D texture support
  • textureLod functions are only available at vertex shaders
  • precision qualifiers behavior.

Doesn't sound much catastrophic, I thought. But now I can expand this list... a little.

  • say goodbye to glBegin/glEnd. All data should now be handled only via array buffers (glCreateBuffer). And there is also no default shader program now (glUseProgram(0) in OpenGL), you have to write your own shaders anyway.
  • no floating point support AT ALL! To create a texture from a floating point data you'll have to enable OES_texture_float or OES_texture_half_float extension. But that won't help you if you wish for a floating point internal format in your textures (in a framebuffer attachment, for example). Add one more extension (WEBGL_color_buffer_float or EXT_color_buffer_half_float) to achieve that. By the way, two last ones are not currently supported by Chrome.
  • no support for attaching whole cube maps to framebuffers (only faces). aaaand also
  • NO GEOMETRY SHADERS, HELL YEAH. (And of course no tesselation shaders.)

I'm done with it.

Add a comment

OpenGL: One-pass rendering to a cube map

Rendering to a texture is a common trick one should be able to do in OpenGL in order to implement many magnificent effects like shadows or refracting surfaces. At this point cube maps supported by OpenGL are a way to enhance those effects. For example, omnidirectional shadows become possible.

How to implement it?

There are two basic approaches. The first approach is just to render the whole scene six times for each face of the cube map. OpenGL allows binding particular face of a cube map as a framebuffer's depth/color attachment. That is a simple trick, and there are lots of articles about it over the Internet.

The second approach is one-pass rendering. It uses geometry shaders to render each triangle six times for each face, so GPU is forced to do all the work. I think this way is preferable and I'm going to show how it can be accomplished.

Add a comment

Read more: OpenGL: One-pass rendering to a cube map

Python Caching decorator

Assume your object has a method that calculates a value that doesn't change in the object's lifetime. For example, you have a tree of objects and a characteristic of a node that is calculated recursively (e. g., depth of a subtree), and you are not going to change the whole tree after it is created. In this case a reasonable solution to improve performance is to calculate the value once on the first call and then cache it in a way. Here is a useful Python decorator for this:

def caching(fn):
  name = fn.__name__
  print name
  cache_name = "_cache_" + name
  def newmethod(self, *args, **kwargs):
    if hasattr(self, cache_name):
      return getattr(self, cache_name)
    else:
      value = fn(self, *args, **kwargs)
      setattr(self, cache_name, value)
      return value
  newmethod.__name__ = name
  return newmethod

And here is an example of usage:

class A(object):
  @caching
  def myattr(self):
    print "Calculating it now..."
    return 42

a = A()
print a.myattr() # outputs "Calculating it now...\n42"
print a.myattr() # outputs "42"

Enjoy using it!

Add a comment