Statistics
| Revision:

root / PyOpenGL-Demo / proesch / shaderProg / shaderProg.py @ 1

History | View | Annotate | Download (4.9 kB)

1
# 
2
# Class to simplify the incorporation of GLSL programs.
3
# 
4
# Copyright (C) 2007  "Peter Roesch" <Peter.Roesch@fh-augsburg.de>
5
#
6
# This code is licensed under the PyOpenGL License.
7
# Details are given in the file license.txt included in this distribution.
8

    
9

    
10
import sys
11
try:
12
        from OpenGL.GLUT import *
13
        from OpenGL.GL import *
14
        from OpenGL.GLU import *
15
        from OpenGL.GL.ARB.shader_objects import *
16
        from OpenGL.GL.ARB.fragment_shader import *
17
        from OpenGL.GL.ARB.vertex_shader import *
18
except:
19
        print 'Error importing GL / shaders'
20
        sys.exit()
21

    
22
class ShaderProgram ( object ):
23
        """Manage GLSL programs."""
24
        def __init__( self ):
25
                self.__requiredExtensions = ["GL_ARB_fragment_shader",
26
                 "GL_ARB_vertex_shader",
27
                 "GL_ARB_shader_objects",
28
                 "GL_ARB_shading_language_100",
29
                                                                 "GL_ARB_vertex_shader",
30
                                                                 "GL_ARB_fragment_shader"]
31
                self.checkExtensions( self.__requiredExtensions )
32
                self.__shaderProgramID = glCreateProgramObjectARB()
33
                self.__checkOpenGLError()
34
                self.__programReady = False
35
                self.__isEnabled = False
36
                self.__shaderObjectList = []
37

    
38
        def checkExtensions( self, extensions ):
39
                """Check if all extensions in a list are present."""
40
                for ext in extensions:
41
                        if ( not ext ):
42
                                print "Driver does not support ", ext
43
                                sys.exit()
44

    
45
        def __checkOpenGLError( self ):
46
                """Print OpenGL error message."""
47
                err = glGetError()
48
                if ( err != GL_NO_ERROR ):
49
                        print 'GLERROR: ', gluErrorString( err )
50
                        sys.exit()
51

    
52
        def reset( self ):
53
                """Disable and remove all shader programs"""
54
                for shaderID in self.__shaderObjectList:
55
                        glDetachObjectARB( self.__shaderProgramID, shaderID )
56
                        glDeleteObjectARB( shaderID )
57
                        self.__shaderObjectList.remove( shaderID )
58
                        self.__checkOpenGLError( )
59
                glDeleteObjectARB( self.__shaderProgramID )
60
                self.__checkOpenGLError( )
61
                self.__shaderProgramID = glCreateProgramObjectARB()
62
                self.__checkOpenGLError( )
63
                self.__programReady = False
64

    
65
        def addShader( self, shaderType, fileName ):
66
                """Read a shader program from a file.
67

68
                The program is load and compiled"""
69
                shaderHandle = glCreateShaderObjectARB( shaderType )
70
                self.__checkOpenGLError( )
71
                sourceString = open(fileName, 'r').read()
72
                glShaderSourceARB(shaderHandle, [sourceString] )
73
                self.__checkOpenGLError( )
74
                glCompileShaderARB( shaderHandle )
75
                success = glGetObjectParameterivARB( shaderHandle, 
76
                        GL_OBJECT_COMPILE_STATUS_ARB)
77
                if (not success):
78
                        print glGetInfoLogARB( shaderHandle )
79
                        sys.exit( )
80
                glAttachObjectARB( self.__shaderProgramID, shaderHandle )
81
                self.__checkOpenGLError( )
82
                self.__shaderObjectList.append( shaderHandle )
83

    
84
        def linkShaders( self ):
85
                """Link compiled shader programs."""
86
                glLinkProgramARB( self.__shaderProgramID )
87
                self.__checkOpenGLError( )
88
                success = glGetObjectParameterivARB( self.__shaderProgramID, 
89
                        GL_OBJECT_LINK_STATUS_ARB )
90
                if (not success):
91
                        print glGetInfoLogARB(self.__shaderProgramID)
92
                        sys.exit()
93
                else:
94
                        self.__programReady = True
95
        
96
        def enable( self ):
97
                """Activate shader programs."""
98
                if self.__programReady:
99
                        glUseProgramObjectARB( self.__shaderProgramID )
100
                        self.__isEnabled=True
101
                        self.__checkOpenGLError( )
102
                else:
103
                        print "Shaders not compiled/linked properly, enable() failed"
104

    
105
        def disable( self ):
106
                """De-activate shader programs."""
107
                glUseProgramObjectARB( 0 )
108
                self.__isEnabled=False
109
                self.__checkOpenGLError( )
110

    
111
        def indexOfUniformVariable( self, variableName ):
112
                """Find the index of a uniform variable."""
113
                if not self.__programReady:
114
                        print "\nShaders not compiled/linked properly"
115
                        result = -1
116
                else:
117
                        result = glGetUniformLocationARB( self.__shaderProgramID, variableName)
118
                        self.__checkOpenGLError( )
119
                if result < 0:
120
                        print 'Variable "%s" not known to the shader' % ( variableName )
121
                        sys.exit( )
122
                else:
123
                        return result
124

    
125
        def indexOfVertexAttribute( self, attributeName ):
126
                """Find the index of an attribute variable."""
127
                if not self.__programReady:
128
                        print "\nShaders not compiled/linked properly"
129
                        result = -1
130
                else:
131
                        result = glGetAttribLocationARB( self.__shaderProgramID, attributeName )
132
                        self.__checkOpenGLError( )
133
                if result < 0:
134
                        print 'Attribute "%s" not known to the shader' % ( attributeName )
135
                        sys.exit( )
136
                else:
137
                        return result
138
        
139
        def isEnabled( self ):
140
                return self.__isEnabled
141

    
142
# test routine
143
if __name__ == '__main__':
144
        glutInit(sys.argv)
145
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA)
146
        glutInitWindowSize( 100,100 )
147
        glutCreateWindow("shaderProg Test")
148
        # Note: this will fail on many platforms where you must call
149
        # *after* you get an initialized glut context...
150
        Sp = ShaderProgram()
151
        Sp.addShader( GL_VERTEX_SHADER_ARB, "temperature.vert" )
152
        Sp.addShader( GL_FRAGMENT_SHADER_ARB, "temperature.frag" )
153
        Sp.linkShaders( )
154
        print "Index of variable CoolestTemp: ", \
155
                Sp.indexOfUniformVariable( "CoolestTemp" )
156
        Sp.enable( )
157
        print "Index of attribute VertexTemp: ", \
158
                Sp.indexOfVertexAttribute( "VertexTemp" )
159
        glVertexAttrib1fNV(Sp.indexOfVertexAttribute( "VertexTemp" ), 12.3)
160
        Sp.disable( )
161
        Sp.reset( )
162
        print 'OK'