title: Drawing Explosions Android OpenGL ES 2.0
body: <p>I am working on a game (<a href="https://play.google.com/store/apps/details?id=com.embeddedmicro.wormholebeta" rel="nofollow" title="beta is here">beta here</a>) and I am drawing explosions using an image I have. As the explosion ages it increases in size and becomes more transparent until it is gone.</p>
  
  <p>My problem is that this seems to be the bottle neck it my code. I easily hit 60FPS but when explosions start happening this can easily drop down to 30FPS. If I disable only the explosions I get a constant 60FPS. </p>
  
  <p>Is there something I can do with OpenGL to render these more effectively? </p>
  
  <p>I am drawing them all sequentially and I only bind the texture and vertices once. </p>
  
  <p>Any general stuff I should be aware of for optimizing OpenGL calls?</p>
  
  <p>My code is in Java, would re-writing this part in native code help?</p>
  
  <p>I have a main draw function that draws all the explosions</p>
  
  <pre><code>public void draw() {
      GLES20.glUniform1i(GraphicsEngine.uEnableVortex, 0);
      for (Boom boom : mBooms) {
          boom.drawCloud();
      }
      mHugeBoom.drawCloud();
      GLES20.glUniform1i(GraphicsEngine.uEnableVortex, 1);
  
      // Prepare the data
      GLES20.glVertexAttribPointer(GraphicsEngine.aPositionHandle, 3,
              GLES20.GL_FLOAT, false, 12, mVerticesBuffer);
      GraphicsEngine.clearShape();
  
      // Disable textures
      GLES20.glUniform1i(GraphicsEngine.uEnableTextureHandle, 0);
  
      GLES20.glLineWidth(2.0f);
  
      for (Boom boom : mBooms) {
          boom.drawSparks();
      }
      mHugeBoom.drawSparks();
  }
  </code></pre>
  
  <p>Then for "booms"</p>
  
  <pre><code>public void drawCloud(){
          if (mActive) {
              float pDone = mTotalTime / 600.0f / mSize;
              if (pDone &lt;= 1.0f) {
                  mBurst.setColor(mRGBA);
                  mBurst.draw(mMMatrix);
              }
          }
      }
  
      public void drawSparks(){
          if (mActive) {
              for (Particle particle : mParticles) {
                  particle.draw();
              }
          }
      }
  </code></pre>
  
  <p>The actual drawing </p>
  
  <pre><code>public void draw(float[] MMatrix, boolean setColor) {
      // Prepare the triangle data
      GraphicsEngine.setShape(mShape);
  
      if (mTextureId != -1) {
          GraphicsEngine.bindTexture(mTextureId);
          if (mCustomTex) {
              GLES20.glVertexAttribPointer(GraphicsEngine.aTexCoordHandle, 2,
                      GLES20.GL_FLOAT, false, 8, mTextureBuffer);
              GLES20.glEnableVertexAttribArray(GraphicsEngine.aTexCoordHandle);
              GraphicsEngine.clearTexture();
          } else {
              GraphicsEngine.setTexture(mShape);
          }
      } else {
          GLES20.glUniform1i(GraphicsEngine.uEnableTextureHandle, 0);
      }
  
      // Apply a ModelView Projection transformation
      GLES20.glUniformMatrix4fv(GraphicsEngine.uMMatrixHandle, 1, false,
              MMatrix, 0);
  
      if (setColor)
          GLES20.glUniform4fv(GraphicsEngine.uColorHandle, 1, mRGBA, 0);
  
      GLES20.glDrawElements(GLES20.GL_TRIANGLES,
              GraphicsEngine.getNumIndicies(mShape),
              GLES20.GL_UNSIGNED_SHORT, GraphicsEngine.getIndicies(mShape));
  
  }
  </code></pre>
  
  <p>Code that prevents reloading of loaded textures</p>
  
  <pre><code>public static void setShape(int i) {
      if (mState.shape != i) {
          GLES20.glVertexAttribPointer(aPositionHandle, 3, GLES20.GL_FLOAT,
                  false, 12, mShapes[i].vertices);
          mState.shape = i;
      }
  }
  
  public static void setTexture(int i) {
      if (mState.texture != i) {
          GLES20.glVertexAttribPointer(GraphicsEngine.aTexCoordHandle, 2,
                  GLES20.GL_FLOAT, false, 8, mShapes[i].texture);
          mState.texture = i;
      }
  }
  </code></pre>