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 8784077
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T20:59:43+00:00 2026-06-13T20:59:43+00:00

Trying to setup a game loop thread for a test animation, I have come

  • 0

Trying to setup a game loop thread for a test animation, I have come across a few problems. There are errors shown during start up and the Android program runs through the splash screen, but then terminates. This is the red highlighted Logcat error.

09-24 16:09:18.731: E/AndroidRuntime(569): FATAL EXCEPTION: GLThread 76
09-24 16:09:18.731: E/AndroidRuntime(569): java.lang.NullPointerException
09-24 16:09:18.731: E/AndroidRuntime(569):  at 
com.spacewrecksoftware.iceward.GLrenderer.onSurfaceCreated(GLrenderer.java:22)
09-24 16:09:18.731: E/AndroidRuntime(569):  at 
android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1446)
09-24 16:09:18.731: E/AndroidRuntime(569):  at 
android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)

This program creates a texture that moves back and forth on a landscape screen with a test implementation of interpolation rendering for smoother animation at higher frame rates.
Here is the gameloop, renderer, menu, object, and state files in that order.

GameLoop:

import android.os.SystemClock;

public class GameLoop extends Thread {
public static int deltaTime;
boolean gameRunning = true;
public void setRunning(boolean running) {
    this.gameRunning = running;
}
public ObjectState previous= new ObjectState(0, 0, 10/1000, 0);
public ObjectState current= new ObjectState(0, 0, 10/1000, 0);
public Globject button= new Globject(previous, current);
public void run() {

    int ticksPerSec = 30;
    int skipTicks = 1000 / ticksPerSec;
    int maxFrameskip = 5;
    long nextGameTick = SystemClock.uptimeMillis();
    int loops;
    long interpolation;
    long oldTimeSinceStart = 0;

    while (gameRunning) {


        loops = 0;
        while( SystemClock.uptimeMillis() > nextGameTick & loops < maxFrameskip){
            long timeSinceStart = SystemClock.uptimeMillis();
              deltaTime = (int) (timeSinceStart - oldTimeSinceStart);
             oldTimeSinceStart = timeSinceStart;
            updateGame();
             nextGameTick += skipTicks;
                loops++;
            }
        interpolation = SystemClock.uptimeMillis() + skipTicks - nextGameTick 
                /  skipTicks ;
        drawGame(interpolation);
    }
}
int switchit = 1;
private void updateGame() {
    if (switchit==1){   
        if (button.now.position_x<=-10){        
             switchit=0;
             button.past.velocity_x=0-button.past.velocity_x;
        }
        else{
    button.past=button.now.copy(button.now);
    button.now=button.past.addDt(button.past, deltaTime);
        }
    }
    else if(switchit==0){   
        if (button.now.position_x>=10){     
             switchit=1;
             button.past.velocity_x=0-button.past.velocity_x;
        }
        else{
            button.past=button.now.copy(button.now);
            button.now=button.past.addDt(button.past, deltaTime);
        }
    }

}
private void drawGame(float interpolation) {
    button.past=button.past.interpolate(button.past, button.now, interpolation);
    Menu.menuSurface.requestRender();

}
}

Renderer:

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;


public class GLrenderer implements Renderer {

private Globject object1;   
private Context context;
long startTime;
public GLrenderer(Context context) {
    this.context = context;
    object1 = new Globject(null, null);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {       
    //Load the texture for the cube once during Surface creation
    object1.now.position_x=0;
    object1.past.position_x=0;
    object1.loadGLTexture(gl, this.context);
    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
    gl.glEnable(GL10.GL_TEXTURE_2D);            //Enable Texture Mapping
    gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
    gl.glClearColor(0.0f, 0.666f, 0.831f, 1f); 
    gl.glClearDepthf(1.0f);                     //Depth Buffer Setup
    gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
    gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
}
/**
 * Here we do our drawing
 */
public void onDrawFrame(GL10 gl) {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
    gl.glLoadIdentity();        

    gl.glTranslatef(0.0f, 0.0f, -20f);  
    gl.glPushMatrix();
    gl.glTranslatef( object1.past.position_x, 0, 0);    
    object1.draw(gl);
    gl.glPopMatrix();

}

/**
 * If the surface changes, reset the view
 */
public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0) {                       //Prevent A Divide By Zero By
        height = 1;                         //Making Height Equal One
    }

    gl.glViewport(0, 0, width, height);     //Reset The Current Viewport
    gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix
    gl.glLoadIdentity();                    //Reset The Projection Matrix

    //Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
    gl.glLoadIdentity();                    //Reset The Modelview Matrix
}
}

Menu:

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class Menu extends Activity
{
static GLSurfaceView menuSurface;
private GameLoop thread;
@Override
public void onCreate(Bundle savedInstanceState) 
{

    super.onCreate(savedInstanceState);
    menuSurface = new GLSurfaceView(this);
        menuSurface.setRenderer(new GLrenderer(this));
        menuSurface.setRenderMode(0);
    setContentView(menuSurface);
    thread = new GameLoop();
    thread.setRunning(true);
    thread.start();
}

@Override
protected void onResume() 
{
    super.onResume();
    menuSurface.onResume();
}

@Override
protected void onPause() 
{   
    super.onPause();
    menuSurface.onPause();
}   
public boolean onTouchEvent(MotionEvent event) {
            return super.onTouchEvent(event);   
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
    try {
        thread.join();
        retry = false;
    } catch (InterruptedException e) {
        // try again shutting down the thread
    }
}
}
}

Object: note-the image is a power of 2, four by one texture.

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;

public class Globject {

private FloatBuffer vertexBuffer;

private FloatBuffer textureBuffer;

private ByteBuffer indexBuffer;


private int[] textures = new int[1];
public ObjectState past;
public ObjectState now;

private float vertices[] = {
                    //Vertices according to faces
                    -4.0f, 1.0f,  //Vertex 0
                    -4.0f, -1.0f,  //v1
                    4.0f, 1.0f,   //v2
                    4.0f, -1.0f   //v3

                                        };

/** The initial texture coordinates (u, v) */   
private float texture[] = {         
                    //Mapping coordinates for the vertices  
                    0.0f, 0.0f,
                    0.0f, 1.0f,             
                    1f, 0.0f,
                    1f, 1.0f


                                        };

/** The initial indices definition */   
private byte indices[] = {

        0,1,2,3             
                                        };

public Globject(ObjectState past2,ObjectState now2) {

    now=now2;
    past=past2;

    ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    vertexBuffer = byteBuf.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    //
    byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuf.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);

    //
    indexBuffer = ByteBuffer.allocateDirect(indices.length);
    indexBuffer.put(indices);
    indexBuffer.position(0);
}

public void draw(GL10 gl) {
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    //Point to our buffers
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    //Set the face rotation
    gl.glFrontFace(GL10.GL_CW);

    //Enable the vertex and texture state
    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

    //Draw the vertices as triangles, based on the Index Buffer information
    gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);

    //Disable the client state before leaving
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

public void loadGLTexture(GL10 gl, Context context) {
    //Get the texture from the Android resource directory
    InputStream is = context.getResources().openRawResource(R.drawable.custom_button1);
    Bitmap bitmap = null;
    try {
        bitmap = BitmapFactory.decodeStream(is);

    } finally {
        //Always clear and close
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }
    }

    //Generate one texture pointer...
    gl.glGenTextures(1, textures, 0);
    //...and bind it to our array
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    //Create Nearest Filtered Texture
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

    //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

    //Clean up
    bitmap.recycle();
}   
}

State:

public class ObjectState {
public float position_x;
public float position_y;
public float velocity_x;
public float velocity_y;
public ObjectState(float position_x2, float position_y2, float velocity_x2, float velocity_y2) {
    position_x = position_x2;
    position_y = position_y2;
    velocity_x = velocity_x2;
    velocity_y = velocity_y2;
}
public ObjectState copy(ObjectState state0) {
ObjectState state1= new ObjectState(state0.position_x, state0.position_y,
        state0.velocity_x, state0.velocity_y);
return state1;
}  
public ObjectState subtract(ObjectState state, ObjectState state1){
    ObjectState  state2=state.copy(state);
    state2.position_x=(state1.position_x-state.position_x);
    state2.position_y=(state1.position_y-state.position_y);
    state2.velocity_x=(state1.velocity_x-state.velocity_x);
    state2.velocity_y=(state1.velocity_y-state.velocity_y);
return state2;
}
public ObjectState addDt(ObjectState state, int deltaTime){
    ObjectState  state1=state.copy(state);
    state1.position_x=(state1.velocity_x*deltaTime)+state1.position_x;
    state1.position_y=(state1.velocity_y*deltaTime)+state1.position_y;
return state1;
}
public ObjectState interpolate(ObjectState state, ObjectState state2,float interpolate){
    ObjectState  state1=state.copy(state);
    state1.position_x=(state1.subtract(state2, state).position_x*interpolate)+state.position_x;
    state1.position_y=(state1.subtract(state2, state).position_y*interpolate)+state.position_y;
    state1.velocity_x=(state1.subtract(state2, state).velocity_x*interpolate)+state.velocity_x;
    state1.velocity_y=(state1.subtract(state2, state).velocity_y*interpolate)+state.velocity_y;
return state1;
}
}

I haven’t been able to find a problem, help would be much appreciated! Thanks!

  • 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-13T20:59:44+00:00Added an answer on June 13, 2026 at 8:59 pm

    This is a null pointer exception.

    In your GLrenderer constructor you have the following:

    object1 = new Globject(null, null);
    

    In your GLobject code:

    public Globject(ObjectState past2,ObjectState now2) {
    
        now=now2;
        past=past2;
        //...
    

    Then back to GLRenderer you have:

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {       
        //Load the texture for the cube once during Surface creation
        object1.now.position_x=0;
        object1.past.position_x=0;
    

    now, and past are still null. They need to be assigned before being accessed.

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

Sidebar

Related Questions

I'm trying to setup a wee scratch card game, where there are several panels
I have been trying to setup git for our web development team unsuccessfully. Some
I have a simple iPhone game consisting of two threads: the main game loop
I am trying to run a Walk style animation on my main game sprite.
I am currently trying to make a game in Android. I have this piece
For the past few days, I have been trying to figure out how to
I'm trying setup a Rails app that will be something like a game. The
I have been thinking of trying out component based architecture for game development. I
I have a cocos2d game setup which uses basic inheritance setup which is similar
I have an iPhone game that I'm trying to create for school, yet I'm

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.