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

| | August 8, 2015

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);

}
``````

``````    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;" +
"}";
``````

``````    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….?

• ### How To Submit a iPhone App to the Appstore

by on July 5, 2012 - 0 Comments

The process to develop an iPhone app is not as hard as one might think. The entry into the app store has been opened up to many new types of develope...

• ### Develop iphone Apps on Windows

by on March 7, 2011 - 13 Comments

Top 10 Ways to Develop an iphone/ipad app without a Mac #1. Code in Java For Java developers, there is a workaround: XMLVM. XMLVM cross-compiles byte...

• ### Iphone Android App Ideas: Getting Started

by on March 19, 2011 - 3 Comments

Smartphone Application Ideas: Getting Started Smartphone application developers are constantly on the move. And since overzealous developers stick ...