Completed
Push — master ( ab9984...af827b )
by Matthew
01:19
created

framework.game.Viewport.set_rect()   A

Complexity

Conditions 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 5
rs 9.4285
1
import math
2
3
from ed2d import window
4
from ed2d import sysevents
5
from ed2d.events import Events
6
from ed2d import context
7
from ed2d import timing
8
from ed2d import files
9
from ed2d import shaders
10
from ed2d.opengl import gl
11
from ed2d.opengl import pgl
12
from gem import vector
13
from gem import matrix
14
from ed2d import mesh
15
from ed2d import text
16
from ed2d import camera
17
from ed2d.scenegraph import SceneGraph
18
from ed2d.assets import objloader
19
from ed2d import cursor
20
from ed2d import view
21
22
class Viewport(object):
23
    '''Basic data container to allow changing the viewport to simpler.'''
24
    def __init__(self, name, camera):
25
        self.name = name
26
        self.camera = camera
27
        self.width = 0
28
        self.height = 0
29
        self.x = 0
30
        self.y = 0
31
    
32
    def set_rect(self, x, y, width, height):
33
        self.width = width
34
        self.height = height
35
        self.x = x
36
        self.y = y
37
38
class ViewportManager(object):
39
    def __init__(self):
40
        self.view = view.View()
41
    
42
    def create_viewport(self, name, camera):
43
        if camera is not None:
44
            camera.set_view(self.view)
45
        return Viewport(name, camera)
46
    
47
    def make_current(self, vp):
48
        if vp.camera is not None:
49
            vp.camera.make_current()
50
            vp.camera.set_projection(75.0, float(vp.width) / float(vp.height), 1.0, 1000.0)
51
        
52
        gl.glViewport(vp.x, vp.y, vp.width, vp.height)
53
    
54
class GameManager(object):
55
    ''' Entry point into the game, and manages the game in general '''
56
    def __init__(self):
57
58
        self.width = 1920
59
        self.height = 1080
60
        self.title = "ed2d"
61
        self.running = False
62
63
        self.fpsTimer = timing.FpsCounter()
64
        self.fpsEstimate = 0
65
66
        self.sysEvents = sysevents.SystemEvents()
67
        self.window = window.Window(self.title, self.width, self.height, window.WindowedMode)
68
        self.context = context.Context(3, 3, 2)
69
        self.context.window = self.window
70
71
        Events.add_listener(self.process_event)
72
73
        self.keys = []
74
75
        # Mouse Information
76
        self.mousePos = [0.0, 0.0]
77
        self.mouseButtons = []
78
        self.mouseRelX = 0
79
        self.mouseRelY = 0
80
        self.mousePosX = 0
81
        self.mousePosY = 0
82
        cursor.set_relative_mode(False)
83
        cursor.show_cursor()
84
85
        gl.init()
86
        major = pgl.glGetInteger(gl.GL_MAJOR_VERSION)
87
        minor = pgl.glGetInteger(gl.GL_MINOR_VERSION)
88
        print('OpenGL Version: {}.{}'.format(major, minor))
89
90
        gl.glViewport(0, 0, self.width, self.height)
91
92
        # For CSG to work properly
93
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
94
        gl.glEnable(gl.GL_DEPTH_TEST)
95
        gl.glEnable(gl.GL_CULL_FACE)
96
        gl.glEnable(gl.GL_MULTISAMPLE)
97
98
        gl.glClearColor(0.0, 0.0, 0.4, 0.0)
99
100
        vsPath = files.resolve_path('data', 'shaders', 'main2.vs')
101
        fsPath = files.resolve_path('data', 'shaders', 'main2.fs')
102
103
        vertex = shaders.VertexShader(vsPath)
104
        fragment = shaders.FragmentShader(fsPath)
105
        self.program = shaders.ShaderProgram(vertex, fragment)
106
        self.program.use()
107
108
        #self.testID1 = self.program.new_uniform(b'perp')
109
        self.testID2 = self.program.new_uniform(b'view')
110
111
        self.vao = pgl.glGenVertexArrays(1)
112
113
        self.scenegraph = SceneGraph()
114
115
        # Creating a object steps:
116
        # Create a mesh object to render
117
        objFL = objloader.OBJ('buildings')
118
        self.meshTest = mesh.Mesh()
119
        self.meshTest.fromData(objFL)
120
        self.meshTest.addProgram(self.program)
121
        self.meshTestID = self.scenegraph.establish(self.meshTest)
122
        self.meshTest.translate(0.0, 0.0, 0.0)
123
124
125
        objBox = objloader.OBJ('box')
126
        self.boxMesh = mesh.Mesh()
127
        self.boxMesh.fromData(objBox)
128
        self.boxMesh.addProgram(self.program)
129
        self.boxMesh.scale(0.25)
130
        self.boxMeshID = self.scenegraph.establish(self.boxMesh)
131
132
        self.vpManager = ViewportManager()
133
        self.vpFull = self.vpManager.create_viewport('full', None)
134
        
135
        self.cameraOrtho = camera.Camera(camera.MODE_ORTHOGRAPHIC)
136
        self.cameraOrtho.set_view(self.vpManager.view)
137
        self.cameraOrtho.set_projection(0.0, self.width, self.height, 0.0, -1.0, 1.0)
138
        
139
        self.camera = camera.Camera(camera.MODE_PERSPECTIVE)
140
        self.viewport = self.vpManager.create_viewport('scene', self.camera)
141
        
142
        self.camera.setPosition(vector.Vector(3, data=[0.5, -2.0, 10.0]))
143
        self.camera.set_program( self.program)
144
        
145
        self.camera2 = camera.Camera(camera.MODE_PERSPECTIVE)
146
        self.viewport2 = self.vpManager.create_viewport('scene2', self.camera2)
147
        
148
        self.camera2.setPosition(vector.Vector(3, data=[0.5, 0.0, 12.0]))
149
        self.camera2.set_program( self.program)
150
        
151
        self.camera3 = camera.Camera(camera.MODE_PERSPECTIVE)
152
        self.viewport3 = self.vpManager.create_viewport('scene3', self.camera3)
153
        
154
        self.camera3.setPosition(vector.Vector(3, data=[30, 30.0, 15.0]))
155
        self.camera3.set_program(self.program)
156
        
157
        self.camera4 = camera.Camera(camera.MODE_PERSPECTIVE)
158
        self.viewport4 = self.vpManager.create_viewport('scene4', self.camera4)
159
        
160
        self.camera4.setPosition(vector.Vector(3, data=[-39, 35.0, 128.0]))
161
        self.camera4.set_program(self.program)
162
        
163
        self.halfWidth = int(self.width /2)
164
        self.halfHeight = int(self.height/2)
165
        
166
        self.viewport.set_rect (0,              0,               self.halfWidth, self.halfHeight)
167
        self.viewport2.set_rect(self.halfWidth, 0,               self.halfWidth, self.halfHeight)
168
        self.viewport3.set_rect(self.halfWidth, self.halfHeight, self.halfWidth, self.halfHeight)
169
        self.viewport4.set_rect(0,              self.halfHeight, self.halfWidth, self.halfHeight)
170
        
171
        self.vpFull.set_rect(0, 0, self.width, self.height)
172
        
173
        self.viewports = [self.viewport, self.viewport2, self.viewport3, self.viewport4]
174
        
175
        self.model = matrix.Matrix(4)
176
        #self.model = matrix.Matrix(4).translate(vector.Vector(3, data=[4.0, -2.0, -8]))
177
        
178
        
179
        self.loadText()
180
181
        glerr = gl.glGetError()
182
        if glerr != 0:
183
            print('GLError:', glerr)
184
185
    def loadText(self):
186
        vsPath = files.resolve_path('data', 'shaders', 'font.vs')
187
        fsPath = files.resolve_path('data', 'shaders', 'font.fs')
188
189
        vertex = shaders.VertexShader(vsPath)
190
        fragment = shaders.FragmentShader(fsPath)
191
        self.textProgram = shaders.ShaderProgram(vertex, fragment)
192
193
        fontPath = files.resolve_path('data', 'SourceCodePro-Regular.ttf')
194
        self.font = text.Font(12, fontPath)
195
        self.text = text.Text(self.textProgram, self.font)
196
197
        self.cameraOrtho.set_program(self.textProgram)
198
199
    def resize(self, width, height):
200
        self.width = width
201
        self.height = height
202
203
        self.halfWidth = int(self.width /2)
204
        self.halfHeight = int(self.height/2)
205
        
206
        self.viewport.set_rect (0,              0,               self.halfWidth, self.halfHeight)
207
        self.viewport2.set_rect(self.halfWidth, 0,               self.halfWidth, self.halfHeight)
208
        self.viewport3.set_rect(self.halfWidth, self.halfHeight, self.halfWidth, self.halfHeight)
209
        self.viewport4.set_rect(0,              self.halfHeight, self.halfWidth, self.halfHeight)
210
        self.vpFull.set_rect(0, 0, self.width, self.height)
211
        self.cameraOrtho.set_projection(0.0, self.width, self.height, 0.0, -1.0, 1.0)
212
213
    def process_event(self, event, data):
214
        if event == 'quit' or event == 'window_close':
215
            self.running = False
216
        elif event == 'window_resized':
217
            winID, x, y = data
218
            self.resize(x, y)
219
        elif event == 'mouse_move':
220
            if cursor.is_relative():
221
                self.mouseRelX, self.mouseRelY = data
222
            else:
223
                self.mousePosX, self.mousePosY = data
224
        elif event == 'key_down':
225
            if data[0] == 'c':
226
                cursor.set_relative_mode(True)
227
            elif data[0] == 'r':
228
                cursor.set_relative_mode(False)
229
                cursor.move_cursor(self.mousePosX, self.mousePosY)
230
            self.keys.append(data[0])
231
            print(self.keys)
232
        elif event == 'key_up':
233
            self.keys.remove(data[0])
234
        elif event == 'mouse_button_down':
235
            self.mouseButtons.append(data[0])
236
            print(self.mouseButtons)
237
        elif event == 'mouse_button_up':
238
            self.mouseButtons.remove(data[0])
239
240
    def keyUpdate(self):
241
242
        moveAmount = 0.5 * self.fpsTimer.tickDelta
243
        
244
        for key in self.keys:
245
            if key == 'w':
246
                self.camera.move(self.camera.vec_back, moveAmount)
247
248
            elif key == 's':
249
                self.camera.move(self.camera.vec_forward, moveAmount)
250
251
            elif key == 'a':
252
                self.camera.move(self.camera.vec_left, moveAmount)
253
254
            elif key == 'd':
255
                self.camera.move(self.camera.vec_right, moveAmount)
256
257
            elif key == 'q':
258
                self.camera.move(self.camera.vec_up, moveAmount)
259
260
            elif key == 'e':
261
                self.camera.move(self.camera.vec_down, moveAmount)
262
263
            elif key == 'UP':
264
                self.camera.rotate(self.camera.vec_right, moveAmount * 0.05)
265
266
            elif key == 'DOWN':
267
                self.camera.rotate(self.camera.vec_left, moveAmount * 0.05)
268
269
            elif key == 'LEFT':
270
                self.camera.rotate(self.camera.vec_up, moveAmount * 0.05)
271
272
            elif key == 'RIGHT':
273
                self.camera.rotate(self.camera.vec_down, moveAmount * 0.05)
274
275
    def mouseUpdate(self):
276
        if cursor.is_relative():
277
            if 1 in self.mouseButtons:
278
                tick = self.fpsTimer.tickDelta
279
                sensitivity = 0.5
280
                if self.mouseRelX != 0:
281
                    self.camera.rotate(self.camera.yAxis, math.radians(-self.mouseRelX * sensitivity * tick))
282
283
                if self.mouseRelY != 0:
284
                    self.camera.rotate(self.camera.vec_right, math.radians(-self.mouseRelY * sensitivity * tick))
285
            
286
            self.mouseRelX, self.mouseRelY = 0, 0
287
288
    def update(self):
289
        posVec = self.camera.position.vector
290
        self.boxMesh.translate(posVec[0], posVec[1], posVec[2]-2.0)
291
        self.mouseUpdate()
292
        self.keyUpdate()
293
        
294
        self.scenegraph.update()
295
296
    def render(self):
297
        self.vpManager.make_current(self.vpFull)
298
        gl.glClearColor(0.3, 0.3, 0.3, 1.0)
299
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
300
301
        # Change view to perspective projection
302
        gl.glDisable(gl.GL_BLEND)
303
        
304
        for vp in self.viewports:
305
306
            self.vpManager.make_current(vp)
307
            self.program.use()
308
            view = vp.camera.getViewMatrix()
309
            self.program.set_uniform_matrix(self.testID2, view)
310
311
            # Draw 3D stuff
312
            gl.glBindVertexArray(self.vao)
313
314
            self.scenegraph.render()
315
316
        gl.glBindVertexArray(0)
317
318
        gl.glEnable(gl.GL_BLEND)
319
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
320
321
        # Change to orthographic projection to draw the text
322
        self.vpManager.make_current(self.vpFull) 
323
        self.textProgram.use()
324
        self.cameraOrtho.make_current()
325
        self.text.draw_text(str(self.fpsEstimate) + ' FPS', 0, 10)
326
327
        gl.glDisable(gl.GL_BLEND)
328
329
330
    def do_run(self):
331
        ''' Process a single loop '''
332
        self.sysEvents.process()
333
        self.update()
334
        self.render()
335
        self.window.flip()
336
        self.fpsTimer.tick()
337
338
        if self.fpsTimer.fpsTime >= 2000:
339
            self.fpsEstimate = self.fpsTimer.get_fps()
340
            print("{:.2f} fps".format(self.fpsEstimate))
341
342
    def run(self):
343
        ''' Called from launcher doesnt exit until the game is quit '''
344
        self.running = True
345
        while self.running:
346
            self.do_run()