File: shader-editor.py

package info (click to toggle)
glitch 0.6-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 488 kB
  • ctags: 649
  • sloc: python: 3,432; makefile: 2
file content (124 lines) | stat: -rw-r--r-- 3,520 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

import gobject
import gtk
import gtksourceview2

import OpenGL.GL as gl

import glitch, glitch.gtk
from glitch.limbo.objects import ColorfulTriangle
import OpenGL.GL.shaders as shaders

vertex = """
varying vec4 vertex_color;
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    vertex_color = gl_Color;
}
"""
fragment = """
varying vec4 vertex_color;
void main() {
    gl_FragColor = vertex_color;
}
"""
error_color = gtk.gdk.Color(1.0, 0.7, 0.7)
white = gtk.gdk.Color(1.0, 1.0, 1.0)

class InteractiveShadedNode(glitch.Shader):
    def compile(self, ctx):
        print 'compiling...',

        try:
            vshader = shaders.compileShader(self.vertex, gl.GL_VERTEX_SHADER)
        except Exception, e:
            print
            print e
            srcview1.modify_base(gtk.STATE_NORMAL, error_color)
            return ctx['shaders'][self][1]
        else:
            srcview1.modify_base(gtk.STATE_NORMAL, white)

        try:
            fshader = shaders.compileShader(self.fragment,
                gl.GL_FRAGMENT_SHADER)
        except Exception, e:
            print
            print e
            srcview2.modify_base(gtk.STATE_NORMAL, error_color)
            return ctx['shaders'][self][1]
        else:
            srcview2.modify_base(gtk.STATE_NORMAL, white)

        print 'ok'
        program = shaders.compileProgram(vshader, fshader)
        return program

def make_srcview(initial_text):
    buffer = gtksourceview2.Buffer()
    buffer.set_language(glsl)
    buffer.set_text(initial_text)

    srcview = gtksourceview2.View(buffer)
    srcview.set_size_request(400, -1)

    frame = gtk.Frame()
    frame.props.shadow_type = gtk.SHADOW_IN
    frame.add(srcview)
    return (frame, srcview, buffer)

def change_timeout(vertex_buffer, fragment_buffer, camera, obj):
    global change_timeout_id
    obj.vertex = vertex_buffer.get_text(*vertex_buffer.get_bounds())
    obj.fragment = fragment_buffer.get_text(*fragment_buffer.get_bounds())
    obj.version += 1
    camera.refresh()
    change_timeout_id = None

def vertex_changed(buffer, fragment_buffer, camera, obj):
    global change_timeout_id

    if change_timeout_id is not None:
        gobject.source_remove(change_timeout_id)

    change_timeout_id = gobject.timeout_add(1000,
        change_timeout, buffer, fragment_buffer, camera, obj)

def fragment_changed(buffer, vertex_buffer, camera, obj):
    global change_timeout_id

    if change_timeout_id is not None:
        gobject.source_remove(change_timeout_id)

    change_timeout_id = gobject.timeout_add(1000,
        change_timeout, vertex_buffer, buffer, camera, obj)

if __name__ == '__main__':
    change_timeout_id = None

    mgr = gtksourceview2.LanguageManager()
    glsl = mgr.get_language('glsl')

    w = gtk.Window()
    w.connect('destroy', lambda w: gtk.main_quit())

    hbox = gtk.HBox()
    vbox = gtk.VBox()
    vbox.set_spacing(1)

    (srcview1_frame, srcview1, buffer1) = make_srcview(vertex)
    (srcview2_frame, srcview2, buffer2) = make_srcview(fragment)

    obj = InteractiveShadedNode(children=[ColorfulTriangle()])
    camera = glitch.gtk.GtkCamera(eye=[1, 0, 3], children=[obj])
    buffer1.connect('changed', vertex_changed, buffer2, camera, obj)
    buffer2.connect('changed', fragment_changed, buffer1, camera, obj)

    vbox.pack_start(srcview1_frame, True)
    vbox.pack_start(srcview2_frame, True)
    hbox.pack_start(vbox, False)
    hbox.pack_start(camera, True)
    w.add(hbox)
    w.show_all()
    gtk.main()