Made dataBuffer be common for all holograms.

This commit is contained in:
evg-zhabotinsky 2014-06-10 23:52:11 +04:00
parent 29cbfb529e
commit 4157109b2e

View File

@ -15,15 +15,15 @@ import org.lwjgl.BufferUtils
import li.cil.oc.Settings import li.cil.oc.Settings
import java.nio.IntBuffer import java.nio.IntBuffer
object HologramRenderer extends TileEntitySpecialRenderer with Callable[(Int, IntBuffer)] with RemovalListener[TileEntity, (Int, IntBuffer)] with ITickHandler { object HologramRenderer extends TileEntitySpecialRenderer with Callable[Int] with RemovalListener[TileEntity, Int] with ITickHandler {
private val random = new Random() private val random = new Random()
/** We cache the VBOs for the projectors we render for performance. */ /** We cache the VBOs for the projectors we render for performance. */
private val cache = com.google.common.cache.CacheBuilder.newBuilder(). private val cache = com.google.common.cache.CacheBuilder.newBuilder().
expireAfterAccess(10, TimeUnit.SECONDS). expireAfterAccess(10, TimeUnit.SECONDS).
removalListener(this). removalListener(this).
asInstanceOf[CacheBuilder[Hologram, (Int, IntBuffer)]]. asInstanceOf[CacheBuilder[Hologram, Int]].
build[Hologram, (Int, IntBuffer)]() build[Hologram, Int]()
/** /**
* Common for all holograms. Holds the vertex positions, texture * Common for all holograms. Holds the vertex positions, texture
@ -33,9 +33,20 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[(Int, In
* same dimensions (in voxels). If we ever need holograms of different * same dimensions (in voxels). If we ever need holograms of different
* sizes we could probably just fake that by making the outer layers * sizes we could probably just fake that by making the outer layers
* immutable (i.e. always empty). * immutable (i.e. always empty).
*
* NOTE: It already takes up 47.25 MiB of video memory and increasing
* hologram size to, for example, 64*64*64 will result in 168 MiB.
*/ */
private var commonBuffer = 0 private var commonBuffer = 0
/**
* Also common for all holograms. Temporary buffer used to upload
* hologram data to GPU. First half stores colors for each vertex
* (0xAABBGGRR Int, alpha is used for alignment only) and second
* half stores (Int) indices of vertices that should be drawn.
*/
private var dataBuffer: IntBuffer = null
/** Used to pass the current screen along to call(). */ /** Used to pass the current screen along to call(). */
private var hologram: Hologram = null private var hologram: Hologram = null
@ -92,13 +103,13 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[(Int, In
// When we don't do this the hologram will look different from different // When we don't do this the hologram will look different from different
// angles (because some faces will shine through sometimes and sometimes // angles (because some faces will shine through sometimes and sometimes
// they won't), so a more... consistent look is desirable. // they won't), so a more... consistent look is desirable.
val (glBuffer, dataBuffer) = cache.get(hologram, this) val glBuffer = cache.get(hologram, this)
GL11.glColorMask(false, false, false, false) GL11.glColorMask(false, false, false, false)
GL11.glDepthMask(true) GL11.glDepthMask(true)
draw(glBuffer, dataBuffer) draw(glBuffer)
GL11.glColorMask(true, true, true, true) GL11.glColorMask(true, true, true, true)
GL11.glDepthFunc(GL11.GL_EQUAL) GL11.glDepthFunc(GL11.GL_EQUAL)
draw(glBuffer, dataBuffer) draw(glBuffer)
GL11.glPopMatrix() GL11.glPopMatrix()
GL11.glPopAttrib() GL11.glPopAttrib()
@ -107,15 +118,17 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[(Int, In
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving") RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
} }
def draw(glBuffer: Int, dataBuffer: IntBuffer) { def draw(glBuffer: Int) {
initialize() initialize()
validate(glBuffer, dataBuffer) validate(glBuffer)
publish(glBuffer) publish(glBuffer)
} }
private def initialize() { private def initialize() {
// First run only, create structure information. // First run only, create structure information.
if (commonBuffer == 0) { if (commonBuffer == 0) {
dataBuffer = BufferUtils.createIntBuffer(hologram.width * hologram.width * hologram.height * 6 * 4 * 2)
commonBuffer = GL15.glGenBuffers() commonBuffer = GL15.glGenBuffers()
val data = BufferUtils.createFloatBuffer(hologram.width * hologram.width * hologram.height * 24 * (2 + 3 + 3)) val data = BufferUtils.createFloatBuffer(hologram.width * hologram.width * hologram.height * 24 * (2 + 3 + 3))
@ -188,7 +201,7 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[(Int, In
} }
} }
private def validate(glBuffer: Int, dataBuffer: IntBuffer) { private def validate(glBuffer: Int) {
// Refresh indexes when the hologram's data changed. // Refresh indexes when the hologram's data changed.
if (hologram.dirty) { if (hologram.dirty) {
def value(hx: Int, hy: Int, hz: Int) = if (hx >= 0 && hy >= 0 && hz >= 0 && hx < hologram.width && hy < hologram.height && hz < hologram.width) hologram.getColor(hx, hy, hz) else 0 def value(hx: Int, hy: Int, hz: Int) = if (hx >= 0 && hy >= 0 && hz >= 0 && hx < hologram.width && hy < hologram.height && hz < hologram.width) hologram.getColor(hx, hy, hz) else 0
@ -294,16 +307,15 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[(Int, In
def call = { def call = {
val glBuffer = GL15.glGenBuffers() val glBuffer = GL15.glGenBuffers()
val dataBuffer = BufferUtils.createIntBuffer(hologram.width * hologram.width * hologram.height * 6 * 4 * 2)
// Force re-indexing. // Force re-indexing.
hologram.dirty = true hologram.dirty = true
(glBuffer, dataBuffer) glBuffer
} }
def onRemoval(e: RemovalNotification[TileEntity, (Int, IntBuffer)]) { def onRemoval(e: RemovalNotification[TileEntity, Int]) {
val (glBuffer, dataBuffer) = e.getValue val glBuffer = e.getValue
GL15.glDeleteBuffers(glBuffer) GL15.glDeleteBuffers(glBuffer)
dataBuffer.clear() dataBuffer.clear()
} }