yellowstonegames / SquidLib

Useful tools for roguelike, role-playing, strategy, and other grid-based games in Java. Feedback is welcome!
Other
448 stars 46 forks source link

libgdx vs old style artifacts and erasing discussion #166

Closed SquidPony closed 7 years ago

SquidPony commented 7 years ago

While erase() now is much faster than Swing squidlib it seems that the entire screen has to be redrawn every render update. This seems to be trading an occasional expensive operation for a guaranteed expensive operation all the time.

In the old days one had to manage only those parts which changed on each panel, which in many cases is not much. Now I have to rebuild my display every frame, which means most likely caching off a simplified view as well as tracking the backing data. This sort of cached information management would ideally be handled by the library.

I'm curious as to whether I'm just missing something here, and if not then why is it this way now?

SquidPony commented 7 years ago

Well I guess it must be caching something since not everything goes away. I'm confused to what gets cleared by the libgdx render loop and what doesn't I guess.

tommyettinger commented 7 years ago

Using erase() isn't always necessary. Since SquidLayers and the SquidPanel widgets it contains will have the same contents and colors, if you don't call erase() and replace the contents they should stay the same. That said, things like mouseover-for-path highlighting should be removed each frame, since they can change very frequently while the mouse is moving. Any animations, like the Perlin noise used for waves in water, will also need to be at least updated, though not necessarily erased fully. I think in the demos I use erase() because I don't know precisely what tiles will need to be updated (due to FOV, mouse path, and animations), and tracking those individually wouldn't be especially clear for a demo. The libGDX Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); code clears the screen entirely in the color specified earlier (or black, I think), and then when the Stage is drawn with someStage.draw() it fills the parts of the screen that are covered by any widget added to the Stage by calling draw() on those widgets. The draw() call for SquidLayers draws its SquidPanel items in order from back to front. The draw() call for SquidPanel draws all chars in their foreground colors, also tracking highlighting as a modifier to that color. If you don't call erase(), then the colors and chars stay the same as in the last frame, including temporary things like highlighted paths.

Redrawing the screen should not be considered an expensive operation, but an important one. As I understand it, you work with people who are probably trying to get 60 redraws of the screen every second, on potentially large displays. Logic to track every cell's updating status seems like a tremendous hassle and easy to get wrong... There are ways I can see to do it, but they don't seem much faster than just avoiding erase() and having your code re-write things that you know are changing.

Leaving this open for comment.

SquidPony commented 7 years ago

That all makes sense, thanks for the detailed explanation.

I think the SqiudLayers vs SquidPanel was the bit that I was missing in the chain of how things happen.