Statistics
| Revision:

root / PyOpenGL-Demo / GLUT / shader_test.py @ 1

History | View | Annotate | Download (5.4 kB)

1 1 equemene
#! /usr/bin/env python
2 1 equemene
'''Tests rendering using shader objects from core GL or extensions
3 1 equemene

4 1 equemene
Uses the:
5 1 equemene
    Lighthouse 3D Tutorial toon shader
6 1 equemene
        http://www.lighthouse3d.com/opengl/glsl/index.php?toon2
7 1 equemene

8 1 equemene
By way of:
9 1 equemene
    http://www.pygame.org/wiki/GLSLExample
10 1 equemene
'''
11 1 equemene
import OpenGL
12 1 equemene
OpenGL.ERROR_ON_COPY = True
13 1 equemene
from OpenGL.GL import *
14 1 equemene
from OpenGL.GLU import *
15 1 equemene
from OpenGL.GLUT import *
16 1 equemene
17 1 equemene
# PyOpenGL 3.0.1 introduces this convenience module...
18 1 equemene
from OpenGL.GL.shaders import *
19 1 equemene
20 1 equemene
import time, sys
21 1 equemene
program = None
22 1 equemene
23 1 equemene
# A general OpenGL initialization function.  Sets all of the initial parameters.
24 1 equemene
def InitGL(Width, Height):                # We call this right after our OpenGL window is created.
25 1 equemene
    glClearColor(0.0, 0.0, 0.0, 0.0)    # This Will Clear The Background Color To Black
26 1 equemene
    glClearDepth(1.0)                    # Enables Clearing Of The Depth Buffer
27 1 equemene
    glDepthFunc(GL_LESS)                # The Type Of Depth Test To Do
28 1 equemene
    glEnable(GL_DEPTH_TEST)                # Enables Depth Testing
29 1 equemene
    glShadeModel(GL_SMOOTH)                # Enables Smooth Color Shading
30 1 equemene
31 1 equemene
    glMatrixMode(GL_PROJECTION)
32 1 equemene
    glLoadIdentity()                    # Reset The Projection Matrix
33 1 equemene
                                        # Calculate The Aspect Ratio Of The Window
34 1 equemene
    gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
35 1 equemene
36 1 equemene
    glMatrixMode(GL_MODELVIEW)
37 1 equemene
38 1 equemene
    if not glUseProgram:
39 1 equemene
        print 'Missing Shader Objects!'
40 1 equemene
        sys.exit(1)
41 1 equemene
    global program
42 1 equemene
    program = compileProgram(
43 1 equemene
        compileShader('''
44 1 equemene
            varying vec3 normal;
45 1 equemene
            void main() {
46 1 equemene
                normal = gl_NormalMatrix * gl_Normal;
47 1 equemene
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
48 1 equemene
            }
49 1 equemene
        ''',GL_VERTEX_SHADER),
50 1 equemene
        compileShader('''
51 1 equemene
            varying vec3 normal;
52 1 equemene
            void main() {
53 1 equemene
                float intensity;
54 1 equemene
                vec4 color;
55 1 equemene
                vec3 n = normalize(normal);
56 1 equemene
                vec3 l = normalize(gl_LightSource[0].position).xyz;
57 1 equemene

58 1 equemene
                // quantize to 5 steps (0, .25, .5, .75 and 1)
59 1 equemene
                intensity = (floor(dot(l, n) * 4.0) + 1.0)/4.0;
60 1 equemene
                color = vec4(intensity*1.0, intensity*0.5, intensity*0.5,
61 1 equemene
                    intensity*1.0);
62 1 equemene

63 1 equemene
                gl_FragColor = color;
64 1 equemene
            }
65 1 equemene
    ''',GL_FRAGMENT_SHADER),)
66 1 equemene
67 1 equemene
# The function called when our window is resized (which shouldn't happen if you enable fullscreen, below)
68 1 equemene
def ReSizeGLScene(Width, Height):
69 1 equemene
    if Height == 0:                        # Prevent A Divide By Zero If The Window Is Too Small
70 1 equemene
        Height = 1
71 1 equemene
72 1 equemene
    glViewport(0, 0, Width, Height)        # Reset The Current Viewport And Perspective Transformation
73 1 equemene
    glMatrixMode(GL_PROJECTION)
74 1 equemene
    glLoadIdentity()
75 1 equemene
    gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
76 1 equemene
    glMatrixMode(GL_MODELVIEW)
77 1 equemene
78 1 equemene
# The main drawing function.
79 1 equemene
def DrawGLScene():
80 1 equemene
    # Clear The Screen And The Depth Buffer
81 1 equemene
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
82 1 equemene
    glLoadIdentity()                    # Reset The View
83 1 equemene
84 1 equemene
    # Move Left 1.5 units and into the screen 6.0 units.
85 1 equemene
    glTranslatef(-1.5, 0.0, -6.0)
86 1 equemene
87 1 equemene
    if program:
88 1 equemene
        glUseProgram(program)
89 1 equemene
    glutSolidSphere(1.0,32,32)
90 1 equemene
    glTranslate( 1,0,2 )
91 1 equemene
    glutSolidCube( 1.0 )
92 1 equemene
93 1 equemene
    #  since this is double buffered, swap the buffers to display what just got drawn.
94 1 equemene
    glutSwapBuffers()
95 1 equemene
96 1 equemene
# The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)
97 1 equemene
def keyPressed(*args):
98 1 equemene
    # If escape is pressed, kill everything.
99 1 equemene
    if args[0] == '\x1b':
100 1 equemene
        sys.exit()
101 1 equemene
102 1 equemene
def main():
103 1 equemene
    global window
104 1 equemene
    # For now we just pass glutInit one empty argument. I wasn't sure what should or could be passed in (tuple, list, ...)
105 1 equemene
    # Once I find out the right stuff based on reading the PyOpenGL source, I'll address this.
106 1 equemene
    glutInit(sys.argv)
107 1 equemene
108 1 equemene
    # Select type of Display mode:
109 1 equemene
    #  Double buffer
110 1 equemene
    #  RGBA color
111 1 equemene
    # Alpha components supported
112 1 equemene
    # Depth buffer
113 1 equemene
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
114 1 equemene
115 1 equemene
    # get a 640 x 480 window
116 1 equemene
    glutInitWindowSize(640, 480)
117 1 equemene
118 1 equemene
    # the window starts at the upper left corner of the screen
119 1 equemene
    glutInitWindowPosition(0, 0)
120 1 equemene
121 1 equemene
    # Okay, like the C version we retain the window id to use when closing, but for those of you new
122 1 equemene
    # to Python (like myself), remember this assignment would make the variable local and not global
123 1 equemene
    # if it weren't for the global declaration at the start of main.
124 1 equemene
    window = glutCreateWindow("Jeff Molofee's GL Code Tutorial ... NeHe '99")
125 1 equemene
126 1 equemene
       # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
127 1 equemene
    # set the function pointer and invoke a function to actually register the callback, otherwise it
128 1 equemene
    # would be very much like the C version of the code.
129 1 equemene
    glutDisplayFunc(DrawGLScene)
130 1 equemene
131 1 equemene
    # Uncomment this line to get full screen.
132 1 equemene
    #glutFullScreen()
133 1 equemene
134 1 equemene
    # When we are doing nothing, redraw the scene.
135 1 equemene
    glutIdleFunc(DrawGLScene)
136 1 equemene
137 1 equemene
    # Register the function called when our window is resized.
138 1 equemene
    glutReshapeFunc(ReSizeGLScene)
139 1 equemene
140 1 equemene
    # Register the function called when the keyboard is pressed.
141 1 equemene
    glutKeyboardFunc(keyPressed)
142 1 equemene
143 1 equemene
    # Initialize our window.
144 1 equemene
    InitGL(640, 480)
145 1 equemene
146 1 equemene
    # Start Event Processing Engine
147 1 equemene
    glutMainLoop()
148 1 equemene
149 1 equemene
# Print message to console, and kick off the main to get it rolling.
150 1 equemene
151 1 equemene
if __name__ == "__main__":
152 1 equemene
    print "Hit ESC key to quit."
153 1 equemene
    main()