omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Python OpenGLES

    Pythonista
    3
    20
    12818
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • omz
      omz last edited by

      Quite honestly, I don't fully understand your code, and my experience with OpenGL is somewhat limited/outdated. But I've done some experimentation with GLKit myself, so the following code may still be helpful to some degree. It's basically the minimal setup for using GLKViewController. The demo just draws a single color that changes over time. Note that you'll need the latest beta for this (build 160023 from earlier today).

      from objc_util import *
      import time
      import colorsys
      
      GLKView = ObjCClass('GLKView')
      GLKViewController = ObjCClass('GLKViewController')
      UINavigationController = ObjCClass('UINavigationController')
      UIBarButtonItem = ObjCClass('UIBarButtonItem')
      EAGLContext = ObjCClass('EAGLContext')
      
      glClearColor = c.glClearColor
      glClearColor.restype = None
      glClearColor.argtypes = [c_float, c_float, c_float, c_float]
      glClear = c.glClear
      glClear.restype = None
      glClear.argtypes = [c_uint]
      GL_COLOR_BUFFER_BIT = 0x00004000
      
      def glkView_drawInRect_(_self, _cmd, view, rect):
      	r, g, b = colorsys.hsv_to_rgb((time.time() * 0.1) % 1.0, 1, 1)
      	glClearColor(r, g, b, 1.0)
      	glClear(GL_COLOR_BUFFER_BIT)
      MyGLViewDelegate = create_objc_class('MyGLViewDelegate', methods=[glkView_drawInRect_], protocols=['GLKViewDelegate'])
      
      def dismiss(_self, _cmd):
      	self = ObjCInstance(_self)
      	self.view().delegate().release()
      	self.view().setDelegate_(None)
      	self.dismissViewControllerAnimated_completion_(True, None)
      MyGLViewController = create_objc_class('MyGLViewController', GLKViewController, methods=[dismiss])
      
      @on_main_thread
      def main():
      	context = EAGLContext.alloc().initWithAPI_(2).autorelease()
      	glview = GLKView.alloc().initWithFrame_(((0, 0), (320, 320))).autorelease()
      	delegate = MyGLViewDelegate.alloc().init()
      	glview.setDelegate_(delegate)
      	glview.setContext_(context)
      	glview.setEnableSetNeedsDisplay_(False)
      	glvc = MyGLViewController.alloc().initWithNibName_bundle_(None, None).autorelease()
      	glvc.setTitle_('GLKit Demo')
      	glvc.setView_(glview)
      	done_b = UIBarButtonItem.alloc().initWithTitle_style_target_action_('Done', 2, glvc, 'dismiss').autorelease()
      	glvc.navigationItem().setRightBarButtonItem_(done_b)
      	nav = UINavigationController.alloc().initWithRootViewController_(glvc)
      	rootvc = UIApplication.sharedApplication().keyWindow().rootViewController()
      	rootvc.presentModalViewController_animated_(nav, True)
      	nav.release()
      
      main()
      
      1 Reply Last reply Reply Quote 1
      • Cethric
        Cethric last edited by

        Thanks @omz for the response, it seems to work much better than what I had.
        I am in the process of intergrating it now, would it be possible to add the GLViewController into the pythonista ui.View? so that it would be possible to use Pythonista's view system instead of having to reference through ctypes to UIKit?

        I will push an updated version of the repo soon
        Thanks again

        1 Reply Last reply Reply Quote 0
        • JonB
          JonB last edited by

          you should be able to add a glkview as a subview of a ui.View. You might even consider a wrapper class which does that for you, creating the glview instance and storing it as an instance variable, setting the frame/bounds/flex correctly, etc.

          as the simplest approach,

          wrapper= ui.View(frame=(0,0,320,320))
          ObjCInstance(wrapper).addSubview_(glview)
          
          1 Reply Last reply Reply Quote 0
          • Cethric
            Cethric last edited by

            @JonB wouldn't doing that ignore the GLKViewController? and if not how would I impliment it? My current code which is a rewrite of @omz's MKMapView script does not seem to work correctly.

            1 Reply Last reply Reply Quote 0
            • JonB
              JonB last edited by

              this worked (after glvc.setview...)

                  v = ui.View(frame=(0,0,600,600))
                  vo = ObjCInstance(v)    
                  v.present('sheet') #must be presented for nextResponder to work
                  vo.nextResponder().addChildViewController_(glvc)
                  vo.addSubview_(glview)
              
              

              not sure this can be represented after the view is closed, might be worth hanging onto glvc, so you can add it after v is re-presented.

              1 Reply Last reply Reply Quote 0
              • Cethric
                Cethric last edited by

                Thanks @JonB it seems to be working now

                1 Reply Last reply Reply Quote 0
                • JonB
                  JonB last edited by

                  incidentally, when experimenting with this, i often got "The view is already being presented or an animation is running"..... @omz what does pythonista use to determine whether a view is already being presented (so we can make sure to clean it up before closing?)

                  1 Reply Last reply Reply Quote 0
                  • omz
                    omz last edited by

                    @JonB It basically checks if nextResponder is a UIViewController. The ui module creates view controllers for presentation automatically, and if a view already has an associated view controller, it usually means that it's currently being presented...

                    1 Reply Last reply Reply Quote 0
                    • Cethric
                      Cethric last edited by

                      How do I properly setup a GLKViewController delegate?
                      My current code does not seem to work at all

                      def glkViewControllerUpdate_(_controller):
                          print "Update", _controller
                      
                      GLKViewControllerDelegate_Class = create_objc_class('GLKViewControllerDelegate_Class', methods=[glkViewControllerUpdate_], protocols='GLKViewControllerDelegate')
                          
                      def GLKViewControllerDelegate():
                          return GLKViewControllerDelegate_Class.alloc().init()
                      

                      which is called in the GLKView class

                      self.vc = GKLViewController("Test GLES", self.glview)
                      self.vcd = GLKViewControllerDelegate()
                      self.vc.delegate = self.vcd
                      

                      GKLViewController is just a wrapper for the ctypes function

                      1 Reply Last reply Reply Quote 0
                      • omz
                        omz last edited by

                        @Cethric Your glkViewControllerUpdate_ method needs to have three parameters, e.g.

                        def glkViewControllerUpdate_(_self, _cmd, _controller):
                            ...
                        

                        (the actual names of the parameters don't really matter, I tend to use underscores to indicate that these are pointers and not actual objects...)

                        To actually set the delegate, use the setDelegate_ method, like this:

                        self.vc.setDelegate_(self.vcd)
                        
                        1 Reply Last reply Reply Quote 0
                        • Cethric
                          Cethric last edited by

                          @omz Thank you so much it seems to work now
                          Hopefully one last question, the 3 parameters only return pointers so what would be the 'best' solution to get the GLKViewController.framesPerSecond variable?

                          1 Reply Last reply Reply Quote 0
                          • omz
                            omz last edited by

                            Wrap the _controller parameter in an ObjCInstance:

                            def glkViewControllerUpdate_(_self, _cmd, _controller):
                                controller = ObjCInstance(_controller)
                                fps = controller.framesPerSecond()
                                dt = controller.timeSinceLastUpdate()
                                # ...
                            
                            1 Reply Last reply Reply Quote 0
                            • Cethric
                              Cethric last edited by

                              @omz thanks again it works now

                              1 Reply Last reply Reply Quote 0
                              • Cethric
                                Cethric last edited by

                                glCreateShader always fails but I don't know why

                                def loadShader(source, glsl_type):
                                    shader = GLuint()
                                    compiled = GLint()
                                    # Create the shader object
                                    shader = glCreateShader(glsl_type)
                                    if(shader == 0):
                                        print "Failed to create shader"
                                        return 0;
                                    # Load the shader source
                                    glShaderSource(shader, 1, shaderSrc, 0)
                                    # Compile the shader
                                    glCompileShader(shader)
                                    # Check the compile status
                                    
                                    glGetShaderiv(shader, GL_COMPILE_STATUS, ctypes.byref(compiled))
                                    if(not compiled):
                                        infoLen = GLint(0)
                                        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, ctypes.byref(infoLen))
                                        if(infoLen > 1):
                                            infoLog = (ctypes.c_char * infoLen)()
                                            glGetShaderInfoLog(shader, infoLen, 0, infoLog);
                                            print("Error compiling shader:\n%s\n" % infoLog);
                                        glDeleteShader(shader);
                                        return 0;
                                    return shader;
                                

                                How glCreateShader is referenced

                                try:
                                    glCreateShader = c.glCreateShader
                                    glCreateShader.restype = GLuint
                                    glCreateShader.argtypes = [GLenum]
                                except AttributeError as e:
                                    if DEBUG:
                                        print 'could not load the function'
                                        print e
                                

                                Called in the setup process as

                                class Renderer(Util.RenderCycler):
                                    def __init__(self):
                                        Util.RenderCycler.__init__(self)
                                        self.r, self.g, self.b = colorsys.hsv_to_rgb((time.time() * 0.1) % 1.0, 0.1, 1)
                                    
                                    def setup(self, context):
                                        if (EAGL.setCurrentContext(context)):
                                            glClearColor(1, 1, 1, 1.0)
                                            s = Util.loadShader("void main() {}", GLenum(GL_FRAGMENT_SHADER))
                                            print s
                                        else:
                                            print "Could not Setup OpenGLES"
                                            
                                    def update(self, dt):
                                        self.r, self.g, self.b = colorsys.hsv_to_rgb((time.time() * 0.1) % 1.0, 1.0, 1)
                                    
                                    def render(self, context):
                                        if (EAGL.setCurrentContext(context)):
                                            glClearColor(self.r, self.g, self.b, 1.0)
                                            glClear(GL_COLOR_BUFFER_BIT)
                                
                                1 Reply Last reply Reply Quote 0
                                • Cethric
                                  Cethric last edited by Cethric

                                  Anyone got an idea? @omz @JonB
                                  Is it potentially because I am calling it from a custom setup event and not on a onDraw or onUpdate event?

                                  EDIT: Never mind I answered my own question... It was because I was calling setup at the wrong time

                                  1 Reply Last reply Reply Quote 0
                                  • Cethric
                                    Cethric last edited by

                                    @omz @JonB is there a way to access the GLKit Math classes? (ie. GLKMatrix4)

                                    1 Reply Last reply Reply Quote 0
                                    • JonB
                                      JonB last edited by JonB

                                      you will need to find the structure definitions, and create your own ctypes structs.

                                      for instance http://developer.limneos.net/?framework=GLKit.framework&header=GLKit-Structs.h

                                      You will need to create classes that extend Structure, and implement the _fields_ appropriately. (note some of these are unions... you can either onherit from Union, or just pick which way you'd rather refer to the fields, and just use a Structure). these mostly sppesr to be simple arrays of 16 floats for example, so you could slso probably do GLKMatrix4=c_float*16 for example.

                                      All of the GLKMatrix4Makexxxxxxxx functions are inlined, so you have to make your own constructors. For the most basic stule, you just define the 16 coefficients directly. zfor the more complicated versions, https://searchcode.com/codesearch/view/70695332/ may have some ideas on what these should look like, so you can roll your own.

                                      1 Reply Last reply Reply Quote 0
                                      • Cethric
                                        Cethric last edited by

                                        Will look into it, thanks for the response

                                        1 Reply Last reply Reply Quote 0
                                        • Cethric
                                          Cethric last edited by

                                          Working on an example file main.py to test shaders and rendering. However I cannot get the view to show a cube I think the issue is with the MVP however I do not know at what point I am going wrong, can someone please look at it and let me know
                                          For simplicity I am using the euclid.py math library.

                                          Thanks in advanced.

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post
                                          Powered by NodeBB Forums | Contributors