Error"Attempt to re-set or change rendering thread

Hi all,

I want to display e.g 3 points in a Jpanel using jogl. But that’s not the problem! I tried to make them twinkle periodically using an animator which is started by pressing a start button. But everytime I press the button the following error occurrs:

net.java.games.jogl.GLException: Attempt to re-set or change rendering thread
at net.java.games.jogl.impl.GLContext.setRenderingThread(GLContext.java:238)
at net.java.games.jogl.GLCanvas.setRenderingThread(GLCanvas.java:148)
at net.java.games.jogl.Animator$1.run(Animator.java:89)
at java.lang.Thread.run(Thread.java:534)

the code implemented for the button is the following:

private void Start_ButtonActionPerformed(java.awt.event.ActionEvent evt)
{
opgl_Display1.startAnimator(1);
opgl_Display2.startAnimator(1);
setClearStat(false);


the code implemented for the listener is the following:

class listener implements GLEventListener
{
private int i;
ApplicationFrame applFrame;

public void setApplicationFrame(ApplicationFrame frame)
{
    this.applFrame = frame;
}


public void display(GLDrawable drawable)
{        
    GL gl = drawable.getGL();
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
            
    if ((i%2 == 0) && applFrame.getClearStat() == false)
    {
        //draw three points with various x- and y-coordinates
        gl.glBegin(GL.GL_POINTS);
        gl.glVertex2i(100,50);
        gl.glVertex2i(100,130);
        gl.glVertex2i(150,130);
        gl.glEnd();
        i++;
    }
    
    else if (applFrame.getClearStat() == false)
    {
        //draw two lines, each specified by various x- and y-coordinates
        gl.glColor3f(0.5f,0.6f,0.6f);
        gl.glBegin(GL.GL_LINES);
        gl.glVertex2i(50,200);
        gl.glVertex2i(75,250);
        gl.glVertex2i(60,200);
        gl.glVertex2i(85,250);
        gl.glEnd();
        i++;
    }
}

public void displayChanged(GLDrawable gLDrawable, boolean param, boolean param2)
{
}

public void init(GLDrawable drawable)
{
    GL gl = drawable.getGL();
    gl.glClearColor(1.0f,1.0f,1.0f,1.0f);
    gl.glColor3f(0.0f,0.0f,0.0f);
    gl.glPointSize(4.0f);
}

public void reshape(GLDrawable drawable, int left, int right, int width, int height)
{
    GL gl = drawable.getGL();
    GLU glu = drawable.getGLU();    //GLU OpenGl Utility Routines
    gl.glViewport(0,0,width,height);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();
    glu.gluOrtho2D(0.0,450.0,0.0,375.0);

    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
    
    //draw three points with various x- and y-coordinates
    gl.glBegin(GL.GL_POINTS);
    gl.glVertex2i(100,50);
    gl.glVertex2i(100,130);
    gl.glVertex2i(150,130);
    gl.glEnd();
    
     //draw two lines, each specified by various x- and y-coordinates
    gl.glColor3f(0.5f,0.6f,0.6f);
    gl.glBegin(GL.GL_LINES);
    gl.glVertex2i(50,200);
    gl.glVertex2i(75,250);
    gl.glVertex2i(60,200);
    gl.glVertex2i(85,250);
    gl.glEnd();
} 

}

Can somebody please tell me what possibly can cause this error?

Thanks a lot

Greetings Samson

What is opgl_Display1 & opgl_Display2? and what does your code for startAnimator look like? and how do you create the Animator? Are the two animators pointing to the same GLDrawable?

Also, why are you drawing in your reshape method? I am pretty sure JOGL doesn’t swap buffers after the reshape method, and JOGL will call your display method after your reshape method which will clear everything that you just drew.

Hi milvich,
thanks for your fast reply.

Here are the answers to your questions:

1.) opgl_Display1

opgl_Display1 is an instance of the class “OpenGLCanvas_Display1” which extends Canvas. It’s the container where I display the OpenGL objects.

2.) code for startAnimator():

public void startAnimator(int i)
{
fpsanimator = new FPSAnimator(canvas1,60,exceptionHandler);
exceptionHandler.setFPSAnimator(fpsanimator);
switch (i)
{
case 1:
{
try
{
fpsanimator.start();
Statuszeile_Label.setText(“Animator started”);
Statuszeile_Panel.setBackground(Color.GREEN);
}
catch (Exception e)
{
exceptionHandler.handleException(e);
}
}
case 2:
{
animator = new Animator(canvas1);
animator.start();
}
}
}

The FPSAnimator is implemented as follows:

import net.java.games.jogl.Animator;
import net.java.games.jogl.GLDrawable;
import net.java.games.jogl.GLException;

import java.util.Timer;
import java.util.TimerTask;

public class FPSAnimator extends Animator {
private GLDrawable drawable;
private RenderRunnable runnable = new RenderRunnable();
private Thread thread;
private boolean shouldStop;
private long delay;
private Timer renderTimer;
private ExceptionHandler exceptionHandler;

public FPSAnimator(GLDrawable drawable, int fps) {
    this(drawable, fps, null);
}

/** Creates a new Animator for a particular drawable. */
public FPSAnimator(GLDrawable drawable, int fps, ExceptionHandler exceptionHandler) {
    super(drawable);
    this.exceptionHandler = exceptionHandler;
    this.drawable = drawable;
    this.delay = 1000 / fps;
}

/** Starts this animator. */
public synchronized void start() {
    if (thread != null) {
        throw new GLException("Already started");
    }
    thread = new Thread(runnable);
    thread.start();

    renderTimer = new Timer();
    renderTimer.schedule(new TimerTask() {
        public void run() {
            runnable.nextFrame();
        }
    }, 0, delay);
}

/** Stops this animator, blocking until the animation thread has
 finished. */
public synchronized void stop() {
    shouldStop = true;
    while (shouldStop && thread != null) {
        try {
            wait();
        } catch (InterruptedException e) {
        }
        renderTimer.cancel();
    }
}

public boolean isFrameRateLimitEnabled() {
    return runnable.isFrameRateLimitEnabled();
}

public void setFrameRateLimitEnabled(boolean frameRateLimit) {
    runnable.setFrameRateLimitEnabled(frameRateLimit);
}

private class RenderRunnable implements Runnable {
    private boolean frameRateLimitEnabled = true;

    public boolean isFrameRateLimitEnabled() {
        return frameRateLimitEnabled;
    }

    public void setFrameRateLimitEnabled(boolean frameRateLimit) {
        frameRateLimitEnabled = frameRateLimit;
        nextFrameSync();
    }

    public void nextFrame() {
        if (frameRateLimitEnabled)
            nextFrameSync();
    }

    private synchronized void nextFrameSync() {
        notify();
    }

    public void run() {
        boolean noException = false;
        try {
            // Try to get OpenGL context optimization since we know we
            // will be rendering this one drawable continually from
            // this thread; make the context current once instead of
            // making it current and freeing it each frame.
            drawable.setRenderingThread(Thread.currentThread());

            // Since setRenderingThread is currently advisory (because
            // of the poor JAWT implementation in the Motif AWT, which
            // performs excessive locking) we also prevent repaint(),
            // which is called from the AWT thread, from having an
            // effect for better multithreading behavior. This call is
            // not strictly necessary, but if end users write their
            // own animation loops which update multiple drawables per
            // tick then it may be necessary to enforce the order of
            // updates.
            drawable.setNoAutoRedrawMode(true);

            while (!shouldStop) {
                noException = false;
                drawable.display();
                if (frameRateLimitEnabled) {
                    synchronized (this) {
                        if (frameRateLimitEnabled) {
                            try {
                                wait();
                            } catch (InterruptedException e) {
                            }
                        }
                    }
                }
                noException = true;
            }
        } catch (Exception e) {
            if (exceptionHandler != null)
                exceptionHandler.handleException(e);
        } finally {
            shouldStop = false;
            drawable.setNoAutoRedrawMode(false);
            try {
                // The surface is already unlocked and rendering
                // thread is already null if an exception occurred
                // during display(), so don't disable the rendering
                // thread again.
                if (noException) {
                    drawable.setRenderingThread(null);
                }
            } finally {
                synchronized (FPSAnimator.this) {
                    thread = null;
                    FPSAnimator.this.notify();
                }
            }
        }
    }
}

}

3.) I don’t think that the animators point to the same GLDrawable. But I’m not sure.

4.) Forget about the reshape method. I just tried something. It’s not important :slight_smile:

Thanks for trying to help me!

Greetings Samson

The first thing I saw, is that you don’t have any break statements in your switch block. So you are “falling” through the case statements and making both the fps annimator and the normal annimator.

Your switch statement should look something like this:


switch(i)
{
  case 1:
     // create fps annimator
     break;
  case 2:
     // create normal annimator
     break;
}

Thanks a lot milvich !

That was the problem. But I’m sure it won’t be the last :slight_smile: