Search code examples
pythonopenglpyopengl

create opengl lights with class constructor


I am currently working on lighting in OpenGL (in python) and I have an idea and with that idea a problem and a question.

As I am reading the documentation here. I got an idea if I can write a class (constructor) to create lights as objects that will have all the input parameters (properties) set to default (defined by me) but I could overwrite them if defined when creating new light object. The Light class should look like this:

from OpenGL import *
from OpenGL.GL import *
from OpenGL.GLU import *
from itertools import count

class Light(object):
    '''
    classdocs
    '''
    _i = count()

    def __init__(self, light_position):
        '''
        Constructor
        '''
        self.i = self._i.next()
        self.light_position = light_position
        glEnable(GL_LIGHTi)
        glLightfv(GL_LIGHTi, GL_POSITION, self.light_position)

The problem is the following: If this can be done (this way) I have a problem with how to make the correct form of the expression GL_LIGHTi in the documentation here it is said in Notes:

It is always the case that

GL_LIGHTi = GL_LIGHT0+i

so is there a way to write this correctly in (python) class or is this a bad idea (is it possible)? What type of input does glEnable() accepts as I know that it works with glEnable(GL_LIGHT0) but does not accept glEnable(str(GL_LIGHT)+str(i)) if i=0.

As I see it the code would be little shorter if compared that you maybe have create/define 8 lights and all its parameters.


Solution

  • OpenGL is a state machine. Setting the state in the constructor makes no sense, because the next time you're initializing a light it will be overridden by the constructor. Also you don't get an infinite number of lights in (fixed function) OpenGL.

    You want something like this:

    class Light:
        ...
        setup(self, i):
            glEnable(GL_LIGHT0 + i)
            glLightfv(GL_LIGHT0 + 1, GL_POSITION, self.light_position)
            ....
    

    And in the drawing function something like

    glEnable(GL_LIGHTING)
    for i,l in enumerate(lights):
        l.setup(i)