Working with TypedArrays in Brython and WebGL

175 views
Skip to first unread message

Anish Narayanan

unread,
Jul 8, 2015, 8:52:44 PM7/8/15
to bry...@googlegroups.com
Hi everyone,

I am currently trying to develop a 3d game using raw webgl through brython. Having used with pyopengl before, I quickly followed along with this tutorial to familiarize myself with webgl-specific details. In order to store the vertices of the triangle in the tutorial,  typed arrays (such as Float32Array) are required to pass data to webgl, as regular arrays throw the following error in brython:

Error: WebGL: drawArrays: bound vertex attribute buffers do not have sufficient size for given first and count

However, Float32Arrays cannot be directly created in brython with a simple Float32Array([vertex data goes here]) constructor call. Is there any way that these data types can be included in brython as builtin object types? Currently, I have a workaround using brython's JSConstructor, but it is unwieldly to use and requires ugly javascript snippets. A live demo using this hack to display a triangle can be found here. Any help to resolve this issue and simplify this code would be appreciated.

Thanks,
Anish

Kiko

unread,
Jul 9, 2015, 1:57:59 AM7/9/15
to bry...@googlegroups.com

--

It seems the following code works for me (the modified lines are in bold and no js is necessary I think):

    <script type="text/python">
            from browser import document, alert, window
            #from javascript import JSConstructor

            def disableScroll(event):
                event.preventDefault()
               
            def createProgram(vs, fs):
                program = gl.createProgram()
                vshader = createShader(vs, gl.VERTEX_SHADER)
                fshader = createShader(fs, gl.FRAGMENT_SHADER)
                gl.attachShader(program, vshader)
                gl.attachShader(program, fshader)
                gl.linkProgram(program)
                return program

            def createShader(shaderStr, shaderType):
                shader = gl.createShader(shaderType)
                gl.shaderSource(shader, shaderStr)
                gl.compileShader(shader)
                return shader

            document.bind("touchmove", disableScroll)
            stage = document.getElementById("glCanvas")
            stage.width = window.innerWidth
            stage.height = window.innerHeight
            gl = stage.getContext("webgl")
            gl.clearColor(0.5, 0, 0.8, 1)
            gl.clear(gl.COLOR_BUFFER_BIT)

            WebglArray = window.Float32Array

            vBuff = gl.createBuffer()
            gl.bindBuffer(gl.ARRAY_BUFFER, vBuff)
            vertices = [-0.5, -0.5, 0.5, -0.5, 0, 0.5]
            vertices = WebglArray(vertices)
            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

            vs = """
            attribute vec2 pos;
            void main()
            {
                gl_Position = vec4(pos, 0, 1);
            }
            """

            fs = """
            void main()
            {
                gl_FragColor = vec4(0.2, 0.0, 0.8, 1.0);
            }
            """

            program = createProgram(vs, fs)
            gl.useProgram(program)
            program.vertexPosAttrib = gl.getAttribLocation(program, "pos")
            gl.enableVertexAttribArray(program.vertexPosAttrib)
            gl.vertexAttribPointer(program.vertexPosAttrib, 2, gl.FLOAT, False, 0, 0)
            gl.drawArrays(gl.TRIANGLES, 0, 3)
       </script>

Let me know if this works for you.

Anish Narayanan

unread,
Jul 9, 2015, 10:10:52 AM7/9/15
to bry...@googlegroups.com
Yes, that works perfectly for me and is a lot more convenient. Thank you so much!
Reply all
Reply to author
Forward
0 new messages