Question

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.

Was it helpful?

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)

OTHER TIPS

First of all, why not use shaders here, but the fixed pipeline? It's a deprected way of lighting your stage, unless you're targeting a very old OpenGL version. This question is just of curiosity ;) it doesn't solve the real problem.

For me it looks like glEnable() accepts string but from defines and it seems, they don't look like "GL_LIGHT0", but rather

#define GL_LIGHT0                         0x4000
#define GL_LIGHT1                         0x4001
#define GL_LIGHT2                         0x4002
#define GL_LIGHT3                         0x4003
#define GL_LIGHT4                         0x4004
#define GL_LIGHT5                         0x4005
#define GL_LIGHT6                         0x4006
#define GL_LIGHT7                         0x4007

as it can be found in the gl.h header. Try giving a suitable id for your lights and then passing that to glEnable()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top