Created
April 30, 2018 07:56
-
-
Save wpk-/f5d8e19f66d4f059ccb2b3e914949304 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import struct | |
import moderngl as gl | |
def test_vao_bind(array_length, loop_count, context): | |
''' | |
The program sums the first `count` floats for each vertex. | |
For example, when `count == 3`, it sums 0 + 1 + 2 = 3 for vertex 1, | |
3 + 4 + 5 = 12 for vertex 2 and 0 + 0 + 0 = 0 for vertex 3. | |
The bug happens when array_length == 2 and loop_count == 2. One | |
would expect the following sums: | |
vertex 1: 0 + 1 = 1 | |
vertex 2: 3 + 4 = 7 | |
vertex 3: 0 + 0 = 0 | |
OpenGL returns 1, 6, 5 instead. I cannot see how 6 would be a sum of | |
two consecutive elements. | |
Args: | |
array_length: Controls how many elements are passed to the GLSL | |
float array `arr`. This is either 1, 2 or 3. For values < 3, | |
the `stride=3*4` argument makes sure to skip the omitted | |
numbers, so that vertex 2 always starts reading at 3 (index | |
3) and vertex 3 always starts reading at 0 (index 6). | |
loop_count: Controls how many numbers are summed. The loop count | |
should be less than or equal to array length. | |
''' | |
assert loop_count <= array_length | |
arr = (0, 1, 2, # Three floats for vertex 1, | |
3, 4, 5, # vertex 2, and | |
0, 0, 0) # three zeros for vertex 3. | |
buf_a = context.buffer(struct.pack('9f', *arr)) | |
buf_r = context.buffer(struct.pack('3f', 0, 0, 0)) | |
prog = context.program( | |
vertex_shader=''' | |
#version 400 | |
in float[{SIZE:d}] arr; | |
out float res; | |
void main() {{ | |
res = 0; | |
for (int i=0; i<{COUNT:d}; i++) {{ | |
res += arr[i]; | |
}} | |
}} | |
'''.format(SIZE=array_length, COUNT=loop_count), | |
varyings=['res'] | |
) | |
vao = context.vertex_array(prog, [(buf_a, '{:d}f'.format(array_length), 'arr')]) | |
vao.bind(prog['arr'].location, 'f', buf_a, '{:d}f'.format(array_length), offset=0, stride=3*4) | |
vao.transform(buf_r, gl.POINTS, vertices=3) | |
return struct.unpack('3f', buf_r.read()) | |
if __name__ == '__main__': | |
ctx = gl.create_standalone_context() | |
expected_output = { | |
(1, 1): (0., 3., 0.), | |
(2, 1): (0., 3., 0.), | |
(2, 2): (1., 7., 0.), | |
(3, 1): (0., 3., 0.), | |
(3, 2): (1., 7., 0.), | |
(3, 3): (3., 12., 0.), | |
} | |
for (length, count), expected in expected_output.items(): | |
result = test_vao_bind(length, count, ctx) | |
if result == expected: | |
print((length, count), 'as expected.') | |
else: | |
print((length, count), 'expected result', expected, | |
'but got', result, 'instead.') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have no tim e right now, I will explain later