Cython OpenGL VBO drawing

449 views
Skip to first unread message

Peter Varo

unread,
Oct 28, 2013, 12:32:06 PM10/28/13
to cython...@googlegroups.com
In the last few days, I created the windowing, contexting and eventhandling API with Cython on top of GLFW. It is super fast and working really nicely -- most of the time:)

Today I started testing some more advanced drawing techniques than the immidiate drawing mode (glBegin/glEnd) I used to testing if the context is working.
Even though the Vertex Arrays are working the Vertex Buffer objects are not, and I can not figure out why -- where is the problem? Do I have to enable something else? The problem is in the Cython code (syntax, pointers, etc..)?

This is my main python code, which imports the GLFW-based window I created, and adds a rendering event to it, which is the on_draw() method, which is called at the end of the event loop:

    import lib.pycasso.window
    import lib.pycasso.graphics

    class Window(lib.pycasso.window.Window):

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)

        def on_draw(self):
            lib.pycasso.graphics.draw()

    Window().run()

It also imports the graphics module, which contains the actual OpenGL drawing calls, it looks like this:

    from GL.gl cimport *
    from GL.glu cimport *

    # Vertex buffer object identifier
    cdef unsigned int vbo
    #  An interleaved array
    cdef float* array = [ -2, -2,  0,  # Vertex
                           1,  0,  0,  # Color
                           2,  0,  0,
                           0,  1,  0,
                           0,  2,  0,
                           0,  0,  1  ]

    glGenBuffers( 1, &vbo )
    glBindBuffer( GL_ARRAY_BUFFER, vbo )
    glBufferData( GL_ARRAY_BUFFER, sizeof( array ), array, GL_STATIC_DRAW )


    cpdef draw():

        glClear( GL_COLOR_BUFFER_BIT )
        glLoadIdentity()

        gluLookAt( 0,  0, 10,
                   0,  0,  0,
                   0,  1,  0 )

        glBindBuffer( GL_ARRAY_BUFFER, vbo )
        glEnableClientState( GL_VERTEX_ARRAY )
        glEnableClientState( GL_COLOR_ARRAY )

        glVertexPointer( 3, GL_FLOAT, 6*sizeof( float ), NULL )
        glColorPointer(  3, GL_FLOAT, 6*sizeof( float ), <void*>(3*sizeof( float )))

        glDrawArrays( GL_TRIANGLES, 0, 3 )

        glDisableClientState( GL_COLOR_ARRAY )
        glDisableClientState( GL_VERTEX_ARRAY )
        glBindBuffer( GL_ARRAY_BUFFER, 0 )

Now any time I run the main python file, the window appears, then colors to black (which means, it is clearing the color buffer (first line in on_draw method)) and then it quits, and gives me the:

Finished in 1.0s with exit code -11

message. It also opens the OS X Problem Reporter, where I get this: http://pastebin.com/sLwUJZp8

Any idea on what am I doing wrong?
Thank you very much,

P

Jeremy Moles

unread,
Oct 28, 2013, 12:44:11 PM10/28/13
to cython...@googlegroups.com
On 10/28/2013 12:32 PM, Peter Varo wrote:
> In the last few days, I created the windowing, contexting and
> eventhandling API with Cython on top of GLFW. It is super fast and
> working really nicely -- most of the time:)
>
> Today I started testing some /more advanced/ drawing techniques than
> the /immidiate drawing mode/ (glBegin/glEnd) I used to testing if the
I can't say what you might be doing wrong (your code actually looks
okay), but you may find my project (and particularly, this part) of my
project helpful as you develop OpenGL with Cython:

https://github.com/cubicool/sobek/blob/master/sobek/gles2/_gles2.pyx

Perhaps we can collaborate! I'm always looking to learn new stuff about
Cython, and sometimes it can be tough to get response on this list
unless you're reporting a bug (I'm not complaining, I'm sure people are
busy... :))

> P
> --
>
> ---
> You received this message because you are subscribed to the Google
> Groups "cython-users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to cython-users...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Peter Varo

unread,
Oct 28, 2013, 1:32:45 PM10/28/13
to cython...@googlegroups.com
In terminal the error says (previously I ran it in SublimeText3, that's why it was only exit code -11):

Segmentation fault: 11

What does this even mean?

@JeremyMoles: Well, I'm absolutely new to C and Cython as well, I only started using it a few days ago, so I don't think I can help you much.. I checked your project, and it looks promising, although I couldn't find anything helpful for my project.. Probably looking at wrong places?

Thanks for the quick reply,
Regards,

P

Stefan Behnel

unread,
Oct 28, 2013, 1:45:18 PM10/28/13
to cython...@googlegroups.com
Peter Varo, 28.10.2013 18:32:
> Segmentation fault: 11
> What does this even mean?

It means that you are reading from or writing to a memory area (segment)
that you do not own, i.e. that you did not allocate or that you already freed.

This can have lots of reasons in C, but this piece of your code looks
*very* suspicions:

<void*>(3*sizeof( float ))

You are casting a (small) number to a pointer here and thus reinterpret it
as a memory address. If the function that you are passing it into then
tries to read from that address, it's a sure crasher.

Stefan

Jeremy Moles

unread,
Oct 28, 2013, 1:49:45 PM10/28/13
to cython...@googlegroups.com
Yeah, OpenGL is funny like that. What it really wants is something it
can perform pointer arithmatic on with the base array. So, passing in a
number like this is actually the "right" way. :/

Took me a while to get my head around that too. :)

> Stefan
>

Peter Varo

unread,
Oct 28, 2013, 1:53:52 PM10/28/13
to cython...@googlegroups.com
So this does mean, that the segmantation fault is not because of <void*>(3*sizeof( float )) ?

Jeremy Moles

unread,
Oct 28, 2013, 1:57:19 PM10/28/13
to cython...@googlegroups.com
On 10/28/2013 01:53 PM, Peter Varo wrote:
> So this does mean, that the segmantation fault is not because of
> <void*>(3*sizeof( float )) ?
> --
>

It certainly still could be, my comment was only that while it looked
like the immediate culprint, you particuarly invocation isn't
necessarily (though again, still potentially) the problem.

Looking at your interleaved array data though, it appears to be correct.

Peter Varo

unread,
Oct 28, 2013, 2:27:26 PM10/28/13
to cython...@googlegroups.com
okay.. then let's say that this part is the problem.. so alternatively what pointer can I pass to glColorPointer then?

Peter Varo

unread,
Oct 28, 2013, 3:14:55 PM10/28/13
to cython...@googlegroups.com
This may help: the code stops running at glGenBuffers() -- I mean that call is never turning back.. I absolutely can't think of any reason why this is not working.. this function is so simple.. :/

Jeremy Moles

unread,
Oct 28, 2013, 3:21:18 PM10/28/13
to cython...@googlegroups.com
> --
>

Well, since you're no longer using "simple" OpenGL, it's possible that
something is wonky with your context. I don't know about Mac (and
wouldn't touch Apple with a pole of infinite length), but perhaps you
have to do something special with OpenGL "profiles" or similar.

Sorry I can't be of more help, but at least now you know what's up.

Peter Varo

unread,
Oct 28, 2013, 3:22:57 PM10/28/13
to cython...@googlegroups.com

Jeremy Moles

unread,
Oct 28, 2013, 3:24:18 PM10/28/13
to cython...@googlegroups.com
> --
>

I certainly recommend it, and have used it in every serious paid and
non-paid GL application I've ever written. :)

Tak another look at how I do it in my project (in that same link, at the
very bottom).

Peter Varo

unread,
Oct 29, 2013, 4:23:16 PM10/29/13
to cython...@googlegroups.com
I can't believe this.. I'm trying to fix this #?%@* problem for a days now, but without any luck..

Here is a snippet of my Window extension type:

    def __cinit__(self):

        if not glfwInit():
            print( 'Failed to initialize GLFW' )
            exit( EXIT_FAILURE )

        glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 2 )

        self.window = glfwCreateWindow( width, height, title, NULL, NULL )
        if not self.window:
            print( 'Failed to initialize Window' )
            glfwTerminate()
            exit( EXIT_FAILURE )

        glfwMakeContextCurrent( self.window )

        glewExperimental = True
        cdef GLenum glew_error = glewInit()
        if glew_error != GLEW_OK:
            print( 'Failed to initialize GLEW' )
            print( glewGetErrorString( glew_error ))
            glfwDestroyWindow( self.window )
            glfwTerminate()
            exit( EXIT_FAILURE )

        self.setup_before_drawing()

    cdef void setup_before_drawing(self):

        print( 0 )
        cdef GLuint VertexArrayID
        print( 1 )
        glGenVertexArrays( 1, &VertexArrayID )
        print( 2 )
        
As you can see I create the GLFW Window with a 2+ OpenGL content. Then I initialize GLEW and at the end I want to setup all the values before I draw, that is in setup_before_drawing() method.

In this method, I'm printing a number before and after each gl call -- and while 0 and 1 is printed out.. I get the segfault before the script reaches the print( 2 )!

So I guess GLEW did not solved my problem (although it doesn't hurt either that it is included:)) on this segfault thingy -- or probably I'm doing something not proper..

HELP ME PLEASE :/

Regards,

P

Daniele Nicolodi

unread,
Oct 29, 2013, 4:32:32 PM10/29/13
to cython...@googlegroups.com
On 29/10/2013 21:23, Peter Varo wrote:
> I can't believe this.. I'm trying to fix this *#?%@* problem* for a days
> now, but without any luck..
>

....

>
> HELP ME PLEASE :/

Can you post somewhere the C code this Cython code generates? Also
having the full Cython code would help...

Cheers,
Daniele

Peter Varo

unread,
Oct 29, 2013, 4:46:09 PM10/29/13
to cython...@googlegroups.com
This is pyx file and this one is the generated C file and this is my setup.py... I hope any of these could help!

Oh, and here is the main.py that is using these:

    import lib.pycasso.window
    from lib.pycasso.const import *

    class Window(lib.pycasso.window.Window):

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)

    # Create window and step into event loop
    Window().run()

Thanks for looking at it!
Cheers,

P

Peter Varo

unread,
Oct 29, 2013, 8:31:41 PM10/29/13
to cython...@googlegroups.com
I added these lines to my code:

    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 )
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2 )
    glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE )
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE )

And when I'm using: print( glGetString( GL_VERSION )) right after I created the content and initialized glew, which gives me this:

    b'3.2 NVIDIA-8.16.74 310.40.00.10f02'

So I guess glew is okay, OpenGL is okay and I got the *advanced* GL pointers and API.. so..

Peter Varo

unread,
Oct 29, 2013, 10:40:54 PM10/29/13
to cython...@googlegroups.com
I think this error has something to do with Cython, because I wrote the *real* part of the code in C (just to make sure) and it compiles and runs (although doesn't draw anything, but this is because I did not write the shaders -- so this part doesn't matter at all, I guess, since it is also missing from the Cython version).


Regards,

P

Peter Varo

unread,
Oct 30, 2013, 12:00:25 AM10/30/13
to cython...@googlegroups.com
I did an other test here: I wrapped the C file with Cython and it is also working!

The Cython file looks like this:

    cdef extern from '_window.c':
        int main()

    def calling_main():
        main()

And the Python file looks like this:

    from _window_cy import calling_main

    calling_main()

I mean there is no segfault anywhere..!

Cheers,

P

Robert Bradshaw

unread,
Oct 30, 2013, 12:26:35 AM10/30/13
to cython...@googlegroups.com
Just at stab in the dark--is your Window class (or something else you
need) going out of scope and getting garbage collected?
> --

Peter Varo

unread,
Oct 30, 2013, 12:38:48 AM10/30/13
to cython...@googlegroups.com
I don't think so, because:

  1. It has an eventloop which is called right at the end of the initialization -- which atm could only stopped, when you quits the application
  2. If I remove the glGenSomeBufferObject callings and replace it with some ancient GL immidiate mode drawings or even if render with simple vertex lists -- it is working. And as I found out, the problem is in a very simple line: glGenSomeBufferObject(1, &a_simple_integer) however afaik this line needs OpenGL 1.2+
  3. I don't delete this instance manually as you can see in my main Python file

Although what you are saying could be the problem but I don't know where or how to change it..

Regards,

P

Robert Bradshaw

unread,
Nov 1, 2013, 12:42:36 AM11/1/13
to cython...@googlegroups.com
In a quick scan of your files, one difference between the C version
and the Cython one is that in the method
do_this_before_drawing_anything() your GLuint vertexbuffer is a local
variable (that goes out of scope which scares me a bit) in Cython but
a global static in C.

- Robert

Peter Varo

unread,
Nov 1, 2013, 1:07:43 AM11/1/13
to cython...@googlegroups.com
Thanks, it was a really nice tip -- however it did not worked..
I replaced the declaration of vertexbuffer and VertexArrayID also, inside the do_this_before_drawing_anything() function with global references, and placed the declarations at the top of my Cython file.. compiled it, but still got segfault at the exact same place!

// Anyway, at least thanks for catching that stupid local->global declaration stuff.. that scared me too!!! :)

Cheers,

P

Robert Bradshaw

unread,
Nov 1, 2013, 1:31:25 AM11/1/13
to cython...@googlegroups.com
I would recommend porting your working "C" version over to Cython
(which should just work). Once you have that, try to make it "object
oriented" one chunk at a time if that's really what you want to do
(though the fact that you can only have one active "Window" class at a
time makes it hard to map onto this OO model and you'll probably want
to catch/prevent people trying to make two active Windows). My guess
is that there's some trivial bug somewhere but starting with a working
version might be easier than continuing to debug what you have.
Reply all
Reply to author
Forward
0 new messages