Well its time to start optimising my graphics, i’ve got my lights and objects rendering nice and pretty, but performance gets terribly slow when i attempt anything other than a tiny test level. And since i’m not sure whats going to be the best option, i’m asking for favoured methods to speed things up.
First stop: the profiler.
VecriptProfile.txt: Exclusive Method Times (CPU) (virtual times)
1923807 sun.awt.windows.WToolkit.eventLoop
540070 net.java.games.jogl.impl.windows.WGL.SwapBuffers
266499 com.vecript.math.ConvexHull2D.renderShadowHull
240943 java.lang.StrictMath.acos
197238 net.java.games.jogl.impl.windows.WindowsGLImpl.glBegin
110363 net.java.games.jogl.impl.windows.WindowsGLImpl.glVertex3f
79736 com.vecript.core.entity.PointLight.getPenumbraVector
69594 net.java.games.jogl.impl.windows.WindowsGLImpl.glColor4f
67792 com.vecript.core.entity.PointLight.getUmbraVector
61921 net.java.games.jogl.impl.windows.WindowsGLImpl.glTexCoord2f
38634 java.util.ArrayList.get
31694 com.vecript.core.entity.PointLight.getDisplacedCenter
21952 net.java.games.jogl.impl.windows.WindowsGLImpl.glBindTexture
21752 com.vecript.math.ConvexHull2D.renderSolid
19150 net.java.games.jogl.impl.windows.WindowsGLImpl.glEnd
18082 com.vecript.math.Vector2f.angle
13812 net.java.games.jogl.impl.windows.WindowsGLImpl.glDisable
11543 com.vecript.core.renderer.GameRenderer.drawGeometryPass
10276 com.vecript.math.ShadowFin.renderFin
9875 net.java.games.jogl.impl.windows.WindowsGLImpl.glEnable
7607 com.vecript.core.renderer.GameRenderer.mergeShadowHulls
7006 java.util.prefs.WindowsPreferences.windowsAbsolutePath
5338 java.util.prefs.WindowsPreferences.WindowsRegOpenKey
3603 java.util.prefs.WindowsPreferences.WindowsRegQueryValueEx
2602 net.java.games.jogl.impl.windows.WindowsGLImpl.glClear
2602 java.security.AccessController.doPrivileged
1802 com.vecript.core.renderer.GameRenderer.findVisibleLights
1735 com.vecript.core.renderer.GameRenderer.render
1735 com.vecript.core.Shader.bind
1535 com.vecript.core.DebugConsole.setFramesPerSecondText
1468 net.java.games.jogl.impl.windows.WindowsGLImpl.glLightfv
1468 com.vecript.math.Circle.renderLightAlpha
1401 java.lang.Thread.currentThread
1268 java.lang.Math.acos
1268 java.awt.image.ComponentColorModel.getDataElements
1201 java.lang.StringBuffer.<init>
1134 java.util.prefs.WindowsPreferences.toWindowsName
1068 java.lang.FloatingDecimal.dtoa
1068 java.lang.StringBuffer.toString
The above was grabbed with the -xprof options for the VM, and HP’s handy-dandy JMeter to extract the information. Now the most obvious here are the ConvexHull and PointLight methods, as well as immediate mode gl calls sticking out like a sore thumb. (Ignore .SwapBuffers, i’m running at ~16fps so thats probably a red herring).
At the moment the light and shadow rendering is the bottleneck, with the shadow geometry being built on the fly every frame and rendered in immediate mode. Shadow generation is quite lengthy, and at the moment is a brute force with no attempt to cull out any geometry. Rendering requires a z-fill & ambient pass, then a pass for every light.
Optimisations that spring to mind are:
[]Some sort of spatial tree. Pretty obvious since i should be able to cull both invisible geometry and geometry out of a lights range in each pass.
[]Getting rid of immediate mode in favor of something better. Plain old vertex arrays are probably going to be the best bet (no point caching results in vRam if they’re going to change all the time).
[]Some method of caching shadow geometry. Tricky, since every geometry-light pair has an associated shadow geometry. I can’t think of a good way to do this that actually sounds like it’d be faster.
[]Optimise my shadow geometry creation. Ugh, probably least favorite. The method is non-optimal in terms of new’d objects, but its some complicated maths that i don’t like the idea of obscurificating it…
[*]Something else?
Spatial tree sounds good, but its more the getting rid of immediate mode i’m worried about - how on earth do I create this geometry on the fly in a nice and efficiant manner? Have one big buffer and fill it up as needed? Shadow geometry is rendered half without textures and half using a single texture, would a buffer for each be a good idea? It seems like i’d have to make it much bigger than needed and waste memory to get something efficiant…
Any pointers appreciated