ElementManager.create_element()   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 6
dl 0
loc 27
rs 7.5384
c 1
b 0
f 1
1
from ed2d.scenegraph import SceneGraph
2
from ed2d.mesh import Mesh
3
from ed2d import view
4
from ed2d import files
5
from ed2d import shaders
6
from gem import matrix
7
from ed2d.texture import Texture
8
from ed2d.events import Events
9
from ed2d.opengl import pgl, gl
10
11
class ElementManager(object):
12
    def __init__(self):
13
        self.scenegraph = SceneGraph()
14
15
        self.elementData = {}
16
        self.width = 800.0
17
        self.height = 600.0
18
        Events.add_listener(self.size_listener)
19
20
        self.init_gl()
21
22
    def init_gl(self):
23
24
        self.vao = pgl.glGenVertexArrays(1)
25
        gl.glBindVertexArray(self.vao)
26
27
        vsPath = files.resolve_path('data', 'shaders', 'main.vs')
28
        fsPath = files.resolve_path('data', 'shaders', 'main.fs')
29
30
        vertex = shaders.VertexShader(vsPath)
31
        fragment = shaders.FragmentShader(fsPath)
32
        self.program = shaders.ShaderProgram(vertex, fragment)
33
34
35
        # A view instance will be used to sync all of the orthographic
36
        # projections in the various shaders the ui uses.
37
38
        # Technically we could use a view instance from the game instead
39
        # of creating a new one, but that makes things a bit more
40
        # complex to setup...
41
42
        self.view = view.View()
43
        self.ortho = matrix.orthographic(0.0, self.width, self.height, 0.0, -1.0, 1.0)
44
        self.view.new_projection('ortho', self.ortho)
45
        self.view.register_shader('ortho', self.program)
46
47
    def size_listener(self, event, data):
48
        if event == 'window_resized':
49
            print ('SIZE RECIEVED')
50
            winID, x, y = data
51
            self.width = x
52
            self.height = y
53
            self.ortho = matrix.orthographic(0.0, self.width, self.height, 0.0, -1.0, 1.0)
54
            self.view.set_projection('ortho', self.ortho)
55
56
    def create_element(self, elmProp):
57
58
        imgMesh = Mesh()
59
        imgMesh.fromData(data=[[0.0, 1.0], [1.0, 1.0], [0.0, 0.0], [1.0, 0.0]])
60
61
        for key, value in elmProp.items():
62
            if key == 'pos':
63
                x, y = value
64
                imgMesh.translate(x,y)
65
            elif key == 'scale':
66
                imgMesh.scale(value)
67
            elif key == 'rotation':
68
                # TODO - not yet implemented in mesh
69
                # imgMesh.rotate(*value)
70
                pass
71
            elif key == 'texture':
72
                imgMesh.addTexture(value)
73
74
        imgMesh.addProgram(self.program)
75
76
        eid = self.scenegraph.establish(imgMesh)
77
78
        self.elementData[eid] = {}
79
        self.elementData[eid]['prop'] = elmProp
80
        self.elementData[eid]['mesh'] = imgMesh
81
82
        return eid
83
84
    def update_element(self, eid, elmProp):
85
        imgMesh = self.elementData[eid]['mesh']
86
87
        for key, value in elmProp.items():
88
            self.elementData[eid]['prop'][key] = value
89
            if key == 'texture':
90
                imgMesh.addTexture(elmProp['texture'])
91
92
    def check_element(self, elmProp):
93
        '''Check if an object is already managed by the '''
94
        for eid, info in self.elementData.items():
95
            if info['prop'] is elmProp:
96
                return eid
97
98
    def render(self):
99
        self.program.use()
100
        gl.glBindVertexArray(self.vao)
101
        self.scenegraph.render()
102
        gl.glBindVertexArray(0)
103
104
_eleman = None
105
106
class Tex2D(object):
107
    def __init__(self, eid, elmProp):
108
        self.eid = eid
109
        self.elmProp = elmProp
110
111
    def update_scale(self, scale):
112
        elmProp = {'scale': scale}
113
114
        _eleman.update_element(elmProp)
115
116
    # TODO - This also should support relative positioning to the previous.
117
    def update_position(self, x, y):
118
        elmProp = {'pos': (x, y)}
119
120
        _eleman.update_element(elmProp)
121
122
    def update_texture(self, texture):
123
        elmProp = {'texture': texture}
124
125
        _eleman.update_element(elmProp)
126
127
    def update_rotation(self, rotation):
128
        elmProp = {'rotation': rotation}
129
130
        _eleman.update_element(elmProp)
131
132
def init_menusystem():
133
    global _eleman
134
    _eleman = ElementManager()
135
136
# These functions are wrapper function to help simplify the usage of
137
# ElementManager, which is basically going to be used like a singleton.
138
def insert_image(imgPath, x, y, scale=1, rotation=(0, 0, 0)):
139
140
    gl.glBindVertexArray(_eleman.vao)
141
    texture = Texture(imgPath, _eleman.program)
142
    elmProp = {
143
        'texture': texture,
144
        'pos': (x, y),
145
        'scale': scale,
146
        'rotation': rotation,
147
    }
148
    eid = _eleman.create_element(elmProp)
149
    gl.glBindVertexArray(0)
150
    return Tex2D(eid, elmProp)
151
152
def insert_text(text, font, x, y, scale=1, rotation=(0, 0, 0)):
153
    elmProp = {
154
        'font': font,
155
        'text': text,
156
        'pos': (x, y),
157
        'scale': scale,
158
        'rotation': rotation,
159
    }
160
    eid = _eleman.create_element(elmProp)
161
162
def render():
163
    _eleman.render()
164