# Cinder

# Chapter 1: Getting Started

## Building a new project

Getting a new project up and running in Cinder is simple. Take a peek at the Mac or Windows guides to creating a new project to see for yourself. However, for this tutorial you can simply follow along from the project source code contained in the cinder/tour folder.
When you create a new Cinder project, you will notice there are a few functions declared for you. Every Cinder project is made up of three main functions. You initialize your variables in the setup() method which is called once when your program begins. You make changes to those variables in the update() method. And finally, you draw() content in your program window. Update and draw are the heartbeat of any Cinder project. Setup, then update and draw, update and draw, update and draw, on and on until you quit the application.

    void setup();
    void update();
    void draw();

Additionally, you can modify some of the settings using the prepareSettings() method. It is entirely optional and if you choose to leave it out, Cinder will use a default window size of 640x480 with a frame rate of 30. For this tutorial, we want our window to be 800x600 with a frame rate of 60 so we would say:

    void TutorialApp::prepareSettings( Settings *settings ){
        settings->setWindowSize( 800, 600 );
        settings->setFrameRate( 60.0f );
    }

Another thing to notice up front is that Cinder uses C++ namespaces. Depending on what programming languages you've worked with, you may have already encountered namespaces before. They're nothing fancy - just a way of grouping functions and classes together under a common name. Everything in Cinder is inside the cinder:: namespace. So to reference something inside it, like say, the Timer class, we refer to cinder::Timer. C++ namespaces also support hierarchies, which is a very nice feature that Cinder takes advantage of. So for example, the OpenGL texture class has the full name of cinder::gl::Texture. However this can get a little long-winded sometimes, so Cinder provides a couple of shortcuts. The first is that whenever you would refer to cinder:: you can also refer to its synonym, ci::. These are completely interchangeable, but `ci::` is a little easier to type, so we recommend it. Secondly, you'll generally see in the samples the following two lines toward the top:

    using namespace ci;
    using namespace ci::app;

These `using` statements are just a shortcut to tell the C++ compiler, "if it's ever unclear, I am talking about namespace whatever, but I am not going to keep typing `whatever::` everywhere." There is a list of the namespaces inside Cinder here.
Now that you understand the basic workings for any Cinder application, feel free to hit Run (or build or whatever button makes it go). You should see a 800x600 pixel window filled with black.

Congratulations. You have just created your new blank canvas: a black expanse filled with potential. It is a single line of code and a perfect place to start. This is how you clear the screen to black in Cinder.

    gl::clear();

If you are familiar with OpenGL, you will note that this is just a convenience method provided by Cinder. All gl::clear() is doing is wrapping up a few lines of code into one easy to use function. The actual code executed by gl::clear() is shown below.

    void clear( const ColorA &color, bool clearDepthBuffer ) {
        glClearColor( color.r, color.g, color.b, color.a );
        if( clearDepthBuffer ) {
            glDepthMask( GL_TRUE );
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        }
        else
            glClear( GL_COLOR_BUFFER_BIT );
    }

For example, if you wanted to clear the background to red and also clear the depth buffer, you would write

    gl::clear( Color( 1, 0, 0 ), true );

It is much nicer to just deal with that single line of code instead of needing to write out the full OpenGL syntax to clear the screen. As we continue, we will encounter many other convenience methods. They are entirely optional. If you'd rather write out the whole thing, be our guest.
By the way, Color() is just a class provided by Cinder to help describe and manipulate color data.
Moving along, perhaps you want the background to cycle between white and black. You could make use of getElapsedSeconds(), which will return a float equal to the number of seconds since the app started. The following `gray` variable oscillates between 0.0 and 1.0.

    float gray = sin( getElapsedSeconds() ) * 0.5f + 0.5f;
    gl::clear( Color( gray, gray, gray ), true );

Animation! Give yourself a pat on the back.

## Loading and displaying images

Loading images in C++ can be a chore. Luckily, Cinder does most of the hard work for you. The process for loading and displaying an image can be broken up into only a few lines of code.
1) Tell the compiler we're interested in Cinder's image input/output code.

    #include "cinder/ImageIo.h"

You put this line at the top of the project with the other includes. In particular we'll be using the loadImage() function this file declares.
2) Declare a new texture in the App class.

    gl::Texture myImage;

This is where you say that you want your app class to have a gl::Texture object and it is going to be called `myImage`. This line of code goes in the App class declarations.
3) Load an image into the texture you just declared.

    myImage = gl::Texture( loadImage( loadResource( "image.jpg" ) ) );

Now that you have declared a new gl::Texture object, you need to put some image data into that gl::Texture. There are myriad ways to do this. In this example we are assuming you've got a resource in your application that is a JPEG file called image.jpg. We can load this resource using loadResource(), and we pass the result of that to loadImage(), and in turn construct our gl::Texture with the image that comes back. This line of code would go into your setup() method. (By the way, this is the Mac OS X way of using resources, and the Windows way is just a bit different, but we won't get into the subtleties here. If you would like to take a break and read about how to use and manage resources, check out Using Resources in Cinder).
4) Draw the Texture into the app window.

    gl::draw( myImage, getWindowBounds() );

Finally, you place this line in the draw() function and it will draw the gl::Texture so that it fills the app window. This is another Cinder convenience method. Behind the scenes there are OpenGL calls to create a textured `GL_TRIANGLE_STRIP`. As we mentioned before, you can write out all the OpenGL yourself if you choose. Either way is fine, but for drawing things like images or circles or other simple forms, it is great to have these one-liner solutions.
And what does a loaded and drawn image look like? Well, if you use a picture of Paris the kitty, it would look a bit like this.

## Other options for dealing with images

As we mentioned before, including images directly in your app as resources is one option, but Cinder makes it easy to load images from many different sources. I'm going to show you two additional ways you can use images in your application without needing to have them stored locally. The first way is to prompt the user to open a file.
The following code will attempt to create an image from a file selected by means of a standard open dialog box. Once you select a file, assuming the file is a valid image, a texture is created. Otherwise, an exception is thrown and we print an error message (we'll discuss console() more in a bit).

    try {
        std::string p = getOpenFilePath( "", ImageIo::getLoadExtensions() );
        if( ! p.empty() ) { // an empty string means the user canceled
            myImage = gl::Texture( loadImage( p ) );
        }
    }
    catch( ... ) {
        console() << "Unable to load the image." << std::endl;
    }

Notice the second parameter to getOpenFilePath(), which is the result of ImageIo::getLoadExtensions(). This is a quick way to tell the open dialog, "only the let user pick files whose extensions correspond with the types of images I know how to load."
The second way of getting images into your application is to load them directly from a Url. This is surprisingly easy.

    Url url( "http://validurl.com/image.jpg" );
    myImage = gl::Texture( loadImage( loadUrl( url ) ) );

Keep in mind that you should not try to draw the texture until after something has been loaded into it. We should check to make sure `myImage` is a valid gl::Texture before attempting to use it. We can do this with a simple `if` statement:

    if( myImage )
        gl::draw( myImage, getWindowBounds() );

## Drawing Shapes

Drawing shapes is just as easy. If you want to draw a circle of a radius of x, you can use gl::drawSolidCircle(). The following line of code will draw a filled circle centered at (15,25) with a radius of 50.

    gl::drawSolidCircle( Vec2f( 15.0f, 25.0f ), 50.0f );

The circle that is created is actually an OpenGL `TRIANGLE_FAN`. The number of triangles comprising the fan can be controlled by an optional third parameter. If left blank, the circle will be created with as much detail as is needed based on the circle's radius. For example, the following code will create a filled hexagon. Note that the detail parameter represents the number of vertices to draw. Since we are drawing a triangle fan, we need to include the center point which brings the total vertices to 7, not 6.

    gl::drawSolidCircle( Vec2f( 15.0f, 25.0f ), 50.0f, 7 );

There are similar methods for drawing all manner of basic geometry, both 2D and 3D. Check the reference for the full list.
Not content with a stationary circle? That is easily fixed.

    float x = cos( getElapsedSeconds() );
    float y = sin( getElapsedSeconds() );
    gl::drawSolidCircle( Vec2f( x, y ), 50.0f );

Now we have a circle that moves in a 1 pixel radius trajectory around the origin (0,0). A 1 pixel radius around the origin? What good is that? Well, we are breaking this process down step by step so you can see how to evolve a sketch. If you were to just skip ahead to the final code you miss out on how it was derived.
First, lets put our circle closer to the center of the app window. Right now, the circle is drawn in the upper left corner of the screen (the origin). We can use getWindowWidth() and getWindowHeight() to retrieve the dimensions of the window and add half their respective values to the `x` and `y` variables.

    float x = cos( getElapsedSeconds() ) + getWindowWidth() / 2;
    float y = sin( getElapsedSeconds() ) + getWindowHeight() / 2;
    gl::drawSolidCircle( Vec2f( x, y ), 50.0f );

We can simplify this further by using getWindowSize(), which returns a Vec2i representing the dimensions of the app window. We can add half of the window size to circle and this will also move it to the middle of the screen.

    float x = cos( getElapsedSeconds() );
    float y = sin( getElapsedSeconds() );
    gl::drawSolidCircle( Vec2f( x, y ) + getWindowSize() / 2, 50.0f );

Now that we have moved our circle to the center of the screen, lets fix the radius of the sine and cosine offset. Currently, our circle is moving but the range of its movement is 2 pixels so it isn't very lively. If you want your circle to move in a 100 pixel radius circular orbit, just multiply the x and y variables by 100.0.

    float x = cos( getElapsedSeconds() ) * 100.0f;
    float y = sin( getElapsedSeconds() ) * 100.0f;
    gl::drawSolidCircle( Vec2f( x, y ) + getWindowSize() / 2, 50.0f );

Finally we are going to make the circle's radius change in relation to its x position. Since x spends as much time as a negative number as it does a positive number, we will go ahead and use the absolute value of x.

    gl::drawSolidCircle( Vec2f( x, y ) + getWindowSize() / 2, abs( x ) );

## Creating a basic Particle engine

These last few steps, though tiny, are a great example why we should go ahead and make a class for this circle. If we ever wanted to draw two or more circles, each with their own position, speed, and size, it becomes necessary to package up this data into its own class to make it easier to access each circle individually. We could say `circle1` has a position of `loc1` with a size of `radius1`, and then do the same with `circle2` and `circle3` and so on. However, when you want to start dealing with thousands of circles, it quickly becomes obvious that we should rethink how we are approaching this problem.
First, we will create a controller class. This just makes it easy to segregate `Particle`-related code. This new class is called `ParticleController` and as the name suggests, it is in charge of controlling the `Particle`s. It will have its own `update()` and `draw`() methods. `update()` will iterate through all of the `Particle`s and tell each one to run its own personal `update()` method. After all the `Particle`s are updated, the `ParticleController` then tells each of the `Particle`s to `draw()`.
The `Particle` class is based what we did with the circle above. Each `Particle` has a position in space, a direction of travel, a speed of travel, a size, and whatever else you want to add to give each `Particle` its own personality. Later on, we will add a few more variables. Here is a summary of the `Particle` class code (the full source is contained in cinder/tour/Chapter 1/)

    Particle::Particle( Vec2f loc ) {
        mLoc = loc;
        mDir = Rand::randVec2f();
        mVel = Rand::randFloat( 5.0f );
        mRadius = 5.0f;
    }

    void Particle::update() {
        mLoc += mDir * mVel;
    }

    void Particle::draw() {
        gl::drawSolidCircle( mLoc, mRadius );
    }

The `ParticleController`, which we will discuss in a moment, is responsible for creating new `Particle`s. For now, we will also task the `ParticleController` with saying where the new `Particle` should be created and we pass that location in the constructor.
The `Particle` then determines which direction it is traveling, in this case that direction is a random normalized 2D vector, as well as what speed it is traveling. We'll discuss these Rand functions in more detail in the next chapter.
Note: The variables in the `Particle` class all begin with the letter 'm'. This is just a naming convention to let me know at a glance which variables are member variables. It is a good habit to get into and comes in very handy when the class grows to hundreds of lines of code.
Let's have a peek at ParticleController.h.

    #pragma once
    #include "Particle.h"
    #include <list>

    class ParticleController {
     public:
        ParticleController();
        void update();
        void draw();
        void addParticles( int amt );
        void removeParticles( int amt );

        std::list<Particle> mParticles;
    };

Not much to it. The `ParticleController::update()` method tells all the `Particle`s to update. The `ParticleController::draw()` method tells all the `Particle`s to draw. And the `addParticles()` and `removeParticles()` methods will create or destroy the supplied amount of `Particle`s.
All of the `Particle`s are kept in a `list`. This is a class built-in to C++ which maintains a linked list of objects. If you're new to C++, you should definitely familiarize yourself with these built-in classes (called the STL) - they are extremely fast and powerful. A nice list and discussion of them is available here. If you want to add a new `Particle` to the end of the `list`, you use `push_back:`

    float x = Rand::randFloat( app::getWindowWidth() );
    float y = Rand::randFloat( app::getWindowHeight() );
    mParticles.push_back( Particle( Vec2f( x, y ) ) );

And as you might have guessed, to remove a `Particle` from the end of the `list`, you use `pop_back()`. Eventually you are going to want more control over which `Particle`s to remove. For instance, a `Particle` moves offscreen and you no longer need it around. You cannot rely on `pop_back()` because it is highly unlikely that the `Particle` at the end of the `list` will also be the one that just moved offscreen. We will solve this problem a little later in the tutorial.
In order to tell each of the `Particle`s in our list to `update()` or `draw`(), we use an iterator. The iterator is simply a way to access all the items in a list one by one.

    void ParticleController::update() {
        for( list<Particle>::iterator p = mParticles.begin(); p != mParticles.end(); ++p ){
            p->update();
        }
    }

That is just about all we need. All that remains is to add the appropriate `ParticleController` method calls in the App class and we are done.
After we declare our `ParticleController`, called `mParticleController`, we add the following line to the setup() method:

    mParticleController.addParticles( 50 );

The update() method will look like this:

    mParticleController.update();

And finally, the draw() method:

    gl::clear( Color( 0, 0, 0 ), true );
    mParticleController.draw();

When you build and run the project, you should see 50 white circles appear in random locations and move in random directions.

50? Boring. How about 50,000?

Up next, we are going to add some personality to our `Particle`s. On to Chapter 2.