SlideShare une entreprise Scribd logo
1  sur  17
Télécharger pour lire hors ligne
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

Graphics Programming in C++ with G3D
C++ is the most widely used programming language for computer graphics in both
industry and research. It combines low-level features like direct memory manipulation
with high-level features like exceptions, classes, and macros. These make C++ incredibly
powerful and adaptable, but also create pitfalls for new programmers.
G3D is an open source, cross-platform library for creating interactive 3D programs like
games. 3D applications, such as games, medical software, artist tools, and film rendering
software are incredibly complex. Nobody writes them from scratch because it takes about
100,000 lines of infrastructure code before you are even ready to begin the programming
that is specific to your project. There are several large libraries (“engines”) that are
regularly used in research and the software industry to support 3D graphics, including
OGRE, Source, OpenCV, and Unreal. G3D is the one you will use as the primary support
library for your projects in this course. It contains OpenGL, libpng, libjpg, zlib, ffmpeg,
and other popular graphics libraries, and extends them to be both easier to use and more
powerful.
This document is a quick-start guide for programmers with Java experience but little or
no C++ and graphics experience. Some additional resources are:
• G3D Manual, /usr/local/371/html/index.html
• iCompile Manual, /usr/local/371/html/icompile-manual.html
• Lerner, C++ for Java Programmers,
http://www.cs.williams.edu/~lenhart/courses/cs371/c++forjava.html
• Fiamingo, DeBula, and Condron, Introduction to Unix
http://8help.osu.edu/wks/unix_course/intro-1.html
• Kernighan and Ritchie, The C Programming Language
• Stroustrup, The C++ Programming Language

• Neider, Davis, and Woo, OpenGL Programming Guide (also available online at
http://fly.cc.fer.hr/~unreal/theredbook/)

1 Critical Things You Need To Know About C++
1. C++ variables are objects by default. Java variables are pointers. In C++ you
have to explicitly declare a pointer if you want one. Usually you can use a
reference (e.g., Vector3&) or a reference-counted pointer (e.g., TextureRef)
instead to avoid some of the dangers of C++ pointers.

1/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

2. C++ lets you control whether objects are allocated on the stack or the heap. You
have to manually delete objects in the heap when you are done with them, which
is error prone, so try to allocate on the stack whenever possible.
3. C++ has separate static compilation and linking steps. Linker errors usually occur
because you forgot to implement a method (possibly due to misspelling) or
because your .icompile file isn’t configured correctly.
4. Put a semi-colon at the end of class declarations.
5. Object assignment copies the whole object (which might be really slow).
Matrix4 A;
Matrix4 B;
…
Matrix4& C(A);
Matrix4 D = A;
C[0][2] = 1.0f;
D[0][2] = 7.0f;

//
//
//
//

Alias for A
Copy of A
Also changes A
Leaves A (and C) unchanged

6. Stack declarations accept constructor arguments. Use them instead of copying!
// Good
Array<int> a(1024*1024);
// Bad: copies 4 MB of memory!
Array<int> a = Array<int>(1024*1024);

7. Don’t use:
a. C array declaration syntax, e.g., int x[10] (use Array instead)
b. Multiple inheritance
c. Pointer arithmetic
d. Multiple object declaration (e.g., don’t write Vector3 a, b, c; put each on
its own line instead.)
e. C memory management: malloc, calloc, free (use stack allocation or
new)
f. C++ new and delete, if you can avoid them with stack allocation
g. std:: data structures when a G3D:: one is available (use Array, Table, Set,
Queue instead)
h. C strings (char*) except for initialization (use std::string instead)
8. Pass large objects by reference using &:
int computeSum(const Array<int>& array);

9. Never return a reference or a pointer to an object on the stack from a method.
10. Make arguments (especially references) and methods const whenever possible
11. NULL is in all caps. It is equal to 0.
12. The Boolean data type is bool (not Bool, Boolean, BOOL, or anything else). It
requires 4 bytes on most machines.

2/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

13. Primitive types, including int, float, bool, and pointers, are uninitialized when
declared as locals or member variables (they are not zero/NULL like in Java.)
14. onGraphics() runs 30 times per second or more to redraw the screen. Don’t do
anything slow from it, like running a ray tracer or loading a file from disk.
15. Put class declarations only in .h files
16. Put class implementations only in .cpp files
17. Wrap every .h file in a header guard. E.g., for Foo.h:
#ifndef Foo_h
#define Foo_h
…
#endif Foo_h

2 Compiling Code
Programs written in any language pass through two steps before they are run. The first
step is compilation, which checks syntax and types and then produces an object file (in
Java, these end in .class; in C++ they end in .o or .obj). The second step is linking, which
connects all of the object files into a single program. In Java, the linking step happens at
run time and is not explicitly seen by the programmer. In C++, the linking step is
performed in two parts: explicitly after compilation (“static linking”) and at run time
(“dynamic linking). Knowing how to invoke the compiler and linker is a valuable skill. It
is also one that takes some time to acquire. To help you get started quickly, I’ve provided
a program called “iCompile” that will automatically compile and link your programs. It
will also provide some additional functions if you request them, like copying data files
from your source directory to your build directory and creating documentation for your
code.
To learn more about compiling and linking you can run iCompile with the “—verbosity
3” argument. All of the green text that it prints contains the actual commands being
issued to the compiler. You can use “man gcc” to see a description of those commands.

3 Debugging
The GNU debugger, gdb, is a command-line program that you can use to pause a running
program, look at its variables, and see a stack trace. You can run your program under
gdb by specifying the “—gdb” flag instead of the “—run” flag to iCompile. Compared to
a visual debugger, gdb is unfortunately hard to use and many programmers use simple
print statements and clever rendering tricks to try and diagnose problems in their
programs. There are some situations that are impractical to debug by those methods,
however, and in those situations gdb is essential. The most common of these is when an
assertion failure occurs and you need a call stack to locate the source of the problem in
your program (the assertion failure typically contains a line number inside a library).
When this happens, select “(3) Debug” from the G3D assertion prompt, which will leave
you at the gdb prompt. Type “bt” to see a backtrace (call stack), which will identify the
line of your code that triggered the failure. Type “help” in gdb to learn more about other
commands, e.g., for looking at local variables.

3/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

G3D creates a log.txt file every time your program is run. This contains information that
is useful in debugging, including the last assertion message and a list of all files that your
program accessed.
G3D provides several routines to aid in debugging your programs. The names of these
routines all begin with “debug”.
The debugPrintf function is like printf except that it disappears when you make an
optimized build of your program and works in a useful way on all operating systems.
The debugBreak macro pauses execution. It is a way of programmatically setting a
breakpoint for the debugger.
The debugAssert and debugAssertM macros execute a debugBreak if the specified
condition is not true. A command-line prompt then allows you to see more information
about the error and choose how you would like to continue. Sometimes you want an
assertion to remain in an optimized build. Use alwaysAssertM in that case.
Three routines output debugging text. screenPrintf displays information directly on your
3D window. It is most useful for debugging interactive programs that continuously
rendering. debugPrintf prints to the xterm that created your program. logPrintf prints to
the log.txt file, which is useful if your program is crashing in a way that takes out the
xterm (or the computer).
Later in the semester when using OpenGL in more advanced ways, the getOpenGLState
function allows you to see the current values of the OpenGL registers.
G3D makes it really easy to create GUI controls to adjust parameters in your program,
which can be very helpful for debugging. Commands like:
debugPane->addCheckBox(“Visible”, &visible);
let you map variables from your program directly to controls on the screen so that you
can try many variations without recompiling your program.

4/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

4 C++ Declarations
4.1

C++ Syntax

public class A : public B {
private:
float
x;
public:
A();
~A();
void foo();
};

4.2

A is a subclass of B
The following declarations are all private
members & methods.
The following declarations are all public
members & methods.
Destructor, the opposite of a constructor.
This runs when an instance is deallocated.
Note the semi-colon

Declarations

The class is split across two files. The declaration is in a header (.h) file. This contains all
of the information needed to tell the compiler how big the class is, what methods it has,
and what members it has. The implementation is in a .cpp file; this is what tells the
compiler what the methods do. The #include statement effectively pastes one file into
another. Classes must be declared before they are used in C++. This is why we have
header files—they enable us to paste the declaration before any use of the class, even if
the implementations of two classes depend on each other.
When the declarations of two classes depend on each other, C++ uses a forward
declaration:
// forward declaration
class B;
class A {
public:
void add(B& b);
};
class B {
public:
void add(A& a);
};

Compilers need to know how big objects are. Since all pointers are the same size, the
compiler knows how big B* and B& are (and the special case of a B as a return value),
even if they don’t know how big an instance of B is. The reason for the forward
declaration is to assure the compiler that you didn’t type “B” by accident. The forward
declaration how you promise the compiler that a declaration of B will show up at some
point in the future (if one doesn’t, then the linker will complain).

4.3

Functions

C++ allows the definition of functions, which are like static methods without an
associated class. You probably won’t have to declare many of your own functions, but

5/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

you likely will have to call functions written by others. For example, endsWith is a
function in the following code snippet:
if (! endsWith(filename, “/”)) {
filename += “/”;
}

5 Constants
The order of initialization of global constants is undefined in C++. For example, this
means that the following code could produce ANY value for the perimeter of the unit
circle, because PI might be initialized after unit.
const float PI = 3.1415926;
class Circle {
public:
float perimenter;
Circle(float radius);
};
Circle::Circle(float radius) : perimeter(PI * 2.0f * radius) {
}
Circle unit(1.0f);

There are several tricks to avoid being caught by this behavior. For integer constants, the
enum type is always created at compile time. So integer constants can be expressed using
(the admittedly awkward syntax):
enum {DAYS_IN_WEEK = 7};

Macros can be used for any kind of constant:
#define PI (3.1415926)
#define DAYS_IN_WEEK (7)

For class constants, it is necessary to create an inline function that returns a static const
variable. This can also be used for other data types:
inline const Matrix3& rot45() {
static const Matrix3 M =
Matrix3::fromAxisAngle(Vector3::unitX(),
toRadians(45));
return M;
}

That example uses a number of C++ features too complicated to explain here, but is a
pattern that you can follow for creating constants and static class member constants that
are guaranteed to be valid at the global level. Constants inside methods and functions do
not require such care and can be defined as if they were variables.

6/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

6 Inheritance
Inheritance in C++ is tricky. In general, never use multiple inheritance—it is especially
confusing and can produce code that compiles but does something other than what you
expected.
In Java, every class can be subclassed and every method overridden unless explicitly
marked with “final”. C++ has the opposite convention. Unless a method is explicitly
marked as “virtual”, it cannot be overridden (well, it can be overridden, but the result
won’t be what you wanted.)
In addition, unless a class has a destructor that is declared as virtual, it may also leak
memory when instances are destroyed. The G3D classes that you need to subclass are
declared with virtual destructors and appropriate methods (e.g., event handlers) declared
virtual. The G3D classes that you don’t need to but might like to subclass (e.g., Vector3)
are not declared virtual and your program will be in error if you try to inherit from them.
A pure virtual method is one that is not implemented by the base class (Java calls this
“abstract”). Pure virtual methods declarations have “=0” at the end, like:
virtual void intersect(const Ray& worldRay,
float& hitDistance, class Hit& hitResult) = 0;

See http://blogs.msdn.com/oldnewthing/archive/2004/05/07/127826.aspx for a discussion
of inheritance.

7 Factory Methods
C++ provides overloaded constructors so that a class may be instantiated in multiple
ways. Sometimes the constructors would be confusing if they were distinguished only by
overloading. In theses cases it is common practice to provide a static method on the class
that produces the desired instance. These so-called “factory” methods are also used for
alternative memory allocation schemes like buffer pooling. Here are examples of using
factory methods:
Vector3
Matrix3

up = Vector3::unitY();
rot = Matrix3::fromAxisAngle(Vector3::unitX(),
toRadians(15);

8 Manual Memory Management
Unlike Java, in C and C++ programmers must both allocate (using “new” or “malloc”)
memory for objects and deallocate that memory (using “delete” or “free”) when the
object is no longer in use. Forgetting to deallocate memory leads to memory leaks,
which will eventually make a program run slowly and crash. Deallocating memory that
is still in use creates a “dangling” pointer and will likely cause a program to crash. As
you can imagine, this manual memory management is one of the trickiest parts of C++
programming and is the source many errors.
Fortunately, G3D helps you avoid ever having to manually manage memory. You should
almost never have to write “new” or “delete” in your program, in fact. Two tools that
G3D provides are common data structures and reference counting.
7/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

9 Data Structures
The G3D Array, Queue, Set, and Table data structures are all dynamic. This means that
you just declare variables of these types, for example,
Array<int>

myIntegerArray;

and G3D will handle allocating and deallocating the underlying memory that is used to
represent the data structure. C++ also provides a standard library with arrays and queues,
and the C language provides built-in arrays (like Java’s built-in arrays). You should
generally not use those in this class. The G3D versions are better optimized for graphics,
are more platform independent, and are easier to use.
For string processing, use the built-in std::string class. This can be initialized from a Cstring (char*), but is a class with useful methods. To convert std::string to C-string, use
the std::string::c_str method. An example of using std::string is:
std::string name = “McGuire”;
debugPrintf(“Length: %dn”, name.size());
debugPrintf(“Value: ”%s”n”), name.c_str();
if (name == “Murtagh”) {
debugPrintf(“username = tomn”);
} else {
name += “ – Username Unknown!”);
}

Note that words in quotes are not strings; they are values that can become strings. So
“hello” + “ there” does not concatenate strings, but std::string(“hello”) + std::string(“
there”) does.

10 Reference Counting
Reference counting is a form of automatic memory management (also known as garbage
collection). Most G3D classes, like Texture, GFont, and Shader, are managed with
reference counting. For these classes, declare your instance to be the corresponding “ref”
type (“ref” means reference, another word for pointer). Use the appropriate factory
method to create an instance of this class. For example:
TextureRef tex = Texture::fromFile(“apple.jpg”);

The ref classes act like regular C++ pointers in almost every way. They can be shared
(aliased), set to NULL, and tested for equality. Use the -> or * syntax to dereference a
pointer. Testing for NULL has a special syntax. Examples:

8/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

int sumWidth(TextureRef tex1, TextureRef tex2) {
if (tex1.notNull()) {
if (tex1 == tex2) {
return 2 * tex1->texelWidth();
} else {
return tex1->texelWidth() +
tex2->texelWidth();
}
} else {
return 0;
}
}

Never use C++ pointer syntax with these reference counted classes, e.g. DO NOT write
Texture*. Never call delete or new with a ref class. You can make your own reference
counted classes; see the G3D documentation for more information.

11 Variable Initialization
C++ does not initialize variables unless they are of a class with a default constructor. This
means that most member variables and stack variables have undefined values. You
should always initialize these immediately after declaring them or in your constructor.
When writing your own class constructors, a special syntax allows you to initialize
members before the constructor executes (this is equivalent to Java’s member assignment
during definition). The syntax is a colon after the constructor signature followed by a
comma-separated list of members, each with its own constructor arguments in
parentheses:
class Player {
public:
Vector2
position;
std::string name;
Player();
};
Player::Player() : position(10, 2), name(“Harvey”) {
}

12 Pass By Reference
In C++, a type written without a “*” declares a variable to be the actual object, not a
pointer to the object as is the case in Java. Since you have been instructed not to use
pointers in most cases, this means that almost all of your variables will be stack allocated
objects or members defined inside another object.
When assigning one object to another, a copy occurs. For a large object like GImage or
an Array, this is potentially slow and is probably not desirable. This means that you will
usually want to pass values into methods and functions by reference to avoid the copy. In
C++, an ampersand (&) placed after a type makes it into a reference type that acts like a
pointer but cannot be reassigned. Passing an object to a reference incurs no copy.
For example, the following code passes a GImage by reference. Note the use of the const
keyword to specify that the function cannot change.

9/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

int findRedPixelX(const GImage& image, int y) {
for (int x = 0; x < image.width; ++x) {
if (image.pixel3(x, y).r == 0) {
return x;
}
}
return -1;
}
…
GImage image(“logo.gif”);
int x = findRedPixelX(im, 0);

Note that the int was not passed as a reference in this example. That is because small
data types like int are the same size as a pointer, so there’s no performance advantage to
passing them by reference. It is possible to pass a reference to an int, and in fact that is a
convenient way of returning more than one value from a method. The following example
demonstrates two values returned by passing them by reference.
void findRedPixel(const GImage& image, int& x, int& y) {
x = -1;
y = -1;
for (y = 0; y < image.height; ++y) {
for (x = 0; x < image.width; ++x) {
if (image.pixel3(x, y).r == 0) {
return;
}
}
}
}
…
GImage image(“logo.gif”);
int x;
int y;
findRedPixel(im, x, y);

13 OpenGL Register Model
OpenGL is the platform independent library that allows access to graphics cards. It
presents a virtual interface to the card called a Hardware Abstraction Layer (HAL). This
abstraction layer refers to registers and other low-level hardware features. Graphics cards
are generally operated by setting state (values in the registers) and then executing a
function that uses that state.
G3D follows this model. The RenderDevice class contains many “set” methods that
assign values to OpenGL registers. Only two methods trigger actual rendering. These are
RenderDevice::sendVertex and RenderDevice::sendIndices. Because graphics cards are
designed as pipelines, “sending” a value means sending it down the pipeline to
processing.
Most bugs in OpenGL programs are from having the wrong state set when sending data.
RenderDevice::push and RenderDevice::pop allow you to easily save and restore all of
the state in the rendering system, which can be used to isolate one piece of code from
another and reduce the number of state-based errors.

10/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

14 Color Model
To a graphics card, 0 is the darkest value that can be displayed and 1 is the brightest.
These values between 0 and 1 are often rescaled and stored in bytes as values between 0
and 255. A color is represented by a triplet of red, green, and blue intensities (always
written in that order). It can also be written as the hexadecimal representation of the
bytes in such a triple, e.g. 0xFF8800 is redish yellow because it contains bright red, dim
green, and no blue. The Color3 and Color3uint8 classes represent colors in G3D.
In addition to red, green, and blue, an “alpha” channel is used to represent translucency
and partial occlusion in many situations. An alpha value of 0 generally means
completely translucent and a value of 1 represents completely opaque. Color4 and
Color4uint8 extend Color3 with an alpha value. The alpha value is represented as the
high-order bits when writing in hex: 0xFF000000 is opaque black.

15 2D Coordinate System
For historical reasons, in 2D (0, 0) is the upper-left corner of an image or the screen. The
x-axis increases to the right and the y-axis increases down. This is used for
RenderDevice push2D rendering, Texture coordinates, and for GImage pixel addressing.
Texture coordinates vary from (0, 0) in the upper-left to (1, 1) in the lower right, while
RenderDevice push2D, Image, and GImage use integer pixel coordinates.

16 Immediate vs. Retained Mode Graphics
In a retained mode graphics API, you create objects and they persist until destroyed,
drawing themselves on screen and interacting with the user. An example is the Swing
JComponent API in Java, where you create objects like JButton and JTextArea that then
appear on screen until dismissed.
In an immediate mode graphics API, you explicitly draw on a canvas that is periodically
erased. There are no persistent objects; if the canvas is erased by your code or by another
window drawing over it, your image will be lost forever and must be redrawn from
scratch. An example of this is the Swing Graphics2D API used in the Component.paint
methods.
G3D provides pieces for writing retained mode code, but it is intended primarily for
immediate mode rendering. In GApplet, the onGraphics event handler that you
implement will be invoked several times a second. It will use calls on a RenderDevice to
create an image that lasts only until the next frame of animation.

17 Starting Your Program
iCompile will automatically copy the contents of the data-files directory into the build
directory, change into the build directory, and then launch your program. At that point,
the main() function begins. Main must have the following syntax:
int main(int argc, char** argv) {
…
return …;
}

11/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

Integer argc is the number of command line arguments that were passed to your program
as strings. There is always at least one, which is the name of your program. Variable argv
is a pointer to a pointer to a character. In C (not C++) syntax, it can also be viewed as an
array of arrays, or an array of strings. That’s because a C array is just a pointer to the first
element in the array. C doesn’t keep track of how many elements are in an array for
you…if you go off the end, you simply start corrupting memory and the program crashes!
That’s why argc is provided. A string in C (as opposed to a C++ std::string) is just an
array of characters. The last character is ‘0’ (this is a “null-terminated” string), which is
how you know when the string has ended.
An example of simple command line argument processing is:
int main(int argc, char** argv) {
if ((argc > 1) && (std::string(“hello”) == argv[1])) {
…
}
return …;
}

Here, constructing a C++ std::string lets us use the == operator to tell if the two strings
are identical. If we just said “hello” == argv[1], then we’d be testing if the memory
pointer to “hello” was the same as the memory pointer argv[1], not asking if they
contained equivalent strings. If you’ve programmed in Java, then you might recall the
difference between String.equals and ==; in C++, that’s the difference between
std::string::operator== and C-string == on pointers.

18 C++ Syntax Reference
18.1 Pointers and References
Object:
Vector3 v;

Reference: this acts like an object but re-uses the memory allocated for v and can never
be assigned to different memory.
Vector3& r(v);

Pointer: this stores the address of the memory for v. It can be reassigned to a different
address (or to NULL).
Vector3* p(&v);

12/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

Reference counted pointer: this acts like a pointer, but garbage collects the object when it
is no longer used. These are only available for some objects:
TextureRef tex = Texture::fromFile(“hello.jpg”);

Assign to a member:
v.x = 1.0f;
r.x = 3.0f;
p->x = 7.0f;
*p.x = 8.0f;
tex->invertY = true;
*tex.invertY = false;

Read a member/invoke a method
float f;
f = v.y;
v.unitize();
f = r.y;
f = p->y;
f = *p.y;
f = tex->width();
f = *tex.width();

Copy the value:
v = *p;
*p = v;
r = v;
v = r;
*p = r;

Point at the same value:
p = &r;
p = &v;
Vector3*
Vector3*
Vector3&
Vector3&
q = p;

q(p);
s(&r);
z(*p);
c(r);

18.2 Allocation
Allocate on the stack (will automatically be deallocated when it goes out of scope):
Vector3 v(5, 2, -15);

13/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

Allocate a C++ array on the stack (will automatically be deallocated when it goes out of
scope), where the contents of the array are in the heap:
Array<Vector3> v(10);
std::vector<Vector3> x(10);

// G3D; recommended
// std; not recommended for 371

Allocate a C array on the stack, where the contents of the array are also on the stack
(generally undesirable):
Vector3 v[10];

Allocate a reference-counted object on the heap (will automatically be deallocated when
the last pointer is dropped, just like in Java):
Image3Ref im = Image3::createEmpty(100, 100);

Allocate a non-reference counted object on the heap (avoid this whenever possible, since
you must explicitly deallocate it or memory will leak!):
MyObject* obj = new MyObject();
…
delete obj;
obj = NULL;

18.3 static
Declare that a method is on a class, not a member (same as in Java):
class Ball {
public:
static BallRef create(const std::string& name);
};

In the .cpp file for the above example, do not put “static” in front of the implementation:
BallRef Ball::create(const std::string& name) {
return new Ball();
}

Declare that a member variable belongs to a class, not a member (same as in Java):
class Cube {
public:
static int numCubes;
};

In the .cpp file for the above example, numCubes is initialized as:
int Cube::numCubes = 0;

14/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

Declare that a variable should only be initialized the first time a method is invoked, and
its value remembered after that (rarely a good idea for non-const variables):
void MyClass::sketchy() {
static int x = 0;
…
}

Declare that a function or variable should not be visible outside a .cpp file (rarely used):
static int helper(int y, int z) {
Return y + 2 * z;
}

18.4 const
Declare that a method never mutates a value:
void safeMethod(const std::string& x);

Declare that a method never mutates any member variable:
void alsoSafe(int y) const;

Declare that a member variable is never changed after initialization:
class Clown {
public:
const Color3 hair;
Clown();
};

Create a mutable pointer to an immutable int, i.e., “don’t change the value x is pointing
at”:
const int* x;
int const* x;

Create an immutable pointer to a mutable int, i.e., “don’t reassign the pointer”/ “don’t
change x”:
int* const x;

15/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

18.5 Iterator
Set<int> keep;
…
Set<int>::Iterator it = keep.begin();
Set<int>::Iterator end = keep.end();
while (it != end) {
…
++it;
}

18.6 Function Pointers
You don’t need to use function pointers very often, but if you do, the syntax is odd and
you’ll want to check back here.
Pass a non-static method pointer as an argument:
debugPane->addButton(“Exit”, &App::exit);

Declare a function pointer/static method pointer (e.g., to atan2):
double(*atan2Ptr)(double, double);

Create a typedef for a function pointer type:
typedef double(*)(double, double) ATan2Type;

Pass a function pointer as an argument or use as a value:
passPointer( &atan2 );
ATan2Type atan2Ptr = &atan2;

Call a function using its pointer (two syntaxes available):
atan2Ptr(x, y);
(*atan2Ptr)(x, y);

18.7 printf
G3D provides three ways of printing text: logPrintf(), debugPrintf(), and screenPrintf().
You can also print to a std::string with format(). Type “man printf” to see a full
specification for these. The common idioms you’ll use are:

16/17
CS371 Fall 2008
Prof. McGuire

Williams College
Department of Computer Science

std::string s;
int i;
float f;
…
debugPrintf(“The int’s value is %dn”, i);
debugPrintf(“A string %s and a float %fn”, s.c_str(), f);

19 Coding Conventions
We’re going to be looking at a lot of each other’s code between group projects, sample
code, and helping each other debug. To make it easy to understand code written by others
and to cut and paste between projects, please follow the following coding conventions. In
some cases you may find that the conventions are making it harder to read your code.
When that occurs, write in the way that is easiest for another person to read even if it
breaks with convention.
• Follow Java coding conventions wherever they apply to C++
• Make header guards case-sensitive, e.g., #ifndef Film_h
• Prefix private and protected member variables with m_, e.g., m_photonMap
• Indent member variables and method arguments in columns, e.g.,
int
m_numPhotons;
std::string
m_filename;
• Put a space before the open parent of FOR, WHILE, and IF, e.g., if (! b)
• Put the open-brace on the same line as FOR, WHILE, IF, TRY, etc.
• Always uses braces, even for single-line FOR, WHILE, etc.
• Use four-space indenting and no tabs
• Put comments before the code to which they apply
• Keep lines to about 80 characters (for printing)
• Fully-parenthesize logical expressions, e.g., (x || y) && (z > 2)
• When writing pointers, the * goes with the class name, e.g., RenderDevice* rd;

17/17

Contenu connexe

Tendances

Heading for a Record: Chromium, the 5th Check
Heading for a Record: Chromium, the 5th CheckHeading for a Record: Chromium, the 5th Check
Heading for a Record: Chromium, the 5th CheckPVS-Studio
 
Impact of Tool Support in Patch Construction
Impact of Tool Support in Patch ConstructionImpact of Tool Support in Patch Construction
Impact of Tool Support in Patch ConstructionDongsun Kim
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project AnalyzedPVS-Studio
 
Checking the Qt 5 Framework
Checking the Qt 5 FrameworkChecking the Qt 5 Framework
Checking the Qt 5 FrameworkAndrey Karpov
 
Introduction to OpenCV 3.x (with Java)
Introduction to OpenCV 3.x (with Java)Introduction to OpenCV 3.x (with Java)
Introduction to OpenCV 3.x (with Java)Luigi De Russis
 
An Introduction to PC-Lint
An Introduction to PC-LintAn Introduction to PC-Lint
An Introduction to PC-LintRalf Holly
 
Anaconda Python KNIME & Orange Installation
Anaconda Python KNIME & Orange InstallationAnaconda Python KNIME & Orange Installation
Anaconda Python KNIME & Orange InstallationGirinath Pillai
 
Installation of PC-Lint and its using in Visual Studio 2005
Installation of PC-Lint and its using in Visual Studio 2005Installation of PC-Lint and its using in Visual Studio 2005
Installation of PC-Lint and its using in Visual Studio 2005PVS-Studio
 
TBar: Revisiting Template-based Automated Program Repair
TBar: Revisiting Template-based Automated Program RepairTBar: Revisiting Template-based Automated Program Repair
TBar: Revisiting Template-based Automated Program RepairDongsun Kim
 
Whats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ DevelopersWhats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ DevelopersRainer Stropek
 
C++ Interface Versioning
C++ Interface VersioningC++ Interface Versioning
C++ Interface VersioningSkills Matter
 
How to avoid bugs using modern C++
How to avoid bugs using modern C++How to avoid bugs using modern C++
How to avoid bugs using modern C++PVS-Studio
 
Java - Generic programming
Java - Generic programmingJava - Generic programming
Java - Generic programmingRiccardo Cardin
 
An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...
An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...
An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...Kamiya Toshihiro
 
Mining Fix Patterns for FindBugs Violations
Mining Fix Patterns for FindBugs ViolationsMining Fix Patterns for FindBugs Violations
Mining Fix Patterns for FindBugs ViolationsDongsun Kim
 
Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33Max Kleiner
 
Porting is a Delicate Matter: Checking Far Manager under Linux
Porting is a Delicate Matter: Checking Far Manager under LinuxPorting is a Delicate Matter: Checking Far Manager under Linux
Porting is a Delicate Matter: Checking Far Manager under LinuxPVS-Studio
 

Tendances (20)

Heading for a Record: Chromium, the 5th Check
Heading for a Record: Chromium, the 5th CheckHeading for a Record: Chromium, the 5th Check
Heading for a Record: Chromium, the 5th Check
 
Impact of Tool Support in Patch Construction
Impact of Tool Support in Patch ConstructionImpact of Tool Support in Patch Construction
Impact of Tool Support in Patch Construction
 
L6
L6L6
L6
 
C tutorials
C tutorialsC tutorials
C tutorials
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project Analyzed
 
Checking the Qt 5 Framework
Checking the Qt 5 FrameworkChecking the Qt 5 Framework
Checking the Qt 5 Framework
 
Introduction to OpenCV 3.x (with Java)
Introduction to OpenCV 3.x (with Java)Introduction to OpenCV 3.x (with Java)
Introduction to OpenCV 3.x (with Java)
 
An Introduction to PC-Lint
An Introduction to PC-LintAn Introduction to PC-Lint
An Introduction to PC-Lint
 
Anaconda Python KNIME & Orange Installation
Anaconda Python KNIME & Orange InstallationAnaconda Python KNIME & Orange Installation
Anaconda Python KNIME & Orange Installation
 
Installation of PC-Lint and its using in Visual Studio 2005
Installation of PC-Lint and its using in Visual Studio 2005Installation of PC-Lint and its using in Visual Studio 2005
Installation of PC-Lint and its using in Visual Studio 2005
 
TBar: Revisiting Template-based Automated Program Repair
TBar: Revisiting Template-based Automated Program RepairTBar: Revisiting Template-based Automated Program Repair
TBar: Revisiting Template-based Automated Program Repair
 
Whats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ DevelopersWhats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ Developers
 
Java lab 2
Java lab 2Java lab 2
Java lab 2
 
C++ Interface Versioning
C++ Interface VersioningC++ Interface Versioning
C++ Interface Versioning
 
How to avoid bugs using modern C++
How to avoid bugs using modern C++How to avoid bugs using modern C++
How to avoid bugs using modern C++
 
Java - Generic programming
Java - Generic programmingJava - Generic programming
Java - Generic programming
 
An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...
An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...
An Execution-Semantic and Content-and-Context-Based Code-Clone Detection and ...
 
Mining Fix Patterns for FindBugs Violations
Mining Fix Patterns for FindBugs ViolationsMining Fix Patterns for FindBugs Violations
Mining Fix Patterns for FindBugs Violations
 
Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33
 
Porting is a Delicate Matter: Checking Far Manager under Linux
Porting is a Delicate Matter: Checking Far Manager under LinuxPorting is a Delicate Matter: Checking Far Manager under Linux
Porting is a Delicate Matter: Checking Far Manager under Linux
 

En vedette

Interes
InteresInteres
Interesma-102
 
Tema de interes
Tema de interesTema de interes
Tema de interesma-102
 
#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015
#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015
#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015Laura Rojas
 
Reference Letter Sard Verbinnen
Reference Letter Sard VerbinnenReference Letter Sard Verbinnen
Reference Letter Sard VerbinnenGuillaume Troesch
 
La evolución de la web
La evolución de la webLa evolución de la web
La evolución de la webVane Haro
 
Ciclo de vida de un sotware
Ciclo de vida de un sotwareCiclo de vida de un sotware
Ciclo de vida de un sotwareEmerson Pilco
 
(1) laboratorio de computo lll jesus hector martinez corral
(1) laboratorio de computo lll jesus hector martinez corral(1) laboratorio de computo lll jesus hector martinez corral
(1) laboratorio de computo lll jesus hector martinez corralJesusMartinez1710
 
1°, 2º, 3º expansión y contracción
1°, 2º, 3º expansión y contracción1°, 2º, 3º expansión y contracción
1°, 2º, 3º expansión y contracciónInessita19
 
CommunicationAudit_Revised 11_19
CommunicationAudit_Revised 11_19CommunicationAudit_Revised 11_19
CommunicationAudit_Revised 11_19Sarah King
 
Modelos administrativos
Modelos administrativosModelos administrativos
Modelos administrativosmaryalexandra
 

En vedette (20)

Interes
InteresInteres
Interes
 
Tema de interes
Tema de interesTema de interes
Tema de interes
 
Mi barrio
Mi barrioMi barrio
Mi barrio
 
arte románico
 arte románico arte románico
arte románico
 
merged
mergedmerged
merged
 
Basant
BasantBasant
Basant
 
#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015
#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015
#Entérate de mis actividades legislativas realizadas en el mes de marzo 2015
 
Resume
ResumeResume
Resume
 
Reference Letter Sard Verbinnen
Reference Letter Sard VerbinnenReference Letter Sard Verbinnen
Reference Letter Sard Verbinnen
 
Ryan
RyanRyan
Ryan
 
La evolución de la web
La evolución de la webLa evolución de la web
La evolución de la web
 
Ciclo de vida de un sotware
Ciclo de vida de un sotwareCiclo de vida de un sotware
Ciclo de vida de un sotware
 
(1) laboratorio de computo lll jesus hector martinez corral
(1) laboratorio de computo lll jesus hector martinez corral(1) laboratorio de computo lll jesus hector martinez corral
(1) laboratorio de computo lll jesus hector martinez corral
 
Diário Oficial de Guarujá
Diário Oficial de GuarujáDiário Oficial de Guarujá
Diário Oficial de Guarujá
 
1°, 2º, 3º expansión y contracción
1°, 2º, 3º expansión y contracción1°, 2º, 3º expansión y contracción
1°, 2º, 3º expansión y contracción
 
Apj Abdul Kalam
Apj Abdul KalamApj Abdul Kalam
Apj Abdul Kalam
 
CommunicationAudit_Revised 11_19
CommunicationAudit_Revised 11_19CommunicationAudit_Revised 11_19
CommunicationAudit_Revised 11_19
 
Modelos administrativos
Modelos administrativosModelos administrativos
Modelos administrativos
 
Letter pad
Letter padLetter pad
Letter pad
 
StrengthsFinder Insight Report
StrengthsFinder Insight ReportStrengthsFinder Insight Report
StrengthsFinder Insight Report
 

Similaire à Graphics Programming in C++ with G3D Library

Introduction-to-C-Part-1 (1).doc
Introduction-to-C-Part-1 (1).docIntroduction-to-C-Part-1 (1).doc
Introduction-to-C-Part-1 (1).docMayurWagh46
 
Legacy of Void*
Legacy of Void*Legacy of Void*
Legacy of Void*Adam Crain
 
Introduction-to-C-Part-1.pptx
Introduction-to-C-Part-1.pptxIntroduction-to-C-Part-1.pptx
Introduction-to-C-Part-1.pptxNEHARAJPUT239591
 
Introduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJ
Introduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJIntroduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJ
Introduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJmeharikiros2
 
C++ helps you to format the I/O operations like determining the number of dig...
C++ helps you to format the I/O operations like determining the number of dig...C++ helps you to format the I/O operations like determining the number of dig...
C++ helps you to format the I/O operations like determining the number of dig...bhargavi804095
 
Introduction-to-C-Part-1.pdf
Introduction-to-C-Part-1.pdfIntroduction-to-C-Part-1.pdf
Introduction-to-C-Part-1.pdfAnassElHousni
 
Not Your Fathers C - C Application Development In 2016
Not Your Fathers C - C Application Development In 2016Not Your Fathers C - C Application Development In 2016
Not Your Fathers C - C Application Development In 2016maiktoepfer
 
Unit 1 of c++ part 1 basic introduction
Unit 1 of c++ part 1 basic introductionUnit 1 of c++ part 1 basic introduction
Unit 1 of c++ part 1 basic introductionAKR Education
 
Data structure week 1
Data structure week 1Data structure week 1
Data structure week 1karmuhtam
 
Production Debugging at Code Camp Philly
Production Debugging at Code Camp PhillyProduction Debugging at Code Camp Philly
Production Debugging at Code Camp PhillyBrian Lyttle
 
C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1ReKruiTIn.com
 
Building of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code loggingBuilding of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code loggingPVS-Studio
 
Debugging Python with gdb
Debugging Python with gdbDebugging Python with gdb
Debugging Python with gdbRoman Podoliaka
 
Two C++ Tools: Compiler Explorer and Cpp Insights
Two C++ Tools: Compiler Explorer and Cpp InsightsTwo C++ Tools: Compiler Explorer and Cpp Insights
Two C++ Tools: Compiler Explorer and Cpp InsightsAlison Chaiken
 

Similaire à Graphics Programming in C++ with G3D Library (20)

C++Basics2022.pptx
C++Basics2022.pptxC++Basics2022.pptx
C++Basics2022.pptx
 
Introduction-to-C-Part-1 (1).doc
Introduction-to-C-Part-1 (1).docIntroduction-to-C-Part-1 (1).doc
Introduction-to-C-Part-1 (1).doc
 
Legacy of Void*
Legacy of Void*Legacy of Void*
Legacy of Void*
 
Introduction-to-C-Part-1.pptx
Introduction-to-C-Part-1.pptxIntroduction-to-C-Part-1.pptx
Introduction-to-C-Part-1.pptx
 
Introduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJ
Introduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJIntroduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJ
Introduction-to-C-Part-1 JSAHSHAHSJAHSJAHSJHASJ
 
C++ helps you to format the I/O operations like determining the number of dig...
C++ helps you to format the I/O operations like determining the number of dig...C++ helps you to format the I/O operations like determining the number of dig...
C++ helps you to format the I/O operations like determining the number of dig...
 
CS267_Graph_Lab
CS267_Graph_LabCS267_Graph_Lab
CS267_Graph_Lab
 
Introduction-to-C-Part-1.pdf
Introduction-to-C-Part-1.pdfIntroduction-to-C-Part-1.pdf
Introduction-to-C-Part-1.pdf
 
Not Your Fathers C - C Application Development In 2016
Not Your Fathers C - C Application Development In 2016Not Your Fathers C - C Application Development In 2016
Not Your Fathers C - C Application Development In 2016
 
Unit 1 of c++ part 1 basic introduction
Unit 1 of c++ part 1 basic introductionUnit 1 of c++ part 1 basic introduction
Unit 1 of c++ part 1 basic introduction
 
Data structure week 1
Data structure week 1Data structure week 1
Data structure week 1
 
The basics of c programming
The basics of c programmingThe basics of c programming
The basics of c programming
 
Production Debugging at Code Camp Philly
Production Debugging at Code Camp PhillyProduction Debugging at Code Camp Philly
Production Debugging at Code Camp Philly
 
C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1
 
Bcsl 031 solve assignment
Bcsl 031 solve assignmentBcsl 031 solve assignment
Bcsl 031 solve assignment
 
Switch case and looping
Switch case and loopingSwitch case and looping
Switch case and looping
 
c.ppt
c.pptc.ppt
c.ppt
 
Building of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code loggingBuilding of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code logging
 
Debugging Python with gdb
Debugging Python with gdbDebugging Python with gdb
Debugging Python with gdb
 
Two C++ Tools: Compiler Explorer and Cpp Insights
Two C++ Tools: Compiler Explorer and Cpp InsightsTwo C++ Tools: Compiler Explorer and Cpp Insights
Two C++ Tools: Compiler Explorer and Cpp Insights
 

Dernier

Karra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptxKarra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptxAshokKarra1
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxHumphrey A Beña
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designMIPLM
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Celine George
 
4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptxmary850239
 
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfAMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfphamnguyenenglishnb
 
Science 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptxScience 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptxMaryGraceBautista27
 
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxiammrhaywood
 
ACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdfACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdfSpandanaRallapalli
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatYousafMalik24
 
Computed Fields and api Depends in the Odoo 17
Computed Fields and api Depends in the Odoo 17Computed Fields and api Depends in the Odoo 17
Computed Fields and api Depends in the Odoo 17Celine George
 
Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxthorishapillay1
 
Q4 English4 Week3 PPT Melcnmg-based.pptx
Q4 English4 Week3 PPT Melcnmg-based.pptxQ4 English4 Week3 PPT Melcnmg-based.pptx
Q4 English4 Week3 PPT Melcnmg-based.pptxnelietumpap1
 
Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptxSherlyMaeNeri
 
ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4MiaBumagat1
 
Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Jisc
 

Dernier (20)

Karra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptxKarra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptx
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-design
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17
 
4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx
 
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfAMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
 
Science 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptxScience 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptx
 
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
 
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptxYOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
 
ACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdfACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdf
 
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice great
 
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdfTataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
 
Computed Fields and api Depends in the Odoo 17
Computed Fields and api Depends in the Odoo 17Computed Fields and api Depends in the Odoo 17
Computed Fields and api Depends in the Odoo 17
 
Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptx
 
Q4 English4 Week3 PPT Melcnmg-based.pptx
Q4 English4 Week3 PPT Melcnmg-based.pptxQ4 English4 Week3 PPT Melcnmg-based.pptx
Q4 English4 Week3 PPT Melcnmg-based.pptx
 
Raw materials used in Herbal Cosmetics.pptx
Raw materials used in Herbal Cosmetics.pptxRaw materials used in Herbal Cosmetics.pptx
Raw materials used in Herbal Cosmetics.pptx
 
Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptx
 
ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4
 
Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...
 

Graphics Programming in C++ with G3D Library

  • 1. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science Graphics Programming in C++ with G3D C++ is the most widely used programming language for computer graphics in both industry and research. It combines low-level features like direct memory manipulation with high-level features like exceptions, classes, and macros. These make C++ incredibly powerful and adaptable, but also create pitfalls for new programmers. G3D is an open source, cross-platform library for creating interactive 3D programs like games. 3D applications, such as games, medical software, artist tools, and film rendering software are incredibly complex. Nobody writes them from scratch because it takes about 100,000 lines of infrastructure code before you are even ready to begin the programming that is specific to your project. There are several large libraries (“engines”) that are regularly used in research and the software industry to support 3D graphics, including OGRE, Source, OpenCV, and Unreal. G3D is the one you will use as the primary support library for your projects in this course. It contains OpenGL, libpng, libjpg, zlib, ffmpeg, and other popular graphics libraries, and extends them to be both easier to use and more powerful. This document is a quick-start guide for programmers with Java experience but little or no C++ and graphics experience. Some additional resources are: • G3D Manual, /usr/local/371/html/index.html • iCompile Manual, /usr/local/371/html/icompile-manual.html • Lerner, C++ for Java Programmers, http://www.cs.williams.edu/~lenhart/courses/cs371/c++forjava.html • Fiamingo, DeBula, and Condron, Introduction to Unix http://8help.osu.edu/wks/unix_course/intro-1.html • Kernighan and Ritchie, The C Programming Language • Stroustrup, The C++ Programming Language • Neider, Davis, and Woo, OpenGL Programming Guide (also available online at http://fly.cc.fer.hr/~unreal/theredbook/) 1 Critical Things You Need To Know About C++ 1. C++ variables are objects by default. Java variables are pointers. In C++ you have to explicitly declare a pointer if you want one. Usually you can use a reference (e.g., Vector3&) or a reference-counted pointer (e.g., TextureRef) instead to avoid some of the dangers of C++ pointers. 1/17
  • 2. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science 2. C++ lets you control whether objects are allocated on the stack or the heap. You have to manually delete objects in the heap when you are done with them, which is error prone, so try to allocate on the stack whenever possible. 3. C++ has separate static compilation and linking steps. Linker errors usually occur because you forgot to implement a method (possibly due to misspelling) or because your .icompile file isn’t configured correctly. 4. Put a semi-colon at the end of class declarations. 5. Object assignment copies the whole object (which might be really slow). Matrix4 A; Matrix4 B; … Matrix4& C(A); Matrix4 D = A; C[0][2] = 1.0f; D[0][2] = 7.0f; // // // // Alias for A Copy of A Also changes A Leaves A (and C) unchanged 6. Stack declarations accept constructor arguments. Use them instead of copying! // Good Array<int> a(1024*1024); // Bad: copies 4 MB of memory! Array<int> a = Array<int>(1024*1024); 7. Don’t use: a. C array declaration syntax, e.g., int x[10] (use Array instead) b. Multiple inheritance c. Pointer arithmetic d. Multiple object declaration (e.g., don’t write Vector3 a, b, c; put each on its own line instead.) e. C memory management: malloc, calloc, free (use stack allocation or new) f. C++ new and delete, if you can avoid them with stack allocation g. std:: data structures when a G3D:: one is available (use Array, Table, Set, Queue instead) h. C strings (char*) except for initialization (use std::string instead) 8. Pass large objects by reference using &: int computeSum(const Array<int>& array); 9. Never return a reference or a pointer to an object on the stack from a method. 10. Make arguments (especially references) and methods const whenever possible 11. NULL is in all caps. It is equal to 0. 12. The Boolean data type is bool (not Bool, Boolean, BOOL, or anything else). It requires 4 bytes on most machines. 2/17
  • 3. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science 13. Primitive types, including int, float, bool, and pointers, are uninitialized when declared as locals or member variables (they are not zero/NULL like in Java.) 14. onGraphics() runs 30 times per second or more to redraw the screen. Don’t do anything slow from it, like running a ray tracer or loading a file from disk. 15. Put class declarations only in .h files 16. Put class implementations only in .cpp files 17. Wrap every .h file in a header guard. E.g., for Foo.h: #ifndef Foo_h #define Foo_h … #endif Foo_h 2 Compiling Code Programs written in any language pass through two steps before they are run. The first step is compilation, which checks syntax and types and then produces an object file (in Java, these end in .class; in C++ they end in .o or .obj). The second step is linking, which connects all of the object files into a single program. In Java, the linking step happens at run time and is not explicitly seen by the programmer. In C++, the linking step is performed in two parts: explicitly after compilation (“static linking”) and at run time (“dynamic linking). Knowing how to invoke the compiler and linker is a valuable skill. It is also one that takes some time to acquire. To help you get started quickly, I’ve provided a program called “iCompile” that will automatically compile and link your programs. It will also provide some additional functions if you request them, like copying data files from your source directory to your build directory and creating documentation for your code. To learn more about compiling and linking you can run iCompile with the “—verbosity 3” argument. All of the green text that it prints contains the actual commands being issued to the compiler. You can use “man gcc” to see a description of those commands. 3 Debugging The GNU debugger, gdb, is a command-line program that you can use to pause a running program, look at its variables, and see a stack trace. You can run your program under gdb by specifying the “—gdb” flag instead of the “—run” flag to iCompile. Compared to a visual debugger, gdb is unfortunately hard to use and many programmers use simple print statements and clever rendering tricks to try and diagnose problems in their programs. There are some situations that are impractical to debug by those methods, however, and in those situations gdb is essential. The most common of these is when an assertion failure occurs and you need a call stack to locate the source of the problem in your program (the assertion failure typically contains a line number inside a library). When this happens, select “(3) Debug” from the G3D assertion prompt, which will leave you at the gdb prompt. Type “bt” to see a backtrace (call stack), which will identify the line of your code that triggered the failure. Type “help” in gdb to learn more about other commands, e.g., for looking at local variables. 3/17
  • 4. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science G3D creates a log.txt file every time your program is run. This contains information that is useful in debugging, including the last assertion message and a list of all files that your program accessed. G3D provides several routines to aid in debugging your programs. The names of these routines all begin with “debug”. The debugPrintf function is like printf except that it disappears when you make an optimized build of your program and works in a useful way on all operating systems. The debugBreak macro pauses execution. It is a way of programmatically setting a breakpoint for the debugger. The debugAssert and debugAssertM macros execute a debugBreak if the specified condition is not true. A command-line prompt then allows you to see more information about the error and choose how you would like to continue. Sometimes you want an assertion to remain in an optimized build. Use alwaysAssertM in that case. Three routines output debugging text. screenPrintf displays information directly on your 3D window. It is most useful for debugging interactive programs that continuously rendering. debugPrintf prints to the xterm that created your program. logPrintf prints to the log.txt file, which is useful if your program is crashing in a way that takes out the xterm (or the computer). Later in the semester when using OpenGL in more advanced ways, the getOpenGLState function allows you to see the current values of the OpenGL registers. G3D makes it really easy to create GUI controls to adjust parameters in your program, which can be very helpful for debugging. Commands like: debugPane->addCheckBox(“Visible”, &visible); let you map variables from your program directly to controls on the screen so that you can try many variations without recompiling your program. 4/17
  • 5. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science 4 C++ Declarations 4.1 C++ Syntax public class A : public B { private: float x; public: A(); ~A(); void foo(); }; 4.2 A is a subclass of B The following declarations are all private members & methods. The following declarations are all public members & methods. Destructor, the opposite of a constructor. This runs when an instance is deallocated. Note the semi-colon Declarations The class is split across two files. The declaration is in a header (.h) file. This contains all of the information needed to tell the compiler how big the class is, what methods it has, and what members it has. The implementation is in a .cpp file; this is what tells the compiler what the methods do. The #include statement effectively pastes one file into another. Classes must be declared before they are used in C++. This is why we have header files—they enable us to paste the declaration before any use of the class, even if the implementations of two classes depend on each other. When the declarations of two classes depend on each other, C++ uses a forward declaration: // forward declaration class B; class A { public: void add(B& b); }; class B { public: void add(A& a); }; Compilers need to know how big objects are. Since all pointers are the same size, the compiler knows how big B* and B& are (and the special case of a B as a return value), even if they don’t know how big an instance of B is. The reason for the forward declaration is to assure the compiler that you didn’t type “B” by accident. The forward declaration how you promise the compiler that a declaration of B will show up at some point in the future (if one doesn’t, then the linker will complain). 4.3 Functions C++ allows the definition of functions, which are like static methods without an associated class. You probably won’t have to declare many of your own functions, but 5/17
  • 6. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science you likely will have to call functions written by others. For example, endsWith is a function in the following code snippet: if (! endsWith(filename, “/”)) { filename += “/”; } 5 Constants The order of initialization of global constants is undefined in C++. For example, this means that the following code could produce ANY value for the perimeter of the unit circle, because PI might be initialized after unit. const float PI = 3.1415926; class Circle { public: float perimenter; Circle(float radius); }; Circle::Circle(float radius) : perimeter(PI * 2.0f * radius) { } Circle unit(1.0f); There are several tricks to avoid being caught by this behavior. For integer constants, the enum type is always created at compile time. So integer constants can be expressed using (the admittedly awkward syntax): enum {DAYS_IN_WEEK = 7}; Macros can be used for any kind of constant: #define PI (3.1415926) #define DAYS_IN_WEEK (7) For class constants, it is necessary to create an inline function that returns a static const variable. This can also be used for other data types: inline const Matrix3& rot45() { static const Matrix3 M = Matrix3::fromAxisAngle(Vector3::unitX(), toRadians(45)); return M; } That example uses a number of C++ features too complicated to explain here, but is a pattern that you can follow for creating constants and static class member constants that are guaranteed to be valid at the global level. Constants inside methods and functions do not require such care and can be defined as if they were variables. 6/17
  • 7. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science 6 Inheritance Inheritance in C++ is tricky. In general, never use multiple inheritance—it is especially confusing and can produce code that compiles but does something other than what you expected. In Java, every class can be subclassed and every method overridden unless explicitly marked with “final”. C++ has the opposite convention. Unless a method is explicitly marked as “virtual”, it cannot be overridden (well, it can be overridden, but the result won’t be what you wanted.) In addition, unless a class has a destructor that is declared as virtual, it may also leak memory when instances are destroyed. The G3D classes that you need to subclass are declared with virtual destructors and appropriate methods (e.g., event handlers) declared virtual. The G3D classes that you don’t need to but might like to subclass (e.g., Vector3) are not declared virtual and your program will be in error if you try to inherit from them. A pure virtual method is one that is not implemented by the base class (Java calls this “abstract”). Pure virtual methods declarations have “=0” at the end, like: virtual void intersect(const Ray& worldRay, float& hitDistance, class Hit& hitResult) = 0; See http://blogs.msdn.com/oldnewthing/archive/2004/05/07/127826.aspx for a discussion of inheritance. 7 Factory Methods C++ provides overloaded constructors so that a class may be instantiated in multiple ways. Sometimes the constructors would be confusing if they were distinguished only by overloading. In theses cases it is common practice to provide a static method on the class that produces the desired instance. These so-called “factory” methods are also used for alternative memory allocation schemes like buffer pooling. Here are examples of using factory methods: Vector3 Matrix3 up = Vector3::unitY(); rot = Matrix3::fromAxisAngle(Vector3::unitX(), toRadians(15); 8 Manual Memory Management Unlike Java, in C and C++ programmers must both allocate (using “new” or “malloc”) memory for objects and deallocate that memory (using “delete” or “free”) when the object is no longer in use. Forgetting to deallocate memory leads to memory leaks, which will eventually make a program run slowly and crash. Deallocating memory that is still in use creates a “dangling” pointer and will likely cause a program to crash. As you can imagine, this manual memory management is one of the trickiest parts of C++ programming and is the source many errors. Fortunately, G3D helps you avoid ever having to manually manage memory. You should almost never have to write “new” or “delete” in your program, in fact. Two tools that G3D provides are common data structures and reference counting. 7/17
  • 8. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science 9 Data Structures The G3D Array, Queue, Set, and Table data structures are all dynamic. This means that you just declare variables of these types, for example, Array<int> myIntegerArray; and G3D will handle allocating and deallocating the underlying memory that is used to represent the data structure. C++ also provides a standard library with arrays and queues, and the C language provides built-in arrays (like Java’s built-in arrays). You should generally not use those in this class. The G3D versions are better optimized for graphics, are more platform independent, and are easier to use. For string processing, use the built-in std::string class. This can be initialized from a Cstring (char*), but is a class with useful methods. To convert std::string to C-string, use the std::string::c_str method. An example of using std::string is: std::string name = “McGuire”; debugPrintf(“Length: %dn”, name.size()); debugPrintf(“Value: ”%s”n”), name.c_str(); if (name == “Murtagh”) { debugPrintf(“username = tomn”); } else { name += “ – Username Unknown!”); } Note that words in quotes are not strings; they are values that can become strings. So “hello” + “ there” does not concatenate strings, but std::string(“hello”) + std::string(“ there”) does. 10 Reference Counting Reference counting is a form of automatic memory management (also known as garbage collection). Most G3D classes, like Texture, GFont, and Shader, are managed with reference counting. For these classes, declare your instance to be the corresponding “ref” type (“ref” means reference, another word for pointer). Use the appropriate factory method to create an instance of this class. For example: TextureRef tex = Texture::fromFile(“apple.jpg”); The ref classes act like regular C++ pointers in almost every way. They can be shared (aliased), set to NULL, and tested for equality. Use the -> or * syntax to dereference a pointer. Testing for NULL has a special syntax. Examples: 8/17
  • 9. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science int sumWidth(TextureRef tex1, TextureRef tex2) { if (tex1.notNull()) { if (tex1 == tex2) { return 2 * tex1->texelWidth(); } else { return tex1->texelWidth() + tex2->texelWidth(); } } else { return 0; } } Never use C++ pointer syntax with these reference counted classes, e.g. DO NOT write Texture*. Never call delete or new with a ref class. You can make your own reference counted classes; see the G3D documentation for more information. 11 Variable Initialization C++ does not initialize variables unless they are of a class with a default constructor. This means that most member variables and stack variables have undefined values. You should always initialize these immediately after declaring them or in your constructor. When writing your own class constructors, a special syntax allows you to initialize members before the constructor executes (this is equivalent to Java’s member assignment during definition). The syntax is a colon after the constructor signature followed by a comma-separated list of members, each with its own constructor arguments in parentheses: class Player { public: Vector2 position; std::string name; Player(); }; Player::Player() : position(10, 2), name(“Harvey”) { } 12 Pass By Reference In C++, a type written without a “*” declares a variable to be the actual object, not a pointer to the object as is the case in Java. Since you have been instructed not to use pointers in most cases, this means that almost all of your variables will be stack allocated objects or members defined inside another object. When assigning one object to another, a copy occurs. For a large object like GImage or an Array, this is potentially slow and is probably not desirable. This means that you will usually want to pass values into methods and functions by reference to avoid the copy. In C++, an ampersand (&) placed after a type makes it into a reference type that acts like a pointer but cannot be reassigned. Passing an object to a reference incurs no copy. For example, the following code passes a GImage by reference. Note the use of the const keyword to specify that the function cannot change. 9/17
  • 10. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science int findRedPixelX(const GImage& image, int y) { for (int x = 0; x < image.width; ++x) { if (image.pixel3(x, y).r == 0) { return x; } } return -1; } … GImage image(“logo.gif”); int x = findRedPixelX(im, 0); Note that the int was not passed as a reference in this example. That is because small data types like int are the same size as a pointer, so there’s no performance advantage to passing them by reference. It is possible to pass a reference to an int, and in fact that is a convenient way of returning more than one value from a method. The following example demonstrates two values returned by passing them by reference. void findRedPixel(const GImage& image, int& x, int& y) { x = -1; y = -1; for (y = 0; y < image.height; ++y) { for (x = 0; x < image.width; ++x) { if (image.pixel3(x, y).r == 0) { return; } } } } … GImage image(“logo.gif”); int x; int y; findRedPixel(im, x, y); 13 OpenGL Register Model OpenGL is the platform independent library that allows access to graphics cards. It presents a virtual interface to the card called a Hardware Abstraction Layer (HAL). This abstraction layer refers to registers and other low-level hardware features. Graphics cards are generally operated by setting state (values in the registers) and then executing a function that uses that state. G3D follows this model. The RenderDevice class contains many “set” methods that assign values to OpenGL registers. Only two methods trigger actual rendering. These are RenderDevice::sendVertex and RenderDevice::sendIndices. Because graphics cards are designed as pipelines, “sending” a value means sending it down the pipeline to processing. Most bugs in OpenGL programs are from having the wrong state set when sending data. RenderDevice::push and RenderDevice::pop allow you to easily save and restore all of the state in the rendering system, which can be used to isolate one piece of code from another and reduce the number of state-based errors. 10/17
  • 11. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science 14 Color Model To a graphics card, 0 is the darkest value that can be displayed and 1 is the brightest. These values between 0 and 1 are often rescaled and stored in bytes as values between 0 and 255. A color is represented by a triplet of red, green, and blue intensities (always written in that order). It can also be written as the hexadecimal representation of the bytes in such a triple, e.g. 0xFF8800 is redish yellow because it contains bright red, dim green, and no blue. The Color3 and Color3uint8 classes represent colors in G3D. In addition to red, green, and blue, an “alpha” channel is used to represent translucency and partial occlusion in many situations. An alpha value of 0 generally means completely translucent and a value of 1 represents completely opaque. Color4 and Color4uint8 extend Color3 with an alpha value. The alpha value is represented as the high-order bits when writing in hex: 0xFF000000 is opaque black. 15 2D Coordinate System For historical reasons, in 2D (0, 0) is the upper-left corner of an image or the screen. The x-axis increases to the right and the y-axis increases down. This is used for RenderDevice push2D rendering, Texture coordinates, and for GImage pixel addressing. Texture coordinates vary from (0, 0) in the upper-left to (1, 1) in the lower right, while RenderDevice push2D, Image, and GImage use integer pixel coordinates. 16 Immediate vs. Retained Mode Graphics In a retained mode graphics API, you create objects and they persist until destroyed, drawing themselves on screen and interacting with the user. An example is the Swing JComponent API in Java, where you create objects like JButton and JTextArea that then appear on screen until dismissed. In an immediate mode graphics API, you explicitly draw on a canvas that is periodically erased. There are no persistent objects; if the canvas is erased by your code or by another window drawing over it, your image will be lost forever and must be redrawn from scratch. An example of this is the Swing Graphics2D API used in the Component.paint methods. G3D provides pieces for writing retained mode code, but it is intended primarily for immediate mode rendering. In GApplet, the onGraphics event handler that you implement will be invoked several times a second. It will use calls on a RenderDevice to create an image that lasts only until the next frame of animation. 17 Starting Your Program iCompile will automatically copy the contents of the data-files directory into the build directory, change into the build directory, and then launch your program. At that point, the main() function begins. Main must have the following syntax: int main(int argc, char** argv) { … return …; } 11/17
  • 12. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science Integer argc is the number of command line arguments that were passed to your program as strings. There is always at least one, which is the name of your program. Variable argv is a pointer to a pointer to a character. In C (not C++) syntax, it can also be viewed as an array of arrays, or an array of strings. That’s because a C array is just a pointer to the first element in the array. C doesn’t keep track of how many elements are in an array for you…if you go off the end, you simply start corrupting memory and the program crashes! That’s why argc is provided. A string in C (as opposed to a C++ std::string) is just an array of characters. The last character is ‘0’ (this is a “null-terminated” string), which is how you know when the string has ended. An example of simple command line argument processing is: int main(int argc, char** argv) { if ((argc > 1) && (std::string(“hello”) == argv[1])) { … } return …; } Here, constructing a C++ std::string lets us use the == operator to tell if the two strings are identical. If we just said “hello” == argv[1], then we’d be testing if the memory pointer to “hello” was the same as the memory pointer argv[1], not asking if they contained equivalent strings. If you’ve programmed in Java, then you might recall the difference between String.equals and ==; in C++, that’s the difference between std::string::operator== and C-string == on pointers. 18 C++ Syntax Reference 18.1 Pointers and References Object: Vector3 v; Reference: this acts like an object but re-uses the memory allocated for v and can never be assigned to different memory. Vector3& r(v); Pointer: this stores the address of the memory for v. It can be reassigned to a different address (or to NULL). Vector3* p(&v); 12/17
  • 13. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science Reference counted pointer: this acts like a pointer, but garbage collects the object when it is no longer used. These are only available for some objects: TextureRef tex = Texture::fromFile(“hello.jpg”); Assign to a member: v.x = 1.0f; r.x = 3.0f; p->x = 7.0f; *p.x = 8.0f; tex->invertY = true; *tex.invertY = false; Read a member/invoke a method float f; f = v.y; v.unitize(); f = r.y; f = p->y; f = *p.y; f = tex->width(); f = *tex.width(); Copy the value: v = *p; *p = v; r = v; v = r; *p = r; Point at the same value: p = &r; p = &v; Vector3* Vector3* Vector3& Vector3& q = p; q(p); s(&r); z(*p); c(r); 18.2 Allocation Allocate on the stack (will automatically be deallocated when it goes out of scope): Vector3 v(5, 2, -15); 13/17
  • 14. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science Allocate a C++ array on the stack (will automatically be deallocated when it goes out of scope), where the contents of the array are in the heap: Array<Vector3> v(10); std::vector<Vector3> x(10); // G3D; recommended // std; not recommended for 371 Allocate a C array on the stack, where the contents of the array are also on the stack (generally undesirable): Vector3 v[10]; Allocate a reference-counted object on the heap (will automatically be deallocated when the last pointer is dropped, just like in Java): Image3Ref im = Image3::createEmpty(100, 100); Allocate a non-reference counted object on the heap (avoid this whenever possible, since you must explicitly deallocate it or memory will leak!): MyObject* obj = new MyObject(); … delete obj; obj = NULL; 18.3 static Declare that a method is on a class, not a member (same as in Java): class Ball { public: static BallRef create(const std::string& name); }; In the .cpp file for the above example, do not put “static” in front of the implementation: BallRef Ball::create(const std::string& name) { return new Ball(); } Declare that a member variable belongs to a class, not a member (same as in Java): class Cube { public: static int numCubes; }; In the .cpp file for the above example, numCubes is initialized as: int Cube::numCubes = 0; 14/17
  • 15. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science Declare that a variable should only be initialized the first time a method is invoked, and its value remembered after that (rarely a good idea for non-const variables): void MyClass::sketchy() { static int x = 0; … } Declare that a function or variable should not be visible outside a .cpp file (rarely used): static int helper(int y, int z) { Return y + 2 * z; } 18.4 const Declare that a method never mutates a value: void safeMethod(const std::string& x); Declare that a method never mutates any member variable: void alsoSafe(int y) const; Declare that a member variable is never changed after initialization: class Clown { public: const Color3 hair; Clown(); }; Create a mutable pointer to an immutable int, i.e., “don’t change the value x is pointing at”: const int* x; int const* x; Create an immutable pointer to a mutable int, i.e., “don’t reassign the pointer”/ “don’t change x”: int* const x; 15/17
  • 16. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science 18.5 Iterator Set<int> keep; … Set<int>::Iterator it = keep.begin(); Set<int>::Iterator end = keep.end(); while (it != end) { … ++it; } 18.6 Function Pointers You don’t need to use function pointers very often, but if you do, the syntax is odd and you’ll want to check back here. Pass a non-static method pointer as an argument: debugPane->addButton(“Exit”, &App::exit); Declare a function pointer/static method pointer (e.g., to atan2): double(*atan2Ptr)(double, double); Create a typedef for a function pointer type: typedef double(*)(double, double) ATan2Type; Pass a function pointer as an argument or use as a value: passPointer( &atan2 ); ATan2Type atan2Ptr = &atan2; Call a function using its pointer (two syntaxes available): atan2Ptr(x, y); (*atan2Ptr)(x, y); 18.7 printf G3D provides three ways of printing text: logPrintf(), debugPrintf(), and screenPrintf(). You can also print to a std::string with format(). Type “man printf” to see a full specification for these. The common idioms you’ll use are: 16/17
  • 17. CS371 Fall 2008 Prof. McGuire Williams College Department of Computer Science std::string s; int i; float f; … debugPrintf(“The int’s value is %dn”, i); debugPrintf(“A string %s and a float %fn”, s.c_str(), f); 19 Coding Conventions We’re going to be looking at a lot of each other’s code between group projects, sample code, and helping each other debug. To make it easy to understand code written by others and to cut and paste between projects, please follow the following coding conventions. In some cases you may find that the conventions are making it harder to read your code. When that occurs, write in the way that is easiest for another person to read even if it breaks with convention. • Follow Java coding conventions wherever they apply to C++ • Make header guards case-sensitive, e.g., #ifndef Film_h • Prefix private and protected member variables with m_, e.g., m_photonMap • Indent member variables and method arguments in columns, e.g., int m_numPhotons; std::string m_filename; • Put a space before the open parent of FOR, WHILE, and IF, e.g., if (! b) • Put the open-brace on the same line as FOR, WHILE, IF, TRY, etc. • Always uses braces, even for single-line FOR, WHILE, etc. • Use four-space indenting and no tabs • Put comments before the code to which they apply • Keep lines to about 80 characters (for printing) • Fully-parenthesize logical expressions, e.g., (x || y) && (z > 2) • When writing pointers, the * goes with the class name, e.g., RenderDevice* rd; 17/17