Texturing a cloth simulation

In this recipe, we will learn how to apply a texture to the cloth simulation we created in the Creating a cloth simulation recipe of the current chapter.

Getting ready

We will be using the cloth simulation developed in the recipe Creating a cloth Simulation as the base for this recipe.

You will also need an image to use as texture; place it inside your assets folder. In this recipe we will name our image texture.jpg.

How to do it…

We will calculate the correspondent texture coordinate to each particle in the cloth simulation and apply a texture.

  1. Include the necessary files to work with the texture and read images.
    #include "cinder/gl/Texture.h"
    #include "cinder/ImageIo.h"
  2. Declare a ci::gl::Texture object in your application's class declaration.
    gl::Texture mTexture;
  3. In the setup method load the image.
    mTexture = loadImage( loadAsset( "image.jpg" ) );
  4. We will remake the draw method. So we'll erase everything in it which was changed in the Creating a cloth simulation recipe and apply the clear method. Your draw method should be like the following:
    void MyApp::draw(){
      gl::clear( Color( 0, 0, 0 ) );
    }
  5. After the clear method call, enable the VERTEX and TEXTURE COORD arrays and bind the texture. Add the following to the draw method:
    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    mTexture.enableAndBind();
  6. We will now iterate over all particles and springs that make up the cloth simulation grid and draw a textured triangle strip between each row and the row next to it. Start by creating a for loop with mNumRows-1 iterations and create two std::vector<Vec2f> containers to store vertex and texture coordinates.
    for( int i=0; i<mNumRows-1; i++ ){
      vector<Vec2f>vertexCoords, textureCoords;
    }
  7. Inside the loop we will create a nested loop that will iterate over all lines in the cloth grid. In this loop we will calculate the index of the particles whose vertices will be drawn, calculate their correspondent texture coordinates, and add them with the positions of textureCoords and vertexCoords. Type the following code into the loop that we created in the previous step:
    or( int j=0; j<mNumLines; j++ ){
     int indexTopLeft = i * mNumLines + j;
     int indexTopRight = ( i+1) * mNumLines + j;
     Particle *left = mParticleSystem.particles[ indexTopLeft ];
     Particle *right = mParticleSystem.particles[indexTopRight ];
     float texX = ( (float)i / (float)(mNumRows-1) ) * mTexture.getRight();
     float texY = ( (float)j / (float)(mNumLines-1) ) * mTexture.getBottom();
     textureCoords.push_back( Vec2f( texX, texY ) );
     vertexCoords.push_back( left->position );
     texX = ( (float)(i+1) / (float)(mNumRows-1) ) * mTexture.getRight();
     textureCoords.push_back( Vec2f( texX, texY ) );
     vertexCoords.push_back( right->position );
    }

    Now that the vertex and texture coordinates are calculated and placed inside vertexCoords and textureCoords we will draw them. Here is the complete nested loop:

    for( int i=0; i<mNumRows-1; i++ ){
     vector<Vec2f> vertexCoords, textureCoords;
     for( int j=0; j<mNumLines; j++ ){
      int indexTopLeft = i * mNumLines + j;
      int indexTopRight = ( i+1) * mNumLines + j;
      Particle *left = mParticleSystem.particles[ indexTopLeft ];
      Particle *right = mParticleSystem.particles[ indexTopRight ];
      float texX = ( (float)i / (float)(mNumRows-1) ) * mTexture.getRight();
      float texY = ( (float)j / (float)(mNumLines-1) ) * mTexture.getBottom();
      textureCoords.push_back( Vec2f( texX, texY ) );
      vertexCoords.push_back( left->position );
      texX = ( (float)(i+1) / (float)(mNumRows-1) ) * mTexture.getRight();
      textureCoords.push_back( Vec2f( texX, texY ) );
      vertexCoords.push_back( right->position );
     }
     glVertexPointer 2, GL_FLOAT, 0, &vertexCoords[0] );
     glTexCoordPointer( 2, GL_FLOAT, 0, &textureCoords[0] );
     glDrawArrays( GL_TRIANGLE_STRIP, 0, vertexCoords.size() );
    }
  8. Finally we need to unbind mTexture by adding the following:
    mTexture.unbind();

How it works…

We calculated the correspondent texture coordinate according to the particle's position on the grid. We then drew our texture as triangular strips formed by the particles on a row with the particles on the row next to it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.34.80