PC:
Graphics card:
Interface between CPU & graphics card: |
|
Interface between graphics card & display: |
|
API = Application Programming Interface
Python, C++, Java, Fortran, etc are languages
OpenGL, Direct3D, etc are graphics APIs
A graphics API can be used with any language, if there's a binding
OpenGL, Direct3D
Very basic commands for things like:
Most data management handled by application
A scene graph is a tree used to represent a graphical scene
"Nodes" represent things like groupings, transformations, lights, geometry
Common features:
Instead of writing code, plug together higher-level components
OpenGL uses the model of a pipeline
Commands and data are fed into the pipeline, processing is done, and the result (an image) comes out the other end (the display)
OpenGL libraries: |
|
OpenGL consists of commands related to drawing 2D & 3D objects (e.g. draw a triangle, define material properties, define a texture).
Drawing takes place in some sort of window, controlled by an operating system.
OpenGL avoids including any sort of functions to create or manipulate windows, or to do other user interface tasks (reading keyboard/mouse, etc).
GLUT (GL Utility Toolkit) provides functions for windowing and interaction.
It defines a simple interface that hides the OS-specific details of these tasks.
GLUT functions can be used in the same way under Unix, MacOS, and Windows, making GLUT-based programs more portable.
GLUT defines a basic program structure - an event loop, with callback functions.
callback - a function that you provide for other code to call when needed; the "other code" is typically in a library
GLUT uses callbacks for drawing, keyboard & mouse input, and other events.
Whenever the window must be redrawn, your drawing callback is called.
Whenever an input event occurs, your corresponding callback is called.
# Minimal program to open & clear a window. # This program is intended to introduce GLUT. import sys from OpenGL.GLUT import * from OpenGL.GL import * from OpenGL.GLU import * def draw(): glClear(GL_COLOR_BUFFER_BIT) glFlush() def keyboard(key, x, y): if key == chr(27): sys.exit(0) glutInit([]) glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB) glutInitWindowSize(200, 200) glutInitWindowPosition(0,0) glutCreateWindow(sys.argv[0]) glutDisplayFunc(draw) glutKeyboardFunc(keyboard) glutMainLoop()
Visit python.org for lots of information, and to download a copy of Python.
Python is an object-oriented scripting language.
Some highlights are:
Features:
C / C++ |
int factorial(int n) { if (n > 0) return n * factorial(n-1); else return 1; } |
---|
Python |
def factorial(n): if n > 0: return n * factorial(n-1) else: return 1 |
---|
Anything following a # is a comment.
>>> print 1 # this is a comment 1 >>> # This whole line is a comment
Numbers can be integers or floating point. e.g.:
1 -77777 3.14159265 1.5e+12
Complex numbers, hexadecimal & octal numbers, and 'long' integers are also supported.
>>> print 0xff 255 >>> print 1j * 1j (-1+0j)
Strings ("string literals", to be precise) are enclosed in quotes (single or double).
Multi-line strings are enclosed in triple-quotes.
'x' "Hello, world" """Twas brillig and the slithy toves did gyre and gimble in the wabe."""
Values can be written into a string with the % operator:
>>> x = 1 >>> y = 2 >>> 'x = %d, y = %f' % (x,y) 'x = 1, y = 2.000000'
Lists are like arrays in C, but they are dynamically allocated.
They can grow to any size, without being fixed in advance.
A list is written in square brackets; entries are separated by commas.
Indexing starts from 0:
>>> x = ['a', 'b', 'c'] >>> print x[2] c
Because Python is dynamically typed, list elements do not all have to be of the same type.
>>> x = ['abc', 17.3] >>> y = [1, ['abc', 17.3], 2]
A variable name is a series of alphanumeric characters; the first must be a letter. Names are case-sensitive.
Variables do not need to be declared. A variable is automatically allocated when a value is assigned to it.
>>> x = 6 >>> print x * 9 54 >>> stringVariable27 = 'A string' >>> print stringVariable27 A string >>> y = x + stringVariable27 Traceback (most recent call last): File "", line 1, in ? TypeError: unsupported operand types for +: 'int' and 'str'
Standard mathematical operators exist for numbers.
Some also apply to strings and lists.
Numbers | Strings | Lists | |
---|---|---|---|
+ | Addition | Concatenation | Concatenation |
- | Subtraction / negation | ||
* | Multiplication | Repetition | Repetition |
/ | Division | ||
% | Remainder | Formatting |
Logical operators are used for conditional expressions.
Similar to C, the numeric value 0 is equivalent to the logical value 'False',
and non-0 is equivalent to 'True'.
or | Logical or |
and | Logical and |
not | Logical negation |
< <= > >= == != | Numeric or string comparison |
in | String or list membership |
>>> 1 in [3,2,1] and 7 > 5 True
Blocks of statements are defined by their level of indentation.
The first level of statements should have no indentation.
New levels are introduced by statements such as if, while, and
for.
The = operator performs assignment of values to variables
>>> x = 7 >>> str = 'abc' * x >>> a,b = -1, 3
>>> if 1 > 2: ... print "Something's wrong" ... >>> >>> if (x > 3) and (x < 4): ... y = x ... elif x > 5: ... y = x / 2 ... else: ... y = x * 2 ...
Loops are normally performed over a list
>>> for i in ['a', 'b']: ... print i ... a b
The range generates a list of numbers
>>> for j in range(0,3): ... print j ... 0 1 2
>>> while x < 10: ... x = x * 2 ...
>>> print 'abc' * x abcabcabcabcabcabcabc
pass is a placeholder, that does nothing (a "no-op").
Functions are defined using the def statement.
They are called using the function name followed by parentheses,
with any arguments inside the parentheses.
>>> def double(x): ... print x * 2 ... >>> double(3) 6
A value can be returned from a function by the return statement.
>>> def factorial(n): ... if n > 0: ... return n * factorial(n-1) ... else: ... return 1 ... >>> x = factorial(5) >>> print x 120
By default, variables that are assigned to in a function only exist within that function - i.e. they have local scope.
The global statement declares that a variable
has global scope.
This will make it visible outside of the function, after the function has
been called.
It also allows you to use variables already defined in the
global scope.
>>> def foo(a): ... global y ... y = a ... print y ... >>> foo(12) 12 >>> print y 12
Modules are pre-written packages of code that can be
used in a Python program.
They are similar to libraries in other languages.
Many standard modules exist, such as math (trig and other math functions), and string (useful string-handling functions).
You can also create new modules to encapsulate your own code.
A module is loaded using the import statement.
Once it's imported, all of a module's functions and variables are
accessible, through the module name.
>>> import math >>> math.sin(1) 0.8414709848078965
The from ... import * statement can be used to avoid having to prefix the functions with the module name.
>>> from math import * >>> sin(1) 0.8414709848078965 >>> pi 3.1415926535897931
Create your own modules by placing the code in a file with the
extension ".py".
Don't include the .py extension when importing the module.
/home/dave> cat > mymodule.py def foo(x): return x * 17 /home/dave> python Python 2.2.2 (#1, Mar 17 2003, 15:17:58) [GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import mymodule >>> mymodule.foo(3) 51
Lists can be 'sliced' using indexing and the colon.
This produces a sub-list.
Slicing can also be applied to strings.
>>> a = [1, 2, 3, 4, 5, 6, 7] >>> a[3:6] [4, 5, 6]
Other functions that exist for lists are: append, sort, reverse, index, and the global function len.
>>> b = [3, 7, 2, 1] >>> b.sort() >>> b [1, 2, 3, 7] >>> b.index(3) 2 >>> len(b) 4
A tuple is like a list, except that it is immutable -
its contents can't be changed once created.
Tuples are defined in parentheses, rather than square brackets,
or just as a series of comma-separated values with nothing around them.
>>> x = (1, 2, 3)
A major use for tuples is for multiple return values from a function.
>>> def doubledouble(x,y): ... return x*2, y*2 ... >>> a,b = doubledouble(3,5) >>> print a 6 >>> print b 10
A dictionary is like a list, except that you can index it by any sort of value.
>>> prim = { 'point' : 1, 'line' : 2, 'triangle' : 3 } >>> prim['line'] 2
A dictionary consists of keys and values. These can be retrieved via the functions keys and values.
>>> primitive.keys() ['line', 'triangle', 'point'] >>> primitive.values() [2, 3, 1]
The function has_key is useful to find out if a particular key exists in a dictionary, before trying to use it.
>>> primitive['square'] Traceback (most recent call last): File "", line 1, in ? KeyError: square >>> if primitive.has_key('square'): ... print primitive['square'] ... else: ... print 'no such key' ... no such key
A class is a data type, for objects that can contain both variables
and functions.
A new class is defined by the class statement.
>>> class triangle: ... def __init__(self, pos): ... self.pos = pos ... self.timesDrawn = 0 ... def draw(self): ... print 'drawing triangle at', self.pos ... self.timesDrawn += 1 ... >>> t = triangle([0,0,5]) >>> t.draw() drawing triangle at [0, 0, 5] >>> t.timesDrawn 1