540 likes | 670 Views
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
E N D
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/SolarSystemIP3DA.wmv
WARNING • This module is challenging • But very rewarding • You will learn a lot which is relevant to your chosen subject • And be well qualified for the best placements • 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 • 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=100000000130707 • "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 • BjarneStroustrup, Programming: Principles and Practices Using C++, Addison Wesley 2008http://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/default.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 • Application Program Interface • allows developers to write 2D and 3D graphics programs without having to write hardware-specific code • rendering functionality • main competitor – Direct3D • 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); glVertex2f(-0.75, 0.5); glVertex2f(0.75, 0.5); glVertex2f(0.75, -0.5); glVertex2f(-0.75, -0.5); glEnd(); glFlush(); } int main(intargc, char* argv[]) { glutInit(&argc, argv); glutCreateWindow("Simple OpenGL Program"); glutDisplayFunc(display); glutMainLoop(); }
#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) • by default (0,0) is at the centre of the window • each axis goes from -1 to 1 • regardless of the window dimensions • x increases to the right • y increases going up (-1, -1) (1, -1)
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(intargc, 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/version1.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: typefunction_name (parameter list) { statements; return statement; } • in C++ local variablescan 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; intaddNums(int x, int y) { return x + y; } int main() { inta = 3; intb = 5; intanswer = 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 intaddNums(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 (interr_no) { cout<< "Error " << err_no << " has occurred " << endl; } • calling the function: if (slope < 0) error_mess(5); }
Overloading functions • consider the addNums function intaddNums(int x, int y) { return x + y; } • it takes two integers as parameters • and returns an int • 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 • 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 'intaddNums(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; } intaddNums(double x, double y) { return (int)(x+y+0.5); } // … int answer = addNums(3.2, 5.6); // ???? error C2556: 'intaddNums(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 intaddNums(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 inlinekeyword requests that the compiler replace every call to this function with the code inside the function. • the compiler can ignore this request inline intaddNums(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 • the main method calls functions which have been declared above it • not a problem in Java or C# • 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 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[ ]; orint[ ]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 Please enter 5 integers: 2 4 6 8 10 10 8 6 4 2 #include <iostream> #define N 5 using namespace std; int main( ) { intnum[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( ) { intnum[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]); • 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 3 1 5 2 4 -858993460 -858993460 7 -858993460 1245112
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(intnums[ ][4], intnRows) { /* 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]); printf("\n"); } } int main(void) { intval[3][4] = { 8, 6, 4, 5, 3, 15, 5, 7, 12, 5, 6, 7}; display(val, 3); } 8 6 4 5 3 15 5 7 12 5 6 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; } ; structdate_time{ date sdate; time stime; }; corrected version! 23 Jan