## Textures

Images in OpenGL generally take the form of textures, and Cinder exposes this functionality through the class gl::Texture2d and its siblings. Let's look at a basic example:

    class BasicApp : public App {
      public:
    	void setup() override;
    	void draw() override;

    	gl::Texture2dRef		mTex;
    };

    void BasicApp::setup()
    {
    	auto img = loadImage( loadAsset( "clouds.jpg" ) );
    	mTex = gl::Texture2d::create( img );
    }

    void BasicApp::draw()
    {
    	gl::clear();

    	gl::draw( mTex );
    }

We're using an image from Trey Ratcliff that's saved in our application's `assets` directory as "clouds.jpg". We call loadImage() using this asset and then pass the result to the variant of gl::Texture2d::create() which accepts an ImageSource.

Besides simply drawing a texture, we often want to apply one (or more) to the vertices of a 2D or 3D model - a process known as texturemapping. Let's look at a simple example of this in Cinder:

    class BasicApp : public App {
      public:
    	void	setup() override;
    	void	draw() override;

    	CameraPersp			mCam;
    	gl::BatchRef		mSphere;
    	gl::TextureRef		mTexture;
    	gl::GlslProgRef		mGlsl;
    };

    void BasicApp::setup()
    {
    	mCam.lookAt( vec3( 3, 2, 4 ), vec3( 0 ) );

    	auto img = loadImage( loadAsset( "checkerboard.png" ) );
    	mTexture = gl::Texture::create( img );
    	mTexture->bind();

    	auto shader = gl::ShaderDef().texture().lambert();
    	mGlsl = gl::getStockShader( shader );
    	auto sphere = geom::Sphere().subdivisions( 50 );
    	mSphere = gl::Batch::create( sphere, mGlsl );

    	gl::enableDepthWrite();
    	gl::enableDepthRead();
    }

    void BasicApp::draw()
    {
    	gl::clear( Color( 0.2f, 0.2f, 0.2f ) );
    	gl::setMatrices( mCam );

    	mSphere->draw();

    	// draw the texture itself in the upper right corner
    	gl::setMatricesWindow( getWindowSize() );
    	Rectf drawRect( 0, 0, mTexture->getWidth() / 3,
    						mTexture->getHeight() / 3 );
    	gl::draw( mTexture, drawRect );
    }

In this example we load the texture from a file called checkerboard.png, similar to the previous example. However in this case, we're setting up a gl::GlslProg from a gl::ShaderDef with both lambert() and texture() applied. Another key distinction is that we're calling the bind() method on mTexture. Binding a texture is simply making it the active texture. We do this from `setup()` because we only ever bind one texture. In the `draw()` method we draw the sphere by calling `mSphere->draw()`. Finally, we draw the texture itself for illustration purposes. Notice that before we do so, we use gl::setMatricesWindow() to restore our `View` and `Perspective` matrices to the window-aligned defaults. Also note that we're using the gl::draw() variant that accepts a Rectf which the texture is mapped to.