Not understanding the resizing behaviour of OpenGL

Hello all !

This isn’t specifically a coding question, but more an attempt at understanding how OpenGL manages resizing. Firstly:

Does OpenGL display the panel continuously while resizing ?

My first experience is that no, since with this very simple code, the panel is cleared only when resizing stops (when I stop moving my mouse to resize). I also thought of the glViewport function but apparently running it inside of the reshape override doesn’t change anything, so I guess that the viewport is resized automatically…

Simple resizing code (in Java JOGL, a wrapper that should behave exactly as OpenGL)

Main.java

public class Main {
	public static void main(String[] args) {
		@SuppressWarnings("unused")
		Frame frame = new Frame(1280, 720);
	}
}

Frame.java

import javax.swing.JFrame;

import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLJPanel;

public class Frame extends JFrame{
	
	public static GLProfile PROFILE;
	public static GLCapabilities CAPABILITIES;
	public static GLJPanel panel;
	public static PanelListener listener;
	
	public Frame(int width, int height) {
		super();

		PROFILE = GLProfile.get(GLProfile.GL2);
		CAPABILITIES = new GLCapabilities(PROFILE);
		
		CAPABILITIES.setSampleBuffers(true);
		CAPABILITIES.setNumSamples(8);
		CAPABILITIES.setStencilBits(8);
		CAPABILITIES.setDoubleBuffered(true);
		CAPABILITIES.setPBuffer(true);
		
		panel = new GLJPanel(CAPABILITIES);
		listener = new PanelListener(panel);
		panel.addGLEventListener(listener);
		
		this.setContentPane(panel);
		
		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(width, height);
		
		run();
	}
	
	public void run() {
		while(true) {
			
			panel.display();
			
			try {Thread.sleep(1);}
			catch (InterruptedException e) {e.printStackTrace();}
		}
	}
}

PanelListener.java

import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.awt.GLJPanel;

public class PanelListener implements GLEventListener{
	
	GLJPanel panel;
	GL2 gl;
	
	public PanelListener(GLJPanel panel) {
		super();
		this.panel = panel;
	}

	@Override
	public void display(GLAutoDrawable displayable) {
		gl.glClearColor(1f, 1f, 1f, 1f);
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
	}

	@Override
	public void dispose(GLAutoDrawable displayable) {
		
	}

	@Override
	public void init(GLAutoDrawable displayable) {
		gl = displayable.getGL().getGL2();
        
        gl.glEnable(GL2.GL_LINE_SMOOTH);
        gl.glEnable(GL2.GL_POINT_SMOOTH);
        gl.glEnable(GL2.GL_SMOOTH);

        gl.glDrawBuffer(GL.GL_FRONT_AND_BACK);
        gl.glEnable(GL.GL_MULTISAMPLE);
        
		gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_FASTEST);
		gl.glHint(GL2.GL_POINT_SMOOTH_HINT, GL2.GL_NICEST);
		
		gl.glShadeModel(GL2.GL_SMOOTH);
		
        gl.glEnable(GL2.GL_BLEND);
        gl.glBlendFuncSeparate(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA, GL2.GL_ONE, GL2.GL_ONE);
        
        gl.glEnable(GL2.GL_TEXTURE_2D);
        
		gl.glClearColor(0.3f, 0.3f, 0.3f, 1f);
		gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);
	}

	@Override
	public void reshape(GLAutoDrawable displayable, int x, int y, int w, int h) {
	}
}

My issue now comes from the following realization : if I then manually resize the panel to be really small (my experimentations seem to yield a size a bit larger than 130x88 pixels), after this point EVERY TIME I resize the panel (not just this time) it seems to be resized continuously, although if the panel is then set to the exact same size as before, exactly the same code is ran, but the behaviour is still different. My second question is therefore :

Is there anything that is done if the panel is reshaped to a sufficiently small size that may cause this shift to happen ?

If so, is there a way to force this behaviour from the start/to block it from happening in the future ?

My main need was to actually have the panel displayed continuously through resizing, but calling panel.display() while redrawing seems to result in a call to GLEventListener.display() only if not currently resizing, and if the panel hasnt been resized to the small size mentionned before… Which doesn’t make sense to me.

EDIT : Just to make sure that it wasn’t Java or the Swing library causing the issue, I made the same application as shown before in pure Swing and resizing is definitely continuous, so I really think that this issue is caused by OpenGL.

Thanks for your help !

This isn’t an OpenGL question. It’s a question about your platform’s window resizing behavior and how that’s exposed to applications (though the language and window system libraries you’re making use of).

In some window systems, continuous resize events are sent to the app window. In others, only one resize event is provided at the end. In some window systems this is configurable; in others not.

Separate from how often your application receives resize events is what your app chooses to do with them. It can redraw or not. There may also be some window system behavior layered on to resize the previous window contents or consider them destroyed.

Bottom line is that you need to get your head around how your platform’s window system handles resizes, and how applications can react to those resize events. OpenGL is just a slave in all this. Your app tells it when to render to framebuffers and what state to render with.

1 Like

hi @r-jaoui
I’m not the right one to answer, but I recall the same kind of problem.
I don’t know your setup but, on my part, I have sat up a loop that I can control.
I use a wait-timeout with a high value when no swap is needed.
The loop calls
poll_events and
swap_buffers.
On resizing, the loop is not called, and no drawing happens. So, I’ve moved some code to the resize_window_callback (including swap_buffers and some matrixes).

Maybe you can use this for your further debugging.

1 Like

I understand that, this is why I tried recreating the app in pure Swing as this is the library used to manage the OpenGL Frame, Panel… And in this case I noticed that in fact resizing was continuous (the call to the resize callback as well as any call to the rendering method for the Panel…)

I also noticed that weirdly, both the reshape function and the display function are apparently still called while redrawing, but that no OpenGL rendering calls work (I saw this by both writing to the console inside the display() function and by rendering a random colored rectangle, that would therefore change to a random color at each frame). While resizing, the display() console message is still printed but the screen isn’t redrawn and the rectangle stays a single color in the meantime… This is why it really looks like the fact that no OpenGL rendering function seem to work while redrawing.

I made a quick video that may help to understand the issue, notice that both the reshape and display functions are still called when resizing : https://www.youtube.com/watch?v=SgL8lzNJ1ik

This may be where this breaks, but this may be a Swing issue then :cry: . And in either case, in a pure Swing application, redrawing is continuous while resizing so it doesn’t make sense why with the JOGL library this would break.

Thanks for your help

I do have a main loop, but it doesn’t use any wait-timeout behaviour. And also as I’ve just answered to @Dark_Photon :

So I don’t think that the issue is that these functions aren’t called, but that the OpenGL rendering functions don’t work while redrawing…

Maybe this?:

https://coderanch.com/t/459664/java/components-won-display-window-resized

Sorry. I’m not much help with Java Swing. I don’t really work in Java and it’s been years since I even played with it a bit.

1 Like

Thanks for the response.

So this is what I tried :

This is why I really dont think that the Swing environment is at fault.

  • For one, the reshape and display functions are called when resizing, even if the screen isn’t actually displayed (which means that the rendering functions aren’t functionnal, not the callbacks).
  • Secondly, the fact that after resizing to a small frame and then making it the same size again, it works as I want it to, tells me that it should be able to work and that it has to do with the state of the Frame or something…

Anyways, if you think that this is a Swing issue and that this is out of topic for this forum perhaps I could add a question to StackOverflow, but I don’t think it’s Swing that is causing this. Is there anything that can cause the display function to be called while no gl rendering method is callable ?

Thanks to both of you for your help, I’ll keep digging :slight_smile:

This isn’t an OpenGL question, it’s a toolkit question.

OpenGL isn’t involved in event processing. OpenGL doesn’t have any concept of a “display function” or “reshape function”. OpenGL functions queue commands to be executed on the current context. Managing windows, managing contexts, and swapping buffers are up to the application (usually via a GUI toolkit).

1 Like

Alright, I’ll post this question in the JOGL forum then, since this is the library that is responsible for all this.

Thanks for your help :slight_smile: