-
Notifications
You must be signed in to change notification settings - Fork 1
/
sparkle5.py
195 lines (159 loc) · 5.94 KB
/
sparkle5.py
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
# PyQt4 imports
from PyQt4 import QtGui, QtCore, QtOpenGL
from PyQt4.QtOpenGL import QGLWidget
# PyOpenGL imports
import OpenGL.GL as gl
import OpenGL.arrays.vbo as glvbo
import glhelpers
import numpy as np
import time
# Vertex shader
VS = """
#version 330
// Attribute variable that contains coordinates of the vertices.
layout(location = 0) in vec2 position;
// Main function, which needs to set `gl_Position`.
void main()
{
// The final position is transformed from a null signal to a sinewave here.
// We pass the position to gl_Position, by converting it into
// a 4D vector. The last coordinate should be 0 when rendering 2D figures.
int x = int(position.x / 256);
int y = int(position.x - (x*256));
gl_Position = vec4((x-128)*0.005, (y-128)*0.005, 0., 1.);
}
"""
# Fragment shader
FS = """
#version 330
// Output variable of the fragment shader, which is a 4D vector containing the
// RGBA components of the pixel color.
out vec4 out_color;
// Main fragment shader function.
void main()
{
// We simply set the pixel color to white.
out_color = vec4(1., 1., 1., 1.);
}
"""
VS_texture = """
#version 330
// Attribute variable that contains coordinates of the vertices.
//layout(location = 0) in vec3 position;
// Main function, which needs to set `gl_Position`.
void main()
{
//gl_Position = vec4(position.x, position.y, position.z, 1);
}
"""
# Fragment shader
FS_texture = """
#version 330
// Output variable of the fragment shader, which is a 4D vector containing the
// RGBA components of the pixel color.
out vec4 out_color;
// Main fragment shader function.
void main()
{
// We simply set the pixel color to white.
out_color = vec4(1., 1., 1., 1.);
}
"""
class GLPlotWidget(QGLWidget):
# default window size
width, height = 600, 600
t_last_msg = time.time()
spike_count = 0
def initializeGL(self):
"""Initialize OpenGL, VBOs, upload data on the GPU, etc."""
# background color
gl.glClearColor(0, 0, 0, 0)
vs = glhelpers.compile_vertex_shader(VS)
fs = glhelpers.compile_fragment_shader(FS)
self.shaders_program = glhelpers.link_shader_program(vs, fs)
vs_texture = glhelpers.compile_vertex_shader(VS_texture)
fs_texture = glhelpers.compile_fragment_shader(FS_texture)
self.shaders_program_texture = glhelpers.link_shader_program(vs_texture, fs_texture)
# create the texture
self.texture = gl.glGenTextures(1, ['sparkle'])
gl.glBindTexture(gl.GL_TEXTURE_2D, self.texture)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
gl.GL_LINEAR)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
gl.GL_LINEAR)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S,
gl.GL_CLAMP_TO_EDGE)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T,
gl.GL_CLAMP_TO_EDGE)
data = np.tile([255,0,255,0],(256, 256)).flatten()
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, 256, 256, 0,
gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, data)
self.fb = gl.glGenFramebuffers(1)
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fb);
gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
gl.GL_TEXTURE_2D, self.texture, 0);
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0); # unbind the framebuffer
self.square = glvbo.VBO(
np.array( [
[ -2,-2, 0 ],
[ 2,-2, 0 ],
[ 2, 2, 0 ],
[ -2,-2, 0 ],
[ 2, 2, 0 ],
[ -2, 2, 0 ],
],'f') * 0.25
)
def paintGL(self):
"""Paint the scene."""
# clear the buffer
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
data = np.random.randint(65536, size=10000)
vbo = glvbo.VBO(data)
vbo.bind()
self.spike_count += len(data)
# tell OpenGL that the VBO contains an array of vertices
# prepare the shader
gl.glEnableVertexAttribArray(0)
# identify what's in the array
gl.glVertexAttribPointer(0, 1, gl.GL_UNSIGNED_SHORT,
gl.GL_FALSE, 0, None)
gl.glUseProgram(self.shaders_program)
# draw "count" points from the VBO
gl.glDrawArrays(gl.GL_POINTS, 0, len(data))
gl.glEnable(gl.GL_TEXTURE_2D)
gl.glBindTexture(gl.GL_TEXTURE_2D, self.texture)
self.square.bind()
gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
#gl.glVertexPointerf(self.square)
gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT,
gl.GL_FALSE, 0, None)
gl.glUseProgram(self.shaders_program_texture)
gl.glUseProgram(0)
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
now = time.time()
if now > self.t_last_msg + 1:
dt = now - self.t_last_msg
print 'Mspikes per second = %1.1f' % (self.spike_count*0.000001/dt)
self.spike_count = 0
self.t_last_msg = now
# flag a redraw
self.update()
def resizeGL(self, width, height):
"""Called upon window resizing: reinitialize the viewport."""
# update the window size
self.width, self.height = width, height
# paint within the whole window
gl.glViewport(0, 0, width, height)
if __name__ == '__main__':
# define a Qt window with an OpenGL widget inside it
class TestWindow(QtGui.QMainWindow):
def __init__(self):
super(TestWindow, self).__init__()
# initialize the GL widget
self.widget = GLPlotWidget()
# put the window at the screen position (100, 100)
self.setGeometry(100, 100, self.widget.width, self.widget.height)
self.setCentralWidget(self.widget)
self.show()
# show the window
win = glhelpers.create_window(TestWindow)