Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8756907
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T14:10:54+00:00 2026-06-13T14:10:54+00:00

I’m drawing about 30 – 80 textured planes (squares) – backgrounds, player, enemies, bullets,

  • 0

I’m drawing about 30 – 80 textured planes (squares) – backgrounds, player, enemies, bullets, etc.
All planes move and scale, some +rotate and some have animated textures.

I think, it can’t be too hard for CPU or GPU, but on slower/older devices it has relative low performance – for example on Galaxy ACE.

Please, Can you look my code, what am I doing wrong or dirty? Or what can be optimalized?

Thank you.

This is my onSurfaceCreated, onSurfaceChanged and onDrawFrame:

public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { 
  ..
  // load and prepare all textures 
  ..

  GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  
  GLES20.glEnable(GLES20.GL_CULL_FACE);             
  GLES20.glDisable(GLES20.GL_DEPTH_TEST);       
  GLES20.glEnable(GLES20.GL_TEXTURE_2D);            

  GLES20.glDisable(GL10.GL_DITHER);
  GLES20.glDisable(GL10.GL_LIGHTING);
  final float eyeX = 0.0f; final float eyeY = 0.0f; final float eyeZ = 1.5f;       
  final float lookX = 0.0f; final float lookY = 0.0f; final float lookZ = -3.0f;
  final float upX = 0.0f; final float upY = 1.0f; final float upZ = 0.0f;
  Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);  

  mProgramHandle = GLES20.glCreateProgram();    

  final String vertexShader =
  "uniform mat4 u_MVPMatrix;         \n"                       
  + "attribute vec4 a_Position;      \n"                            
  + "attribute vec2 a_TexCoordinate; \n"    
  + "attribute float a_AlphaValue;   \n"
  + "varying vec2 v_TexCoordinate;   \n"            
  + "varying float v_AlphaValue;     \n"
  + "void main()                     \n"                                
  + "{                               \n"                          
  + "   v_TexCoordinate = a_TexCoordinate;      \n"  
  + "   v_AlphaValue = a_AlphaValue;            \n"
  + "   gl_Position = u_MVPMatrix * a_Position; \n"
  + "}                                          \n";        

  final String fragmentShader =
  "precision lowp float;                \n"         
  + "uniform sampler2D u_Texture;       \n"     
  + "varying vec2 v_TexCoordinate;      \n"     
  + "varying float v_AlphaValue;        \n"             
  + "void main()                        \n"     
  + "{                                  \n"
  + "   gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n"             
  + "   gl_FragColor.a *= v_AlphaValue; \n"
  + "}                                  \n";            

  final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);     
  final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);       
  mProgramHandle = ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, new String[] {"a_Position", "a_TexCoordinate", "a_AlphaValue"});

  GLES20.glUseProgram(mProgramHandle);  
  mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
  mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
  mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
}   

public void onSurfaceChanged(GL10 glUnused, int width, int height) {    
  GLES20.glViewport(0, 0, width, height);
  float ratio = (float) width / height;
  Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 1, 1000);
}   

public void onDrawFrame(GL10 glUnused) {
  GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
  GLES20.glEnable(GLES20.GL_BLEND); 
  GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
  updateGame();

  // all planes are saved in Vector<Mesh> children          
  int size = children.size();
  for (int i = 0; i < size; i++)
  {
    children.get(i).Draw(renderer);
  }
}

And Draw(Renderer) in ‘plane’ object:

public void Draw(Renderer renderer)
{                       
  if (!Visible) return; // no visible object, no need draw
  mTextureCoordinateHandle = GLES20.glGetAttribLocation(renderer.mProgramHandle, "a_TexCoordinate");
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBrickDataHandle); 
  mAlphaHandle = GLES20.glGetAttribLocation(renderer.mProgramHandle, "a_AlphaValue");       
  GLES20.glVertexAttrib1f(mAlphaHandle, alpha);

  // texture animation
  renderer.mPlaneTextureCoords[(byte)indexAnim].position(0); 
  GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0, renderer.mPlaneTextureCoords[(byte)indexAnim]);
  indexAnim++;

  renderer.mPlanePositions.position(0); 
  GLES20.glVertexAttribPointer(Renderer.mPositionHandle, renderer.mPositionDataSize, GLES20.GL_FLOAT, false, 0, renderer.mPlanePositions);        
  GLES20.glEnableVertexAttribArray(Renderer.mPositionHandle);                       

  if (angleZ == 0) // no rotating plane -> no need setRotateM
  {
    Matrix.setIdentityM(renderer.mModelMatrix, 0);
    Matrix.translateM(renderer.mModelMatrix, 0, x, y, z);
    Matrix.scaleM(renderer.mModelMatrix, 0, scaleX, scaleY, 1);
  }
  else // rotating plane
  {
    float[] mt = new float[16];
    Matrix.setIdentityM(mt, 0);
    Matrix.translateM(mt, 0, x, y, z);
    Matrix.scaleM(mt, 0, scaleX, scaleY, 1);
    Matrix.setRotateM(mRotZMatrix, 0, angleZ, 0, 0, 1);
    Matrix.multiplyMM(renderer.mModelMatrix, 0, mt, 0, mRotZMatrix, 0);
  }

  Matrix.multiplyMM(renderer.mMVPMatrix, 0, renderer.mViewMatrix, 0, renderer.mModelMatrix, 0);   
  GLES20.glUniformMatrix4fv(renderer.mMVMatrixHandle, 1, false, renderer.mMVPMatrix, 0);                

  //Matrix.multiplyMM(renderer.mMVPMatrix, 0, renderer.mProjectionMatrix, 0, renderer.mMVPMatrix, 0);
  Matrix.multiplyMM(renderer.mTemporaryMatrix, 0, renderer.mProjectionMatrix, 0, renderer.mMVPMatrix, 0); // little bit faster (?)
  System.arraycopy(renderer.mTemporaryMatrix, 0, renderer.mMVPMatrix, 0, 16);

  GLES20.glUniformMatrix4fv(renderer.mMVPMatrixHandle, 1, false, renderer.mMVPMatrix, 0); // pass in the combined matrix
  GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);        
  GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);  
}   
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T14:10:55+00:00Added an answer on June 13, 2026 at 2:10 pm

    If you’re running on a newer version of the Android SDK (e.g. v16) you can use the profiler to find out where the problem areas are:

    http://developer.android.com/tools/debugging/debugging-tracing.html

    But at first glance there are a couple of things I can see:

    1. Another responder highlighted that you are calling glGetAttribLocation inside your draw call, you don’t need to do this every time you draw. Once the “program” is set these references can be obtained and they won’t change as long as that program doesn’t change (i.e you don’t change shaders). Likewise with the calls to glEnableVertexAttribArray

    2. Consider using a texture atlas. Each call to glBindTexture may result in a state change in VRAM which is a slow operation. A texture atlas is simply a single image which contains all (or many) or your textures (e.g. sprites). When you specify the texture coordinates you simply specify a value between 0 and 1 representing the location of your single sprite within the atlas. If you want to use this approach you will have to “bin pack” your atlas so you’re not wasting space. There are a few tools out there to do this (eg TexturePacker). This means fewer (possibly only one) calls to glBindTexture

    3. You’re passing your MVP matrix twice with glUniformMatrix4fv which is unnecessary. Changing the matrix that is sent to the shader after it’s been sent will have no effect (i.e. the initial set operation will be overwritten) as the matrix is only used when the shader executes in the call to glDrawArrays

    4. I have recently discovered that setRotateM is pretty damn slow. There are alternatives around the place which I need to find also!

    5. Your last System.arrayCopy is unnecessary. You can just chain the matrix multiplication without needing the temp. matrix. Model * View = MV, then MV * Projection = MVP

    If you haven’t already you should also check out this tutorial:

    http://www.learnopengles.com/android-lesson-one-getting-started/

    And if you DO decide to go down the route of a 3rd party game engine, IMO libgdx is by FAR the best:

    http://libgdx.badlogicgames.com/

    It’s free, open source and has a strong focus on performance. Having said that I too decided to build my own because I didn’t need the breadth of features offered by libgdx but I have to say that every line of code I write makes me stop and question this decision 😉

    Good luck.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
this is what i have right now Drawing an RSS feed into the php,
I am reading a book about Javascript and jQuery and using one of the
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have a text area in my form which accepts all possible characters from
I don't have much knowledge about the IPv6 protocol, so sorry if the question
I have a .ini file as follows: [playlist] numberofentries=2 File1=http://87.230.82.17:80 Title1=(#1 - 365/1400) Example
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.