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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import sys
import copy
from math import cos, sin
from ArcBall import * # ArcBallT and this tutorials set of points/vectors/matrix types
PI2 = 2.0*3.1415926535 # 2 * PI (not squared!) // PI Squared
# *********************** Globals ***********************
# Python 2.2 defines these directly
try:
True
except NameError:
True = 1==1
False = 1==0
g_Transform = Matrix4fT ()
g_LastRot = Matrix3fT ()
g_ThisRot = Matrix3fT ()
g_ArcBall = ArcBallT (640, 480)
g_isDragging = False
g_quadratic = None
# A general OpenGL initialization function. Sets all of the initial parameters.
def Initialize (Width, Height): # We call this right after our OpenGL window is created.
global g_quadratic
glClearColor(0.0, 0.0, 0.0, 1.0) # This Will Clear The Background Color To Black
glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LEQUAL) # The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST) # Enables Depth Testing
glShadeModel (GL_FLAT); # Select Flat Shading (Nice Definition Of Objects)
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # Really Nice Perspective Calculations
g_quadratic = gluNewQuadric();
gluQuadricNormals(g_quadratic, GLU_SMOOTH);
gluQuadricDrawStyle(g_quadratic, GLU_FILL);
# Why? this tutorial never maps any textures?! ?
# gluQuadricTexture(g_quadratic, GL_TRUE); # // Create Texture Coords
glEnable (GL_LIGHT0)
glEnable (GL_LIGHTING)
glEnable (GL_COLOR_MATERIAL)
return True
def Upon_Drag (cursor_x, cursor_y):
""" Mouse cursor is moving
Glut calls this function (when mouse button is down)
and pases the mouse cursor postion in window coords as the mouse moves.
"""
global g_isDragging, g_LastRot, g_Transform, g_ThisRot
if (g_isDragging):
mouse_pt = Point2fT (cursor_x, cursor_y)
ThisQuat = g_ArcBall.drag (mouse_pt) # // Update End Vector And Get Rotation As Quaternion
g_ThisRot = Matrix3fSetRotationFromQuat4f (ThisQuat) # // Convert Quaternion Into Matrix3fT
# Use correct Linear Algebra matrix multiplication C = A * B
g_ThisRot = Matrix3fMulMatrix3f (g_LastRot, g_ThisRot) # // Accumulate Last Rotation Into This One
g_Transform = Matrix4fSetRotationFromMatrix3f (g_Transform, g_ThisRot) # // Set Our Final Transform's Rotation From This One
return
def Upon_Click (button, button_state, cursor_x, cursor_y):
""" Mouse button clicked.
Glut calls this function when a mouse button is
clicked or released.
"""
global g_isDragging, g_LastRot, g_Transform, g_ThisRot
g_isDragging = False
if (button == GLUT_RIGHT_BUTTON and button_state == GLUT_UP):
# Right button click
g_LastRot = Matrix3fSetIdentity (); # // Reset Rotation
g_ThisRot = Matrix3fSetIdentity (); # // Reset Rotation
g_Transform = Matrix4fSetRotationFromMatrix3f (g_Transform, g_ThisRot); # // Reset Rotation
elif (button == GLUT_LEFT_BUTTON and button_state == GLUT_UP):
# Left button released
g_LastRot = copy.copy (g_ThisRot); # // Set Last Static Rotation To Last Dynamic One
elif (button == GLUT_LEFT_BUTTON and button_state == GLUT_DOWN):
# Left button clicked down
g_LastRot = copy.copy (g_ThisRot); # // Set Last Static Rotation To Last Dynamic One
g_isDragging = True # // Prepare For Dragging
mouse_pt = Point2fT (cursor_x, cursor_y)
g_ArcBall.click (mouse_pt); # // Update Start Vector And Prepare For Dragging
return
def Torus(MinorRadius, MajorRadius):
# // Draw A Torus With Normals
glBegin( GL_TRIANGLE_STRIP ); # // Start A Triangle Strip
for i in xrange (20): # // Stacks
for j in xrange (-1, 20): # // Slices
# NOTE, python's definition of modulus for negative numbers returns
# results different than C's
# (a / d)*d + a % d = a
if (j < 0):
wrapFrac = (-j%20)/20.0
wrapFrac *= -1.0
else:
wrapFrac = (j%20)/20.0;
phi = PI2*wrapFrac;
sinphi = sin(phi);
cosphi = cos(phi);
r = MajorRadius + MinorRadius*cosphi;
glNormal3f (sin(PI2*(i%20+wrapFrac)/20.0)*cosphi, sinphi, cos(PI2*(i%20+wrapFrac)/20.0)*cosphi);
glVertex3f (sin(PI2*(i%20+wrapFrac)/20.0)*r, MinorRadius*sinphi, cos(PI2*(i%20+wrapFrac)/20.0)*r);
glNormal3f (sin(PI2*(i+1%20+wrapFrac)/20.0)*cosphi, sinphi, cos(PI2*(i+1%20+wrapFrac)/20.0)*cosphi);
glVertex3f (sin(PI2*(i+1%20+wrapFrac)/20.0)*r, MinorRadius*sinphi, cos(PI2*(i+1%20+wrapFrac)/20.0)*r);
glEnd(); # // Done Torus
return
def Draw ():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); # // Clear Screen And Depth Buffer
glLoadIdentity(); # // Reset The Current Modelview Matrix
glTranslatef(-1.5,0.0,-6.0); # // Move Left 1.5 Units And Into The Screen 6.0
glPushMatrix(); # // NEW: Prepare Dynamic Transform
glMultMatrixf(g_Transform); # // NEW: Apply Dynamic Transform
glColor3f(0.75,0.75,1.0);
Torus(0.30,1.00);
glPopMatrix(); # // NEW: Unapply Dynamic Transform
glLoadIdentity(); # // Reset The Current Modelview Matrix
glTranslatef(1.5,0.0,-6.0); # // Move Right 1.5 Units And Into The Screen 7.0
glPushMatrix(); # // NEW: Prepare Dynamic Transform
glMultMatrixf(g_Transform); # // NEW: Apply Dynamic Transform
glColor3f(1.0,0.75,0.75);
gluSphere(g_quadratic,1.3,20,20);
glPopMatrix(); # // NEW: Unapply Dynamic Transform
glFlush (); # // Flush The GL Rendering Pipeline
glutSwapBuffers()
return
|