1#! /usr/bin/env python 2from __future__ import print_function 3import os 4if not os.environ.get( 'PYOPENGL_PLATFORM' ): 5 os.environ['PYOPENGL_PLATFORM'] = 'osmesa' 6from math import pi, sin, cos 7import OpenGL 8OpenGL.USE_ACCELERATE = False 9from OpenGL.GL import * 10from OpenGL.GL.ARB.fragment_program import glGenProgramsARB 11from OpenGL.GLU import * 12from OpenGL.osmesa import * 13 14def sphere(radius, slices, stacks): 15 q = gluNewQuadric() 16 gluQuadricNormals(q, GLU_SMOOTH) 17 gluSphere(q, radius, slices, stacks) 18 gluDeleteQuadric(q) 19 20 21def cone(base, height, slices, stacks): 22 q = gluNewQuadric() 23 gluQuadricDrawStyle(q, GLU_FILL) 24 gluQuadricNormals(q, GLU_SMOOTH) 25 gluCylinder(q, base, 0.0, height, slices, stacks) 26 gluDeleteQuadric(q) 27 28 29def torus(innerRadius, outerRadius, sides, rings): 30 ringDelta = 2.0 * pi / rings 31 sideDelta = 2.0 * pi / sides 32 33 theta = 0.0 34 cosTheta = 1.0 35 sinTheta = 0.0 36 for i in range(rings - 1, -1, -1): 37 theta1 = theta + ringDelta 38 cosTheta1 = cos(theta1) 39 sinTheta1 = sin(theta1) 40 glBegin(GL_QUAD_STRIP) 41 phi = 0.0 42 for j in range(sides, -1, -1): 43 phi += sideDelta 44 cosPhi = cos(phi) 45 sinPhi = sin(phi) 46 dist = outerRadius + innerRadius * cosPhi 47 48 glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi) 49 glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, innerRadius * sinPhi) 50 glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi) 51 glVertex3f(cosTheta * dist, -sinTheta * dist, innerRadius * sinPhi) 52 glEnd() 53 theta = theta1 54 cosTheta = cosTheta1 55 sinTheta = sinTheta1 56 57 58def render_image(): 59 light_ambient = [0.0, 0.0, 0.0, 1.0] 60 light_diffuse = [1.0, 1.0, 1.0, 1.0] 61 light_specular = [1.0, 1.0, 1.0, 1.0] 62 light_position = [1.0, 1.0, 1.0, 0.0] 63 red_mat = [1.0, 0.2, 0.2, 1.0] 64 green_mat = [0.2, 1.0, 0.2, 1.0] 65 blue_mat = [0.2, 0.2, 1.0, 1.0] 66 67 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient) 68 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse) 69 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular) 70 glLightfv(GL_LIGHT0, GL_POSITION, light_position) 71 72 glEnable(GL_LIGHTING) 73 glEnable(GL_LIGHT0) 74 glEnable(GL_DEPTH_TEST) 75 76 glMatrixMode(GL_PROJECTION) 77 glLoadIdentity() 78 glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0) 79 glMatrixMode(GL_MODELVIEW) 80 81 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 82 83 glPushMatrix() 84 glRotatef(20.0, 1.0, 0.0, 0.0) 85 86 glPushMatrix() 87 glTranslatef(-0.75, 0.5, 0.0) 88 glRotatef(90.0, 1.0, 0.0, 0.0) 89 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat) 90 torus(0.275, 0.85, 20, 20) 91 glPopMatrix() 92 93 glPushMatrix() 94 glTranslatef(-0.75, -0.5, 0.0) 95 glRotatef(270.0, 1.0, 0.0, 0.0) 96 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green_mat) 97 cone(1.0, 2.0, 16, 1) 98 glPopMatrix() 99 100 glPushMatrix() 101 glTranslatef(0.75, 0.0, -1.0) 102 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat) 103 sphere(1.0, 20, 20) 104 glPopMatrix() 105 106 glPopMatrix() 107 108 # This is very important!!! 109 # Make sure buffered commands are finished!!! 110 glFinish() 111 112 113def write_ppm(buf, filename): 114 f = open(filename, "w") 115 if f: 116 h, w, c = buf.shape 117 print( "P3", file=f) 118 print( "# ascii ppm file created by osmesa",file=f) 119 print( "%i %i" % (w, h),file=f) 120 print("255",file=f) 121 for y in range(h - 1, -1, -1): 122 for x in range(w): 123 pixel = buf[y, x] 124 l = " %3d %3d %3d" % (pixel[0], pixel[1], pixel[2]) 125 f.write(l) 126 f.write("\n") 127 128if __name__ == '__main__': 129 from OpenGL import arrays 130 131 ctx = OSMesaCreateContext(OSMESA_RGBA, None) 132 #ctx = OSMesaCreateContextExt(OSMESA_RGBA, 32, 0, 0, None) 133 134 width, height = 400, 400 135 buf = arrays.GLubyteArray.zeros((height, width, 4)) 136 assert(OSMesaMakeCurrent(ctx, buf, GL_UNSIGNED_BYTE, width, height)) 137 138 assert(OSMesaGetCurrentContext()) 139 140 program = glGenProgramsARB(1) 141 assert(program) 142 143 z = glGetIntegerv(GL_DEPTH_BITS) 144 s = glGetIntegerv(GL_STENCIL_BITS) 145 a = glGetIntegerv(GL_ACCUM_RED_BITS) 146 print("Depth=%d Stencil=%d Accum=%d" % (z, s, a)) 147 148 print("Width=%d Height=%d" % (OSMesaGetIntegerv(OSMESA_WIDTH), 149 OSMesaGetIntegerv(OSMESA_HEIGHT))) 150 #OSMesaPixelStore(OSMESA_Y_UP, 0) 151 152 render_image() 153 154 write_ppm(buf, 'output.ppm') 155 156 OSMesaDestroyContext(ctx) 157