0

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.

lskrinjar
  • 5,483
  • 7
  • 29
  • 54

2 Answers2

1

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()

Tomcatus
  • 167
  • 9
  • I am quite new to `OpenGL` and this way seems (seemed) to me the right way. Regarding the shaders I would like to know, if I remember correctly, that the shader program has to be written in `C(C++)` or yould be written in `python`? If I understand correctly, you suggest that I predefine this values `GL_LIGHTi = 0x400i` in my `class` (constructor)? Thanks for the quick and useful answer. – lskrinjar Nov 25 '13 at 13:35
  • Shaders are written in a separate language, for OpenGL it's called GLSL. It has C-like syntax, and there are a lot of tutorials on the Internet. The can be loaded from a different text file or be hardcoded as a string in your source code - it depends on you, but the first is highly advisable ;) To the solution, I'd predefine it as `GL_LIGHTi = 0x4000 + i` as i can be larger than 9, and you can give them more suitable names, they're local for your program now. – Tomcatus Nov 25 '13 at 14:32
1

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)
datenwolf
  • 159,371
  • 13
  • 185
  • 298