ShaderProgram.set_uniform_array()   F
last analyzed

Complexity

Conditions 11

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 11
dl 0
loc 23
rs 3.4945

How to fix   Complexity   

Complexity

Complex classes like ShaderProgram.set_uniform_array() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from ed2d.opengl import gl, pgl
2
from ed2d import files
3
from ed2d import typeutils
4
from gem import vector
5
6
7
class ShaderBase(object):
8
    def create(self):
9
        self.shader = gl.glCreateShader(self.shaderType)
10
        pgl.glShaderSource(self.shader, self.shaderData)
11
        gl.glCompileShader(self.shader)
12
13
        status = pgl.glGetShaderiv(self.shader, gl.GL_COMPILE_STATUS)
14
15
        # TODO - Implement this with logging when that is finished.
16
        if not status:
17
            print(self.shaderErrorMessage)
18
            print(pgl.glGetShaderInfoLog(self.shader))
19
        else:
20
            print(self.shaderSuccessMessage)
21
22
23
class VertexShader(ShaderBase):
24
    def __init__(self, path):
25
        self.shaderData = files.read_file(path)
26
        self.shaderType = gl.GL_VERTEX_SHADER
27
        self.shaderErrorMessage = 'Vertex Shader compilation error.'
28
        self.shaderSuccessMessage = 'Vertex Shader compiled successfully.'
29
30
31
class FragmentShader(ShaderBase):
32
    def __init__(self, path):
33
        self.shaderData = files.read_file(path)
34
        self.shaderType = gl.GL_FRAGMENT_SHADER
35
        self.shaderErrorMessage = 'Fragment Shader compilation error.'
36
        self.shaderSuccessMessage = 'Fragment Shader compiled successfully.'
37
38
39
class ShaderProgram(object):
40
    def __init__(self, vertex, fragment):
41
42
        self.uniforms = []
43
        self.uniformNames = {}
44
45
        self.vertex = vertex
46
        self.fragment = fragment
47
48
        self.vertex.create()
49
        self.fragment.create()
50
51
        self.program = gl.glCreateProgram()
52
53
        gl.glAttachShader(self.program, self.vertex.shader)
54
        gl.glAttachShader(self.program, self.fragment.shader)
55
56
        gl.glLinkProgram(self.program)
57
58
        status = pgl.glGetProgramiv(self.program, gl.GL_LINK_STATUS)
59
60
        if not status:
61
            print('Linking error:')
62
            print(pgl.glGetProgramInfoLog(self.program))
63
        else:
64
            print('Program Linked successfully.')
65
66
    def use(self, using=True):
67
        if using is False:
68
            prog = 0
69
        else:
70
            prog = self.program
71
72
        gl.glUseProgram(prog)
73
74
    def get_attribute(self, name):
75
        return gl.glGetAttribLocation(self.program, name)
76
77
    def get_uniform_name(self, uniID):
78
        return self.uniformNames[uniID]
79
80
    def new_uniform(self, name):
81
        uniID = len(self.uniforms)
82
        self.uniformNames[uniID] = name
83
        self.uniforms.append(gl.glGetUniformLocation(self.program, name))
84
        return uniID
85
86
    def set_uniform_matrix(self, uniID, value, uniform=None, size=None):
87
        if not uniform:
88
            uniform = self.uniforms[uniID]
89
        if not size:
90
            size = value.size
91
92
        # use non wrapped funcion for performance reasons
93
        if size == 4:
94
            gl.glUniformMatrix4fv(uniform, 1, gl.GL_FALSE, value.c_matrix[0])
95
        elif size == 3:
96
            gl.glUniformMatrix3fv(uniform, 1, gl.GL_FALSE, value.c_matrix[0])
97
        elif size == 2:
98
            gl.glUniformMatrix2fv(uniform, 1, gl.GL_FALSE, value.c_matrix[0])
99
100
    def set_uniform_array(self, uniID, value):
101
        uniform = self.uniforms[uniID]
102
        try:
103
104
            if isinstance(value, vector.Vector):
105
                value = value.vector
106
            size = len(value)
107
            if isinstance(value[0], int):
108
                if size == 4:
109
                    gl.glUniform4i(uniform, *value)
110
                elif size == 3:
111
                    gl.glUniform3i(uniform, *value)
112
                elif size == 2:
113
                    gl.glUniform2i(uniform, *value)
114
            elif isinstance(value[0], float):
115
                if size == 4:
116
                    gl.glUniform4f(uniform, *value)
117
                elif size == 3:
118
                    gl.glUniform3f(uniform, *value)
119
                elif size == 2:
120
                    gl.glUniform2f(uniform, *value)
121
        except:
122
            raise TypeError
123
124
    def get_uniform(self, uniID):
125
126
        uniform = self.uniforms[uniID]
127
128
        return uniform
129
130
    def set_uniform(self, uniID, value):
131
132
        uniform = self.uniforms[uniID]
133
134
        # Need to imeplement the matrix uniforms after I
135
        # Implement the matrix math library
136
        if isinstance(value, int):
137
            gl.glUniform1i(uniform, value)
138
        elif isinstance(value, float):
139
            gl.glUniform1f(uniform, value)
140
        else:
141
            raise TypeError
142