Advertisement
Guest User

wxgl sample

a guest
Jun 28th, 2017
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.91 KB | None | 0 0
  1. from __future__ import with_statement
  2.  
  3. import math
  4. import os
  5. import sys
  6. import numpy as np
  7. from contextlib import contextmanager
  8.  
  9. import wxversion
  10. wxversion.select('2.8')
  11. import wx
  12. import wx.glcanvas as wxgl
  13.  
  14. import OpenGL
  15. # OpenGL.ERROR_CHECKING = False
  16. from OpenGL.GL import *
  17. from OpenGL.GLU import *
  18.  
  19. fragment_src = r'''
  20. #version 120
  21.  
  22. const float bailout = 2.0;
  23. const int maxiter = 64;
  24.  
  25. uniform bool mandel;
  26. uniform vec2 pos;
  27.  
  28. vec2 csqr(vec2 z)
  29. {
  30.    float re = z[0] * z[0] - z[1] * z[1];
  31.    float im = 2 * z[0] * z[1];
  32.    return vec2(re, im);
  33. }
  34.  
  35. void main()
  36. {
  37.    vec2 c, z;
  38.    if (mandel) {
  39.        c = gl_TexCoord[0].st;
  40.        z = vec2(0, 0);
  41.    }
  42.    else {
  43.        c = pos;
  44.        z = gl_TexCoord[0].st;
  45.    }
  46.  
  47.    int i;
  48.    for (i = 0; i < maxiter; i++) {
  49.        if (length(z) >= bailout)
  50.            break;
  51.        z = csqr(z) + c;
  52.    }
  53.  
  54.    float k = 5 * i / maxiter;
  55.    switch (int(k)) {
  56.    case 0:  gl_FragColor = mix(vec4(0,0,1,1),vec4(0,1,1,1),k-0); break;
  57.    case 1:  gl_FragColor = mix(vec4(0,1,1,1),vec4(0,1,0,1),k-1); break;
  58.    case 2:  gl_FragColor = mix(vec4(0,1,0,1),vec4(1,1,0,1),k-2); break;
  59.    case 3:  gl_FragColor = mix(vec4(1,1,0,1),vec4(1,0,0,1),k-3); break;
  60.    case 4:  gl_FragColor = mix(vec4(1,0,0,1),vec4(1,0,1,1),k-4); break;
  61.    case 5:  gl_FragColor = vec4(0,0,0,1); break;
  62.    }
  63. }
  64. '''
  65.  
  66. @contextmanager
  67. def Attrib(attrib):
  68.     glPushAttrib(attrib)
  69.     yield
  70.     glPopAttrib()
  71.  
  72. @contextmanager
  73. def Matrix():
  74.     glPushMatrix()
  75.     yield
  76.     glPopMatrix()
  77.  
  78. @contextmanager
  79. def Primitive(type):
  80.     glBegin(type)
  81.     yield
  82.     try:
  83.         glEnd()
  84.     except Exception, e:
  85.         print 'exception: %s' % e
  86.  
  87. class GLCanvas(wxgl.GLCanvas):
  88.     attrib = [wxgl.WX_GL_RGBA, wxgl.WX_GL_DOUBLEBUFFER, 0]
  89.  
  90.     def __init__(self, parent, id = -1, *args, **kwargs):
  91.         wxgl.GLCanvas.__init__(self, parent, id, attribList = GLCanvas.attrib,
  92.                                *args, **kwargs)
  93.         self.realized = False
  94.         self.ctx = None
  95.         self.program = None
  96.         self.SetInitialSize((640, 640))
  97.         self.Bind(wx.EVT_SIZE, self.resize)
  98.         self.Bind(wx.EVT_ERASE_BACKGROUND, self.erase)
  99.  
  100.     def realize(self):
  101.         if self.realized:
  102.             self.SetCurrent(self.ctx)
  103.             return
  104.  
  105.         self.ctx = wxgl.GLContext(self)
  106.         self.SetCurrent(self.ctx)
  107.         self.init_shader()
  108.         self.realized = True
  109.  
  110.         if not self.program:
  111.             sys.exit(1)
  112.  
  113.     def erase(self, event):
  114.         pass
  115.  
  116.     def resize(self, event):
  117.         self.realize()
  118.         w, h = event.GetSize()
  119.         glViewport(0, 0, w, h)
  120.         with Attrib(GL_TRANSFORM_BIT):
  121.             glMatrixMode(GL_PROJECTION)
  122.             glLoadIdentity()
  123.             gluOrtho2D(-2, 2, -2, 2)
  124.  
  125.     def init_shader(self):
  126.         if not bool(glCreateShader):
  127.             raise NotImplementedError('shaders not supported')
  128.  
  129.         shader = glCreateShader(GL_FRAGMENT_SHADER)
  130.         glShaderSource(shader, fragment_src)
  131.         glCompileShader(shader)
  132.         if not glGetShaderiv(shader, GL_COMPILE_STATUS):
  133.             raise RuntimeError(glGetShaderInfoLog(shader))
  134.  
  135.         program = glCreateProgram()
  136.         glAttachShader(program, shader)
  137.         glLinkProgram(program)
  138.         if not glGetProgramiv(program, GL_LINK_STATUS):
  139.             raise RuntimeError(glGetProgramInfoLog(program))
  140.  
  141.         self.program = program
  142.  
  143.     @staticmethod
  144.     def quad():
  145.         with Primitive(GL_QUADS):
  146.             for v in [(-2,-2), (2,-2), (2,2), (-2,2)]:
  147.                 glTexCoord2f(*v)
  148.                 glVertex2f(*v)
  149.  
  150. class Mandelbrot(GLCanvas):
  151.     def __init__(self, *args, **kwargs):
  152.         GLCanvas.__init__(self, *args, **kwargs)
  153.         self.pos = (0, 0)
  154.         self.Bind(wx.EVT_PAINT, self.expose)
  155.         self.Bind(wx.EVT_MOTION, self.motion)
  156.  
  157.     def motion(self, event):
  158.         self.realize()
  159.         x, y = event.GetPosition()
  160.         w, h = self.GetSize()
  161.         x =  4.0 * x / w - 2
  162.         y = -4.0 * y / h + 2
  163.         self.pos = x, y
  164.         self.GetParent().julia.Refresh()
  165.  
  166.     def expose(self, event):
  167.         dc = wx.PaintDC(self)
  168.         self.realize()
  169.         glClear(GL_COLOR_BUFFER_BIT)
  170.         glUseProgram(self.program)
  171.         with Matrix():
  172.             glLoadIdentity()
  173.             glUniform1i(glGetUniformLocation(self.program, "mandel"), 1)
  174.             GLCanvas.quad()
  175.         self.SwapBuffers()
  176.  
  177. class Julia(GLCanvas):
  178.     def __init__(self, *args, **kwargs):
  179.         GLCanvas.__init__(self, *args, **kwargs)
  180.         self.Bind(wx.EVT_PAINT, self.expose)
  181.  
  182.     def expose(self, event):
  183.         dc = wx.PaintDC(self)
  184.         self.realize()
  185.         glClear(GL_COLOR_BUFFER_BIT)
  186.         glUseProgram(self.program)
  187.         with Matrix():
  188.             glLoadIdentity()
  189.             pos = self.GetParent().mandel.pos
  190.             glUniform1i(glGetUniformLocation(self.program, "mandel"), 0)
  191.             glUniform2f(glGetUniformLocation(self.program, "pos"), pos[0], pos[1])
  192.             GLCanvas.quad()
  193.         self.SwapBuffers()
  194.  
  195. class MyFrame(wx.Frame):
  196.     def __init__(self):
  197.         wx.Frame.__init__(self, None, -1, "Fractal")
  198.         self.Create()
  199.         self.Bind(wx.EVT_CLOSE, self.Close)
  200.  
  201.     def Close(self, event):
  202.         self.Destroy()
  203.  
  204.     def Create(self):
  205.         self.mandel = Mandelbrot(self)
  206.         self.julia = Julia(self)
  207.  
  208.         sizer = wx.BoxSizer(wx.HORIZONTAL)
  209.         sizer.Add(self.mandel, 1, wx.EXPAND)
  210.         sizer.Add(self.julia, 1, wx.EXPAND)
  211.         self.SetSizerAndFit(sizer)
  212.  
  213. class MyApp(wx.App):
  214.     def __init__(self, *args, **kwargs):
  215.         wx.App.__init__(self, redirect = False, *args, **kwargs)
  216.  
  217.     def OnInit(self):
  218.         self.mainwin = MyFrame()
  219.         self.mainwin.Show()
  220.         self.SetTopWindow(self.mainwin)
  221.         return True
  222.  
  223. if __name__ == "__main__":
  224.     app = MyApp()
  225.     app.MainLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement