Lecture 3

advertisement
Audio Engine Programming
Lecture 4
Functions, Arrays and Structures
in C++
Introduction
Last week we
 introduced the C++ language



similar to Java
different methods for I/O
Class construction
This lecture we will
 Introduce Graphics programming using
OpenGL and GLUT
 discuss functions, arrays and structures in C++
Rubik’s
cube
www.fcet.staffs.ac.uk/clf1/IP3DA/RubiksCubeIP3DA.wmv
Crane

lots of user
interaction to
move the
crane parts
and camera
www.fcet.staffs.ac.uk/clf1/IP3DA/CraneIP3DA.wmv
Solar
System
www.fcet.staffs.ac.uk/clf1/IP3DA/SolarSystemIP3D
A.wmv
WARNING


This module is challenging
But very rewarding






Attend every session and make notes
Work through the examples in the lecture slides
Read more as recommended
Keep up with the tutorial exercises each week



You will learn a lot which is relevant to your chosen subject
And be well qualified for the best placements
this will involve a substantial amount of work beyond the
scheduled classes
Ask questions
Don’t get behind


If you do get behind don’t give up
Ask for help!
Recommended Books


See Blackboard "Resources” section
"OpenGL: A Primer" 3rd Edition by Edward
Angel. Peason 2007.
http://www.pearsoned.co.uk/bookshop/detail.asp?item=10000
0000130707


"OpenGL Programming Guide - The Official Guide
to Learning OpenGL", Versions 3.0 and 3.1" by
Dave Shreiner 7th Edition. Pearson 2009
any introductory book on C++, such as

Bjarne Stroustrup, Programming: Principles and Practices
Using C++, Addison Wesley 2008
http://www.stroustrup.com/Programming/
ISBN 978-0321543721
Useful Web Resources


See Blackboard “Resources” section
The official Website for OpenGL, with news,
documentation, tutorials and downloads.
http://www.opengl.org/

Networking site for OpenGL
developers. Includes "The Official Guide to
Learning OpenGL, Version 1.1" (The Red Book,
previous slide)
http://glprogramming.com/

Microsoft's MSDN Library
C++ language reference
http://msdn.microsoft.com/en-us/library/3bstk3k5.aspx

Development environment

you can develop C++ programs on almost any
platform





Windows, Linux, PS3...
in the labs we will develop on Windows PCs
and use the Visual Studio Development
Environment
you can get a free copy through the MSDN
Academic Alliance - see
http://www.staffs.ac.uk/faculties/comp_eng_tech/
current_students_and_staff/usefulstuff.jsp
or your can download Visual C++ Express for
free from
http://www.microsoft.com/express/download/def
ault.aspx .
OpenGL

Versions of OpenGL are available for every
major operating system






Microsoft Windows
Apple Mac OS
Unix X Windows
OpenGL for Embedded Systems (OpenGL ES) is
implemented for Android phones, Java Mobile edition,
PS3, embedded systems....
We will be using the OpenGL libraries that come
with Visual Studio
we will also be using the GLUT library for
creating windows

download from
http://www.xmission.com/~nate/glut.html
What is OpenGL?

a cross-platform graphics API


allows developers to write 2D and 3D graphics
programs without having to write hardwarespecific code



rendering functionality
main competitor – Direct3D


Application Program Interface
Microsoft Windows platforms only
widely used in games development, virtual
reality, visualisation, CAD
free and open source
A very simple OpenGL program
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "glut.h"
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
int main(int argc, char* argv[]) {
glVertex2f(-0.75, 0.5);
glutInit(&argc, argv);
glVertex2f(0.75, 0.5);
glutCreateWindow("Simple
OpenGL Program");
glVertex2f(0.75, -0.5);
glutDisplayFunc(display);
glVertex2f(-0.75, -0.5);
glutMainLoop();
glEnd();
}
glFlush();
}
Program output
#include statements
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "glut.h"

makes library functions available



GL – graphics library
GLU – Utility Library
GLUT – graphics library utilities toolkit

for windowing and user input
display function
void display() {
glClear(GL_COLOR_BUFFER
_BIT);
glBegin(GL_POLYGON);
glVertex2f(-0.75, 0.5);
glVertex2f(0.75, 0.5);
glVertex2f(0.75, -0.5);
glVertex2f(-0.75, -0.5);
glEnd();
glFlush();
}




first clear the display to
the current background
colour (black)
then define a polygon
composed of the 2D
vertices which follow
end the polygon definition
then flush – render the
previous commands
OpenGL coordinates



(1, 1)
(-1, -1)
(1, -1)
by default (0,0) is at
the centre of the
window


(-1, 1)
each axis goes from -1
to 1
regardless of the
window dimensions
x increases to the right
y increases going up
main function
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutCreateWindow("Simple OpenGL Program");
glutDisplayFunc(display);
glutMainLoop();
}
 initialise the Utility Toolkit
 create a window with a title
 register the function “display” as the function to
be called whenever the window is redrawn
 start the event loop



listen for events (window, mouse, keyboard)
process them when they occur
until the window is closed
Changing the window defaults

by default the window is



size 300 x 300 pixels
positioned at the top left corner of the screen
you can change these using the functions
void glutInitWindowSize(int width, int height)
void glutInitWindowPosition(int x, int y)

note the y-axis increases as you go down in
screen coordinates
Specifying colours



by default OpenGL draws white shapes on a black
background
we can change these using the glColor*() and
glClearColor() functions
glClearColor has the signature
void glClearColor( GLClampf r, GLClampf g, GLClampf b,
GLClampf a)
 GLClampf is a float between 0.0 and 1.0
 a is the opacity (alpha): 1.0 is opaque

there are several forms of glColor*()



with or without a fourth (alpha) parameter
floats, integers (0-255)
separate parameters or an array
New main method
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(400, 200);
glutInitWindowPosition(500, 100);
glutCreateWindow("Simple OpenGL Program");
glutDisplayFunc(display);
glClearColor(0.2, 0.8, 1.0, 1.0);
glColor3f(1.0, 1.0, 0);
glutMainLoop();
}
OpenGL is a state machine



we specify the state of the system (colour,
viewing coordinates, materials)
all objects are rendered with that state until
the state is changed
so we can specify a drawing colour, which is
effective until a new colour is specified
display method with colours
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0);
glVertex2f(-0.75, 0.5);
glVertex2f(0.75, 0.5);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(0.75, -0.5);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(-0.75, -0.5);
glEnd();
glFlush();
}
 first two vertices are red, 3rd is green,
4th is blue
 the colours are interpolated between
the vertices
Drawing state

the same list of points can be rendered in
different ways depending on the parameter to
glBegin()











GL_POLYGON
GL_POINTS
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
GL_QUADS
GL_QUAD_STRIP
GL_RECT
display method with points
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5.0);
glBegin(GL_POINTS);
glVertex2f(-0.75, 0.5);
glVertex2f(0.75, 0.5);
glVertex2f(0.75, -0.5);
glVertex2f(-0.75, -0.5);
glEnd();
glFlush();
}
 experiment!!
Summary
Today we have
 introduced the module
 introduced OpenGL
 looked at a simple OpenGL program
Next lecture
 introduction to C++
Further reading
http://www.opengl.org/documentation/specs/ver
sion1.1/glspec1.1/node17.html
for documentation of the glBegin() parameters
C++ Functions

C++ functions are similar to those in Java, C, C#


also known as methods, subroutines, or procedures
general form:
type function_name (parameter list) {
statements;
return statement;
}

in C++ local variables can be declared anywhere in the
function


in C they must be declared at the beginning the function
unlike in Java and C#, C++ functions don't need to belong
to a class
A function to add two numbers
#include <iostream>
using namespace std;
int addNums(int x, int y) {
return x + y;
}
int main() {
int a = 3;
int b = 5;
int answer = addNums(a, b);
cout << a << " + " << b << " = " << answer <<
endl;
cout << "7 + 6 = " << addNums(7, 6) << endl;
}
Functions
in C++, C, Java, and C#, the return statement returns control to the
calling function
 the returned value must have the same type as the function
int addNums(int x, int y) {
return x + y;
}
 a function that does not return a value has type void


the return statement may be omitted
void error_mess (int err_no) {
cout << "Error " << err_no << " has occurred " <<
endl;
}
calling the function:
if (slope < 0)
error_mess(5);
}

Overloading functions

consider the addNums function
int addNums(int x, int y) {
return x + y;
}

it takes two integers as parameters





what if we wanted to add two doubles?
three integers?
we need to write more functions
we are allowed to give them the same name



and returns an int
as long as they can be distinguished by their parameter lists
this is function overloading
C does not allow overloading, but Java and C# do
Overloads of addNum
int addNums(int x, int y) {
return x + y;
}
double addNums(double x, double y) {
return x + y;
}
int addNums(int x, int y, int z) {
return x + y + z;
}

which function will be called by:
answer = addNums(3.1f, 4.5f); ?
answer = addNums(3, 4.5); ?
Overloading functions



selection of the correct function overload occurs
at compile time
the compiler will first try to find an exact match to
the parameter list
it then applies any possible type conversions


int or float to double
if the compiler cannot choose it will give an error
answer = addNums(3, 4.5);
error C2666: 'addNums' : 2 overloads have similar conversions
test.cpp(55): could be 'double addNums(double,double)'
test.cpp(51): or
'int addNums(int,int)'

the Java compiler is better at this!
Overloading functions


function overloads that have the same parameter list
but differ only in the return type are not allowed
how would the compiler know which overload to
call?
double addNums(double x, double y) {
return x + y;
}
int addNums(double x, double y) {
return (int)(x+y+0.5);
}
// …
int answer = addNums(3.2, 5.6);
// ????
error C2556: 'int addNums(double,double)' : overloaded
function differs only by return type from 'double
addNums(double,double)'
Default arguments

we can sometimes avoid writing multiple overloads by providing
default values in the function declaration
int addNums(int x, int y, int z = 0) {
return x + y + z;
}

can be called by both
answer = addNums(5, 2);
answer = addNums(3, 1, 8);


in the first call, z is assigned the value 0
parameters with default values must appear at the end of the
parameter list
why?

Java and C# don't allow default arguments
update:
C# has recently introduced them, in C# 4.0
http://msdn.microsoft.com/en-us/library/dd264739.aspx
Inline expansion


Function calls are expensive
The inline keyword requests that the compiler
replace every call to this function with the code
inside the function.
the compiler can ignore this request
inline int addNums(int x, int y) {
return x + y;
}


the function call
int answer = addNums(a, b);
might be expanded by the compiler to
int answer = a + b;
Inline expansion

advantage of inline expansion

avoids the overhead of function call and return


particularly useful for short functions
disadvantages

compiled program can take up more room in
memory


because function code is repeated for every function call
CPU can't take advantage of instruction caching
Function declaration



In C++ a function must be declared before it is used
(called)
so that the compiler can check that the correct parameters
and return types are being used
this is why the main method appears last in all our
examples


not a problem in Java or C#


the main method calls functions which have been declared above
it
functions can appear in any order
later we will see how we can use function prototypes and
header files to structure C++ programs
Arrays

An array is a collection of elements


The elements are of the same type
The elements can be accessed with an integer
index
myArray
3 5 1 2 4 8 7 9
0 1 2 3 4 5 6 7

index
For example:
cout << "Array element 5 is " << myArray[5] << endl;
Outputs: Array element 5 is 8
Creating an array


unlike in Java, the
keyword new is not
required to create a C++
array
simply declaring an array
of a given size allocates
space for the array on the
stack
total space =
size of array * size of each
element
Address
name
value
1245012
num[4]
4
1245008
num[3]
2
1245004
num[2]
5
1245000
num[1]
1
1244996
num[0]
3
int num[ 5 ] = { 3, 1, 5, 2, 4 };
Stack: area of memory sequentially filled as a code block executes
Declaring Arrays on the stack

the number of array elements must be specified when
the array is declared
so that the correct space on the stack can be reserved
int num[5]; char name[20];
not
int num[ ]; char name[ ]; or int[ ] num; char[ ] name;


you can use the #define preprocessor directive to
define an array size
easier to change if needed
#define N 5
 the preprocessor will replace N by 5 wherever it appears

Array example
#include <iostream>
#define N 5
using namespace std;
Please enter 5 integers: 2 4 6 8 10
10 8 6 4 2
int main( ) {
int num[N];
cout << "Please enter " << N << " integers: ";
for (int i=0; i<N; i++)
cin >> num[i];
for (int i=(N-1); i >= 0; i--)
cout << num[i] << " ";
cout << endl;
}
Array initialisation

Unlike Java, a C++ array is not initialised with
default values when it is created

the data contained is unpredictable
#include <iostream>
#define N 5
using namespace std;
int main( ) {
int num[N];
for (int i= 0; i < N; i++)
cout << num[i] << " ";
cout << endl;
}
-858993460 -858993460 -858993460 -858993460 -858993460
Short-cut initialisation


Like in Java, we can initialise the values in
the array when it is declared:
int num[ 5 ] = { 3, 1, 5, 2, 4 };
if we don't specify the size, the array will be
the same size as the initialising list
int num[ ] = { 3, 1, 5, 2, 4 };

we can declare the array to be larger than the
list
int num[ 10 ] = { 3, 1, 5, 2, 4 };
 the last elements will be initialised to zero
Default initialisation

What does this do?
int myArray[100] = {0};

initialises all 100 elements in the array to 0

why is this useful?
THERE IS NO ARRAY BOUNDS
CHECKING IN C++!!!!!!!!

you can do this
int i;
int num[5 ] = { 3, 1, 5, 2, 4 };
for (i=0; i < 10; i++)
printf("%d ", num[i]);

3 1 5 2 4 -858993460 858993460 7 -858993460
1245112
and this
num[42] = 100;

you will NOT get any compiler or run-time errors




this is NOT good
but it is fast
bounds checking slows run-time performance
but it does prevent potentially disastrous errors
Passing arrays to functions


arrays can be passed to functions
unlike in Java and C#, the array does NOT carry any
information about its size


need to also pass the array size to the function
a function to output an array:
void outputArray(int a[ ], int size) {
for (int i=0; i < size; i++)
cout << a[i] << " ";
}

to call the function:
outputArray(num, 5);
2D (and higher-dimension) arrays

as in Java and C#, C++ arrays can have more than
one dimension
#include <iostream>
using namespace std;
void display(int nums[ ][4], int nRows) {
/* the number of columns in the 2D array must be specified*/
for (int row=0; row< nRows; row++) {
for (int col=0; col< 4; col++)
printf("%5d", nums[row][col]); 8
6
4
printf("\n");
3
15
5
}
12
5
6
}
int main(void) {
int val[3][4] = { 8, 6, 4, 5, 3, 15, 5, 7, 12, 5, 6, 7};
display(val, 3);
}
5
7
7
Structures

In C++, structures are used to group several pieces
of related information together
struct date {
int day;
int month;
int year;
};

This defines a new type date


made up of three integers
Variables of type date can then be declared as
follows.
date jimBirthday;
Using structures

Structure members are accessed using the dot operator:
jimBirthday.day= 10;
jimBirthday.month = 5;
jimBirthday.year = 1960;

Structure variables may be initialised when declared:
date hastings = {23, 10, 1066};

Using structure members:
hastings.day = 24;
 sets the day component of hastings to 24
cin >> hastings.day;
 reads an integer from the keyboard and stores it in the day
component of hastings.
cout << "The year was " << hastings.year << endl;
 outputs The year was 1066
Structures vs. classes

in some ways C++ structures are like classes



they define a way to group together related data
the fields are like the attributes (member variables) of a
Java (or C# or C++) class
however


structure fields are always public
accessor methods are not needed


no encapsulation
once a structure is defined, we can use it many
times

each instance holds its own data
Structures containing structures
Structures can also contain structures.
struct time {
int hours, mins, secs;
};
struct date_time {
date sdate;
time stime;
};
corrected version! 23 Jan
Using structures containing
structures
date_time lunch = {{15, 3, 2012}, {12, 15, 0}};
date_time assignmentDue;
assignmentDue.sdate = jimBirthday;
assignmentDue.stime.hours = 3;
assignmentDue.stime.mins = 30;
assignmentDue.stime.secs = 0;
Structures as function
arguments


A structure can be passed as a function
argument just like any other variable.
by default, it is passed by value




the function creates a new structure of the same
type
and copies each member of the original structure
this is useful if we don't want the function to
change any of the original structure members
but it is time- and space- inefficient

later we will learn how to pass it by value
Passing a structure to a
function
void printDate(date d) {
cout << d.day << " " << d.month << " " << d.year
<< endl;
}
int main() {
date hastings = {23, 10, 1066};
printDate(hastings);
}
23 10 1066
Summary
Today we have






compared how functions are implemented in C++
and Java
compared C++ and Java arrays
introduced structures
Tutorial
Reading:
“C++: A beginners guide” by Herbert Schildt
http://go.microsoft.com/?linkid=8311584
Download