I am using the java.awt.Canvas class for drawing in my application and it simply does not seem to be fast enough. After filling my screen with some hand drawn math I get to a point where I am running at 70 fps and just rendering takes up about 90% of the time each frame. I wonder what I can do to spend less time drawing.
I have so far done the following to try and decrease the time needed to draw.
- I only draw what is visible on the screen(to compute what is visible does not take a significant amount of time). I have also confirmed it works as when I pan away from the lines my frame rate spikes to upwards of 4000 fps.
- I have implemented an algorithm to simplify paths(only computed once when I create a path). Interactive showcase of what it does: http://paperjs.org/examples/path-simplification/
This is the code which does the drawing.
def render(drawAbsolute: Graphics2D => Unit, drawFromCamera: Graphics2D => Unit, camera: Camera): Unit =
import java.awt.Color
var bs = getBufferStrategy
if (bs == null) {
createBufferStrategy(3)
bs = getBufferStrategy
}
val g2d = bs.getDrawGraphics().asInstanceOf[Graphics2D]
g2d.setRenderingHint(
java.awt.RenderingHints.KEY_ANTIALIASING,
java.awt.RenderingHints.VALUE_ANTIALIAS_ON
)
g2d.setColor(backgroundColor)
g2d.fillRect(Vector2.zero, canvasSize)
drawAbsolute(g2d) // this is fast because I am not drawing anything here atm :)
g2d.setTransform(camera.transform)
drawFromCamera(g2d) // This line takes up about 90% of the frame time. (Only draws a couple of hundred lines).
bs.show()
g2d.dispose()
Drawing code for my paths
override val shape: Shape = path2D
override def draw(g2d: Graphics2D): Unit =
g2d.draw(shape)
Also worth noting that not redrawing areas might be hard since the user is able to rotate and pan around. I guess that I could call a redraw function or something everytime the camera transform changes, I do feel however that it opens up a scary can of worms not redrawing everything everyframe and I will constantly have to think about.