Skip to content

Commit

Permalink
Fix performance issue of the ae2 visualistation tool (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexdoru authored Nov 28, 2024
1 parent 3d3d493 commit b017465
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package net.bdew.ae2stuff.items.visualiser
import net.bdew.ae2stuff.misc.{OverlayRenderHandler, WorldOverlayRenderer}
import net.bdew.ae2stuff.network.{MsgVisualisationData, NetHandler}
import net.bdew.lib.Client
import net.minecraft.client.renderer.Tessellator
import org.lwjgl.opengl.GL11

object VisualiserOverlayRender extends WorldOverlayRenderer {
Expand All @@ -32,182 +33,190 @@ object VisualiserOverlayRender extends WorldOverlayRenderer {
needListRefresh = true
}

def setColor(rgb: (Double, Double, Double), mul: Double): Unit = {
GL11.glColor3d(rgb._1 * mul, rgb._2 * mul, rgb._3 * mul)
}

def renderNodes(): Unit = {
GL11.glBegin(GL11.GL_QUADS)
val tess = Tessellator.instance
tess.startDrawing(GL11.GL_QUADS)

for (node <- currentLinks.nodes) {
val color =
if (node.flags.contains(VNodeFlags.MISSING))
(1d, 0d, 0d)
(255, 0, 0)
else if (node.flags.contains(VNodeFlags.DENSE))
(1d, 1d, 0d)
(255, 255, 0)
else
(0d, 0d, 1d)
(0, 0, 255)

setColor(color, 1d) // +Y
GL11.glVertex3d(
tess.setColorRGBA(color._1, color._2, color._3, 255) // +Y
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d - SIZE
)

setColor(color, 0.5d) // -Y
GL11.glVertex3d(
tess.setColorRGBA(color._1 / 2, color._2 / 2, color._3 / 2, 255) // -Y
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d - SIZE
)

setColor(color, 0.8d) // +/- Z
GL11.glVertex3d(
tess.setColorRGBA(
color._1 * 8 / 10,
color._2 * 8 / 10,
color._3 * 8 / 10,
255
) // +/- Z
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d - SIZE
)

setColor(color, 0.6d) // +/- X
GL11.glVertex3d(
tess.setColorRGBA(
color._1 * 6 / 10,
color._2 * 6 / 10,
color._3 * 6 / 10,
255
) // +/- X
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d + SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d + SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d + SIZE,
node.z + 0.5d - SIZE
)
GL11.glVertex3d(
tess.addVertex(
node.x + 0.5d - SIZE,
node.y + 0.5d - SIZE,
node.z + 0.5d - SIZE
)
}

GL11.glEnd()
tess.draw()
}

def renderLinks(links: Seq[VLink], width: Float, onlyP2P: Boolean): Unit = {
GL11.glLineWidth(width)
GL11.glBegin(GL11.GL_LINES)
val tess = Tessellator.instance
tess.startDrawing(GL11.GL_LINES)

for (
link <- links if (!onlyP2P) || link.flags.contains(VLinkFlags.COMPRESSED)
) {
if (link.flags.contains(VLinkFlags.COMPRESSED)) {
GL11.glColor3f(1, 0, 1)
tess.setColorRGBA(255, 0, 255, 255)
} else if (link.flags.contains(VLinkFlags.DENSE)) {
GL11.glColor3f(1, 1, 0)
tess.setColorRGBA(255, 255, 0, 255)
} else {
GL11.glColor3f(0, 0, 1)
tess.setColorRGBA(0, 0, 255, 255)
}

GL11.glVertex3d(
tess.addVertex(
link.node1.x + 0.5d,
link.node1.y + 0.5d,
link.node1.z + 0.5d
)
GL11.glVertex3d(
tess.addVertex(
link.node2.x + 0.5d,
link.node2.y + 0.5d,
link.node2.z + 0.5d
)
}

GL11.glEnd()
tess.draw()
}

val renderNodesModes = Set(
Expand All @@ -222,64 +231,74 @@ object VisualiserOverlayRender extends WorldOverlayRenderer {
VisualisationModes.P2P
)

override def doRender(partialTicks: Float): Unit = {
if (Client.player != null) {
val stack = Client.player.inventory.getCurrentItem
if (
stack != null && stack.getItem == ItemVisualiser && stack.hasTagCompound && stack.getTagCompound
.hasKey("dim")
) {

// Do not render if in a different dimension from the bound network
val networkDim = stack.getTagCompound.getInteger("dim")
if (networkDim != Client.world.provider.dimensionId) {
return
}

val mode = ItemVisualiser.getMode(stack)

GL11.glPushAttrib(GL11.GL_ENABLE_BIT)
override def doRender(
partialTicks: Float,
viewX: Double,
viewY: Double,
viewZ: Double
): Unit = {
val stack = Client.player.inventory.getCurrentItem
if (
!(stack != null && stack.getItem == ItemVisualiser && stack.hasTagCompound) || !stack.getTagCompound
.hasKey("dim")
) {
return
}
// Do not render if in a different dimension from the bound network
val networkDim = stack.getTagCompound.getInteger("dim")
if (networkDim != Client.world.provider.dimensionId) {
return
}

GL11.glDisable(GL11.GL_LIGHTING)
GL11.glDisable(GL11.GL_TEXTURE_2D)
GL11.glDisable(GL11.GL_DEPTH_TEST)
val mode = ItemVisualiser.getMode(stack)

if (needListRefresh) {
needListRefresh = false
GL11.glNewList(staticList, GL11.GL_COMPILE)
GL11.glPushAttrib(GL11.GL_ENABLE_BIT)

if (renderNodesModes.contains(mode))
renderNodes()
GL11.glDisable(GL11.GL_LIGHTING)
GL11.glDisable(GL11.GL_TEXTURE_2D)
GL11.glDisable(GL11.GL_DEPTH_TEST)

GL11.glEnable(GL11.GL_LINE_SMOOTH)
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
if (needListRefresh) {
needListRefresh = false
GL11.glNewList(staticList, GL11.GL_COMPILE)

if (renderLinksModes.contains(mode)) {
renderLinks(dense, 16f, mode == VisualisationModes.P2P)
renderLinks(normal, 4f, mode == VisualisationModes.P2P)
}
if (renderNodesModes.contains(mode))
renderNodes()

GL11.glEndList()
}
GL11.glEnable(GL11.GL_LINE_SMOOTH)
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)

GL11.glCallList(staticList)
if (renderLinksModes.contains(mode)) {
renderLinks(dense, 16f, mode == VisualisationModes.P2P)
renderLinks(normal, 4f, mode == VisualisationModes.P2P)
}

// Labels are rendered every frame because they need to face the camera
GL11.glEndList()
}

if (mode == VisualisationModes.FULL) {
for (link <- currentLinks.links if link.channels > 0) {
OverlayRenderHandler.renderFloatingText(
link.channels.toString,
(link.node1.x + link.node2.x) / 2d + 0.5d,
(link.node1.y + link.node2.y) / 2d + 0.5d,
(link.node1.z + link.node2.z) / 2d + 0.5d,
0xffffff
)
}
GL11.glCallList(staticList)

// Labels are rendered every frame because they need to face the camera

if (mode == VisualisationModes.FULL) {
for (link <- currentLinks.links if link.channels > 0) {
val linkX = (link.node1.x + link.node2.x) / 2d + 0.5d
val linkY = (link.node1.y + link.node2.y) / 2d + 0.5d
val linkZ = (link.node1.z + link.node2.z) / 2d + 0.5d
val distSq =
(viewX - linkX) * (viewX - linkX) + (viewY - linkY) * (viewY - linkY) + (viewZ - linkZ) * (viewZ - linkZ)
if (distSq < 256d) { // 16 blocks
OverlayRenderHandler.renderFloatingText(
link.channels.toString,
linkX,
linkY,
linkZ,
0xffffff
)
}

GL11.glPopAttrib()
}
}

GL11.glPopAttrib()
}
}
Loading

0 comments on commit b017465

Please sign in to comment.