File: gldraw.py

package info (click to toggle)
pybik 3.0-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 13,280 kB
  • sloc: python: 11,362; cpp: 5,116; xml: 264; makefile: 50; sh: 2
file content (329 lines) | stat: -rw-r--r-- 11,366 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#-*- coding:utf-8 -*-
# cython: profile=False

#  Copyright © 2009-2017  B. Clausius <barcc@gmx.de>
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

# pylint: disable=W0614,C0326
# although this file is compiled with Python3 syntax, Cython needs at least division from __future__
from __future__ import print_function, division

# This line makes cython happy
global __name__, __package__    # pylint: disable=W0604
#px/__compiled = True
__compiled = False

#px/from libc.math cimport M_PI, cos, sin
from math import radians, cos, sin

#pxm>IF '[[GLDEBUG]]' == 'gldebug'
#pxd+from [[_debug_VARIANT]] cimport *
#pxm>IF '[[GLDEBUG]]' != 'gldebug'
#pxd+from gl_[[GLVARIANT]] cimport *
#pxm>IF_END

#px:
from pybiklib.debug import DEBUG_LOGGL
try:
    if DEBUG_LOGGL:
        import OpenGL
        OpenGL.FULL_LOGGING = True
    from OpenGL.GLU import * # XXX: without the next line fails with python 3.5
    from OpenGL.GL import *     # pylint: disable=W0614,W0401
except ImportError as e:
    print('The pure Python mode needs PyOpenGL (for Python 3):', e)
    raise SystemExit(1)
import ctypes
from ctypes import sizeof
from OpenGL.raw.GL.VERSION.GL_2_0 import glVertexAttribPointer
#px.


#px/cdef enum: #
if True:
    DEBUG_MSGEXT = 8
#px+cdef long debug
debug = 0
    
def set_debug_flags(module):
    global debug
    if module.DEBUG_MSGEXT: debug |= DEBUG_MSGEXT
    
#px-
NULL = None

#pxd>cdef enum: #
#px-
if True:
    #pxd:
    MAX_TRANSFORMATIONS = 60
    MAX_BLOCKS = 1312
    MAX_FACES = 20
    ATTRIB_LOCATION = 0
    PICKATTRIB_LOCATION = 5
    ATTRIB_CNT = 7
    #px.

#pxd>ctypedef float vec4[4]
#pxd>ctypedef vec4 mat4[4]
#px:
vec4 = lambda: [0.]*4
mat4 = lambda: [[0.]*4 for _i in range(4)]
#px.

#pxm-FUNC PD nogil
def matrix_set_identity(matrix:'mat4 &'):
    matrix[0][0] = 1.; matrix[0][1] = 0.; matrix[0][2] = 0.; matrix[0][3] = 0.
    matrix[1][0] = 0.; matrix[1][1] = 1.; matrix[1][2] = 0.; matrix[1][3] = 0.
    matrix[2][0] = 0.; matrix[2][1] = 0.; matrix[2][2] = 1.; matrix[2][3] = 0.
    matrix[3][0] = 0.; matrix[3][1] = 0.; matrix[3][2] = 0.; matrix[3][3] = 1.
    
#px/cdef struct Block:
class Block:     # pylint: disable=R0903
#px-
    def __init__(self):
        #px/vec4 *transformation
        self.transformation = None
        
        #px/bint in_motion
        self.in_motion = None
        
        #px/int idx_triangles
        self.idx_triangles = None
        #px/int cnt_triangles
        self.cnt_triangles = None
        
#px/cdef struct Cube:
class cube:     # pylint: disable=W0232, R0903
    #px/mat4 transformations[MAX_TRANSFORMATIONS]
    transformations = [[[None]*4, [None]*4, [None]*4, [None]*4] for __t in range(MAX_TRANSFORMATIONS)]
        
    #px+unsigned int number_blocks
    #px/Block blocks[MAX_BLOCKS]
    blocks = [Block() for __block in range(MAX_BLOCKS)]
    
    #px+int cnt_pick
    #px+int idx_debug
    #px+int cnt_debug
    
    #px+GLuint object_location
    #px+GLuint glbuffer
    
    #px+int vertexdatalen
    #px+char *vertexdata
    #px/long attrib_pointers[ATTRIB_CNT]
    attrib_pointers = [None] * ATTRIB_CNT
    
    # animated slice
    #px/mat4 rotation_matrix
    rotation_matrix = mat4()
    
#px+cdef Cube cube


#pxm-FUNC PD
def init_gldraw():
    if debug & DEBUG_MSGEXT:
        print('init module:', __name__)
        print('  from package:', __package__)
        print('  compiled:', __compiled)
        #px+print('  GL-type: [[GLVARIANT]]')
    cube.number_blocks = 0
    cube.cnt_pick = 0
    cube.idx_debug = 0
    cube.cnt_debug = 0
    cube.vertexdatalen = 0
    cube.vertexdata = NULL
    
#pxm-FUNC PD nogil
def sync_block_transformations(blocks:'short *'):
    #px+cdef unsigned int i
    for i in range(cube.number_blocks):
        cube.blocks[i].transformation = cube.transformations[blocks[i]]
        cube.blocks[i].in_motion = False
    
#pxm-FUNC PD nogil
def sync_animation_start(blocks_count:int, blocks:'short *'):
    matrix_set_identity(cube.rotation_matrix)
    #px+cdef int i
    for i in range(blocks_count):
        cube.blocks[blocks[i]].in_motion = True
    
#pxm-FUNC PD nogil
def sync_animation_next(angle:float, rotation_x:float, rotation_y:float, rotation_z:float):
    #px/angle = angle / 180. * M_PI
    angle = radians(angle)
    #px+cdef float x, y, z
    x = rotation_x
    y = rotation_y
    z = rotation_z
    #px+cdef float c, s
    c = cos(angle)
    s = sin(angle)
    
    cube.rotation_matrix[0][0] = x*x*(1-c) + c
    cube.rotation_matrix[0][1] = x*y*(1-c) + z*s
    cube.rotation_matrix[0][2] = x*z*(1-c) - y*s
    cube.rotation_matrix[1][0] = y*x*(1-c) - z*s
    cube.rotation_matrix[1][1] = y*y*(1-c) + c
    cube.rotation_matrix[1][2] = y*z*(1-c) + x*s
    cube.rotation_matrix[2][0] = x*z*(1-c) + y*s
    cube.rotation_matrix[2][1] = y*z*(1-c) - x*s
    cube.rotation_matrix[2][2] = z*z*(1-c) + c
    
#pxm-FUNC P nogil
def matrix_mult(dest:'mat4 &', src1:'mat4 &', src2:'mat4 &'):
    #px+cdef int i, j, k
    #px+cdef float sum_
    for j in range(4):
        for i in range(4):
            sum_ = 0.
            for k in range(4):
                sum_ += src1[k][i] * src2[j][k]
            dest[j][i] = sum_
            
#pxm-FUNC PD nogil
def gl_draw_cube():
    #px+cdef unsigned int i
    #px/cdef mat4 object_matrix
    object_matrix = mat4()
    for i in range(cube.number_blocks):
        if cube.blocks[i].in_motion:
            matrix_mult(object_matrix, cube.rotation_matrix, cube.blocks[i].transformation)
            #px/glUniformMatrix4fv(cube.object_location, 1, GL_FALSE, &object_matrix[0][0])
            glUniformMatrix4fv(cube.object_location, 1, GL_FALSE, object_matrix)
        else:
            #px/glUniformMatrix4fv(cube.object_location, 1, GL_FALSE, &cube.blocks[i].transformation[0][0])
            glUniformMatrix4fv(cube.object_location, 1, GL_FALSE, cube.blocks[i].transformation)
        glDrawArrays(GL_TRIANGLES, cube.blocks[i].idx_triangles, cube.blocks[i].cnt_triangles)
        
#pxm-FUNC PD nogil
def gl_pick_cube():
    glDrawArrays(GL_TRIANGLES, 0, cube.cnt_pick)
    
#pxm-FUNC PD nogil
def gl_init_buffers():
    #px/glGenBuffers(1, &cube.glbuffer)
    cube.glbuffer = glGenBuffers(1)
    
#pxm-FUNC PD nogil
def gl_delete_buffers():
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    #px/glDeleteBuffers(1, &cube.glbuffer)
    glDeleteBuffers(1, [cube.glbuffer])
    cube.glbuffer = 0
    
#pxm-FUNC P nogil
def _gl_enable_pointer(index:'GLuint', size:'GLint', type:'GLenum', normalized:'GLboolean', pointer:'long'):
    #px/glVertexAttribPointer(index, size, type, normalized, 0, <void*>pointer)
    glVertexAttribPointer(index, size, type, normalized, 0, ctypes.cast(pointer, ctypes.c_void_p))
    glEnableVertexAttribArray(index)
    
#pxm-FUNC P nogil
def _gl_disable_pointer(index:'GLuint'):
    #px/glVertexAttribPointer(index, 4, GL_FLOAT, GL_FALSE, 0, NULL)
    glVertexAttribPointer(index, 4, GL_FLOAT, GL_FALSE, 0, ctypes.cast(0, ctypes.c_void_p))
    glDisableVertexAttribArray(index)
    
#pxm-FUNC PD nogil
def sync_blocks(nblocks:int, cnts_block:'short *', idx_debug:int, cnt_debug:int, cnt_pick:int):
    #px+cdef unsigned int idx_block, idx
    cube.number_blocks = nblocks
    
    idx_block = 0
    for idx in range(cube.number_blocks):
        cube.blocks[idx].idx_triangles = idx_block
        cube.blocks[idx].cnt_triangles = cnts_block[idx]
        idx_block += cnts_block[idx]
        
    cube.cnt_pick = cnt_pick
    cube.idx_debug = idx_debug
    cube.cnt_debug = cnt_debug
    
#pxm-FUNC PD nogil
def sync_vertexdata(vertexdatalen:int, vertexdata:'char *', vertexpointers:'long *'):
    cube.vertexdatalen = vertexdatalen
    cube.vertexdata = vertexdata
    cube.attrib_pointers[0] = 0
    cube.attrib_pointers[1] = vertexpointers[0]
    cube.attrib_pointers[2] = vertexpointers[1]
    cube.attrib_pointers[3] = vertexpointers[2]
    cube.attrib_pointers[4] = vertexpointers[3]
    cube.attrib_pointers[5] = vertexpointers[4]
    cube.attrib_pointers[6] = vertexpointers[5]
    
#pxm-FUNC PD nogil
def sync_transformations(transformations_count:int, transformations:'mat4 *'):
    #px+cdef int t
    #px+cdef unsigned int i, j
    for t in range(transformations_count):
        for i in range(4):
            for j in range(4):
                cube.transformations[t][i][j] = float(transformations[t][i][j])
                
#pxm-FUNC PD nogil
def gl_enable_data():
    glBindBuffer(GL_ARRAY_BUFFER, cube.glbuffer)
    glBufferData(GL_ARRAY_BUFFER, cube.vertexdatalen, cube.vertexdata, GL_STATIC_DRAW)
        
    _gl_enable_pointer(ATTRIB_LOCATION,   3, GL_FLOAT, GL_FALSE, cube.attrib_pointers[0])
    _gl_enable_pointer(ATTRIB_LOCATION+1, 3, GL_FLOAT, GL_FALSE, cube.attrib_pointers[1])
    _gl_enable_pointer(ATTRIB_LOCATION+2, 3, GL_UNSIGNED_BYTE, GL_TRUE, cube.attrib_pointers[2])
    _gl_enable_pointer(ATTRIB_LOCATION+3, 2, GL_FLOAT, GL_FALSE, cube.attrib_pointers[3])
    _gl_enable_pointer(ATTRIB_LOCATION+4, 3, GL_FLOAT, GL_FALSE, cube.attrib_pointers[4])
    _gl_enable_pointer(PICKATTRIB_LOCATION, 3, GL_FLOAT, GL_FALSE, cube.attrib_pointers[5])
    _gl_enable_pointer(PICKATTRIB_LOCATION+1, 3, GL_UNSIGNED_BYTE, GL_TRUE, cube.attrib_pointers[6])
    
#pxm-FUNC PD nogil
def gl_disable_data():
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    _gl_disable_pointer(ATTRIB_LOCATION)
    _gl_disable_pointer(ATTRIB_LOCATION+1)
    _gl_disable_pointer(ATTRIB_LOCATION+2)
    _gl_disable_pointer(ATTRIB_LOCATION+3)
    _gl_disable_pointer(ATTRIB_LOCATION+4)
    _gl_disable_pointer(PICKATTRIB_LOCATION)
    _gl_disable_pointer(PICKATTRIB_LOCATION+1)
    
#pxm-FUNC PD nogil
def gl_draw_cube_debug():
    #px/cdef mat4 object_matrix
    object_matrix = mat4()
    matrix_set_identity(object_matrix)
    #px/glUniformMatrix4fv(cube.object_location, 1, GL_FALSE, &object_matrix[0][0])
    glUniformMatrix4fv(cube.object_location, 1, GL_FALSE, object_matrix)
    glDrawArrays(GL_LINES, cube.idx_debug, cube.cnt_debug)
    
#pxm-FUNC PD nogil
def gl_draw_select_debug(selectdata:'GLfloat *', size:'GLsizeiptr', prog_hud:'GLuint'):
    #px+cdef int i, j
    #px+cdef GLintptr offset
    if cube.cnt_debug == 0:
        #XXX: The data used here has fixed size, but may not be initialized yet
        return
    offset = (cube.idx_debug+cube.cnt_debug) * 3 * sizeof(GLfloat)
    #px/glBufferSubData(GL_ARRAY_BUFFER, offset, size, &selectdata[0])
    glBufferSubData(GL_ARRAY_BUFFER, offset, len(selectdata) * sizeof(GLfloat), ArrayDatatype.asArray(selectdata, GL_FLOAT))
    
    glDisable(GL_DEPTH_TEST)
    glDrawArrays(GL_LINES, cube.idx_debug+cube.cnt_debug, 2)
    glUseProgram(prog_hud)
    glDrawArrays(GL_POINTS, cube.idx_debug+cube.cnt_debug+2, 2)
    
#pxm-FUNC PD nogil
def gl_init_object_location(location:'GLuint'):
    cube.object_location = location