openglfx
openglfx copied to clipboard
Animator frequency not honored
More render calls than necessary I am creating a GLCanvas with LWJGL and adding an animator with 30.0 as the FPS, but I am seeing no limit on draw calls. Is this intentional? I would expect no more than 30 render calls per second in this scenario but i am seeing upwards of 90 calls per second in my render code.
To Reproduce
GLCanvas canvas = new GLCanvas(LWJGL_MODULE, GLProfile.Compatibility, true, msaa, false);
canvas.setAnimator(new GLCanvasAnimator(30.0));
Environment:
- OS: W11
- openglfx version: 4.0.5
The canvas can also be updated when the size or visibility changes. Is any of this used?
The canvas is not currently resizing nor is its visibility changing. If it is relevant, I do have overlapping transparent boxes in the javafx application
hold on, more information incoming
Nevermind, apparently a resize is being invoked though the width and height are not changing... I guess i need to debug the JFX layout. That's my bad. Thank you.
Why is fixed fps so important? If it is used for movement, then it is better to use delta time from the render event.
I am optimizing resource usage so 90 FPS draw calls to the gpu would be troublesome. I may invent a little rate limit in the render code like
if(event.delta < (1/fps)) return;
btw. Resize on the JavaFX node is being invoked, but the reshape event is not as width and height are not actually changing
getChildren().add(canvas);
canvas.setManaged(true);
canvas.setLayoutX(0);
canvas.setLayoutY(0);
canvas.minHeightProperty().bind(heightProperty());
canvas.prefHeightProperty().bind(heightProperty());
canvas.maxHeightProperty().bind(heightProperty());
canvas.minWidthProperty().bind(widthProperty());
canvas.prefWidthProperty().bind(widthProperty());
canvas.maxWidthProperty().bind(widthProperty());
canvas.minHeightProperty().addListener((a,b,c)->{
canvas.minHeightProperty().get();
log.info("canvas resized");
});
This is still causing many extra resize calls to my render function. This "canvas resized" log is not being triggered. How does openGLFX sense resizes such that it is still attempting to render extra frame even though it is managed and thus should not change dimensions outside of these bindings which are not currently invalidating.
openglfx behaves just like any other element in javafx - it has a "dirty" state, which says it needs to be redrawn. It is set when the external parameters of the element are changed (size, visibility, etc.). Along with canvas rendering, opengl rendering is also called.
I plan to do a separate type of rendering without unnecessary draws, but that will come later.
Thank you! should i expect any internal issues using this style of workaround for now?
long lastDrawNano = System.nanoTime();
public void render(GLRenderEvent event) {
//simple rate limiting on render.
// resize events where WxH do not change so useless extra render calls are being invoked
if(System.nanoTime() < lastDrawNano + Duration.ofMillis((long) (1000/30.0)).toNanos())
return;
lastDrawNano = System.nanoTime();
...
Yes, you may get a blank screen when canvas was resized (fbo is recreating at this time) and you skipped the frame.
As a workaround for your workaround (lol) you can create a "double buffer" logic. Then you can print the second buffer instead of just skipping the frame.
or just don't let skipping when resizing was previously called