# OpenGL ES 2.0 – Applying rotation to only specific quads within a batch

This problem seems fairly simple on the face of it: How, when drawing a batch of quads using a triangle strip, can I apply a rotation to **only one or some of the quads**.

I’ve been looking at this problem for ages and have looked at various similar questions on SE and the wider internet (I’ve also asked this before). I’m still at a loss as to how to achieve this.

I’ve included the code that I use to draw my sprites (my project is a 2D game). As well as my rotation method and shaders.

Needless to say, I can draw many objects (currently, my largest batch contains over 200 objects) – I use a spritesheet, so drawing my sprites with different parts of a larger texture, isn’t a problem. Obviously, when I apply a rotation, it rotates the batch as a whole.

**Draw Batch Method**

```
public void drawBatch(int[] coOrdinates, float[] mvpMatrix, int numOfSprites, int totalFrames, float[] whichFrame){
x= 0;
coOrdinateCount = 0;
//Populate the array based on the number of sprites
for (int count = 0;count<numOfSprites;count+=1){
//NOTE - textureLeft, TextureRight, textureTop, textureBottom, xPlotTop, xPlotBottom, xPlotLeft & xPlotRight ARE valid. I've removed the code working them out for readability as it's not relevant to this question
vertices[x] = xPlotLeft;
vertices[(x+1)] = yPlotTop;
vertices[(x+2)] = 0;
vertices[(x+3)] = textureLeft;
vertices[(x+4)] = textureTop;
vertices[(x+5)] = xPlotRight;
vertices[(x+6)] = yPlotTop;
vertices[(x+7)] = 0;
vertices[(x+8)] = textureRight;
vertices[x+9] = textureTop;
vertices[x+10] = xPlotLeft;
vertices[x+11] = yPlotBottom;
vertices[x+12] = 0;
vertices[x+13] = textureLeft;
vertices[x+14] = textureBottom;
vertices[x+15] = xPlotRight;
vertices[x+16] = yPlotTop;
vertices[x+17] = 0;
vertices[x+18] = textureRight;
vertices[x+19] = textureTop;
vertices[x+20] = xPlotLeft;
vertices[x+21] = yPlotBottom;
vertices[x+22] = 0;
vertices[x+23] = textureLeft;
vertices[x+24] = textureBottom;
vertices[x+25] = xPlotRight;
vertices[x+26] = yPlotBottom;
vertices[x+27] = 0;
vertices[x+28] = textureRight;
vertices[x+29] = textureBottom;
x+=30;
coOrdinateCount+=2;
}
vertexBuf.rewind();
vertexBuf.put(vertices).position(0);
GLES20.glUseProgram(iProgId);
// Combine the rotation matrix
Matrix.multiplyMM(mvpMatrix2, 0, mvpMatrix, 0, mRotationMatrix, 0);
mMVPMatrixHandle = GLES20.glGetUniformLocation(iProgId, "uMVPMatrix");
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix2, 0);
//Set starting position
vertexBuf.position(0);
//Specify attributes
GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
//Enable attribute
GLES20.glEnableVertexAttribArray(iPosition);
//Set starting position (texture)
vertexBuf.position(3);
//Specify attributes (textures)
GLES20.glVertexAttribPointer(iTexCoords, 2, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
//Enable attribute for texture
GLES20.glEnableVertexAttribArray(iTexCoords);
//Enable Alpha blending
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
//Draw
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6 * numOfSprites);
//Disable Alpha blending
GLES20.glDisable(GLES20.GL_BLEND);
}
```

**Rotation Method(only works for single quads)**

```
public void rotate(float x, float y, int angle){
//Note centreX, centreY are valid. The code that works them out has been removed for readability as they are not relevant to this question.
Matrix.setIdentityM(mRotationMatrix, 0);
Matrix.translateM(mRotationMatrix, 0, centreX, centreY, 0f);
Matrix.rotateM(mRotationMatrix, 0, angle, 0, 0, 0.1f);
Matrix.translateM(mRotationMatrix, 0, -centreX, -centreY, 0f);
}
```

**Vertex Shader**

```
String strVShader =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 a_position;n"+
"attribute vec2 a_texCoords;" +
"varying vec2 v_texCoords;" +
"void main()n" +
"{n" +
"gl_Position = uMVPMatrix * a_position;n"+
"v_texCoords = a_texCoords;" +
"}";
```

**Fragment Shader**

```
String strFShader =
"precision mediump float;" +
"uniform float opValue;"+
"varying vec2 v_texCoords;" +
"uniform sampler2D u_baseMap;" +
"void main()" +
"{" +
"gl_FragColor = texture2D(u_baseMap, v_texCoords);" +
"gl_FragColor *= opValue;"+
"}";
```

Please could someone explain any methods that are available to achieve this with some *code examples*, so I can try to understand how this is supposed to work? Or indeed if this *is* actually possible….?