Fixes #31 for current 1.3 upstream.

Removed nested display lists from screen renderer.
This commit is contained in:
evg-zhabotinsky 2014-06-08 02:24:15 +04:00
parent ac811de85d
commit 2e00640839

View File

@ -38,51 +38,15 @@ object MonospaceFontRenderer {
})
private class Renderer(private val textureManager: TextureManager) {
/** Display lists, one per char (renders quad with char's uv coords). */
private val charLists = GLAllocation.generateDisplayLists(256)
RenderState.checkError("MonospaceFontRenderer.charLists")
/** Buffer filled with char display lists to efficiently draw strings. */
private val listBuffer = GLAllocation.createDirectIntBuffer(512)
RenderState.checkError("MonospaceFontRenderer.listBuffer")
private val (charWidth, charHeight) = (MonospaceFontRenderer.fontWidth * 2, MonospaceFontRenderer.fontHeight * 2)
private val cols = 256 / charWidth
private val uStep = charWidth / 256.0
private val uSize = uStep
private val vStep = (charHeight + 1) / 256.0
private val vSize = charHeight / 256.0
// Set up the display lists.
{
val s = Settings.get.fontCharScale
val dw = charWidth * s - charWidth
val dh = charHeight * s - charHeight
// Now create lists for all printable chars.
for (index <- 1 until 0xFF) {
val x = (index - 1) % cols
val y = (index - 1) / cols
val u = x * uStep
val v = y * vStep
GL11.glNewList(charLists + index, GL11.GL_COMPILE)
GL11.glBegin(GL11.GL_QUADS)
GL11.glTexCoord2d(u, v + vSize)
GL11.glVertex3d(-dw, charHeight * s, 0)
GL11.glTexCoord2d(u + uSize, v + vSize)
GL11.glVertex3d(charWidth * s, charHeight * s, 0)
GL11.glTexCoord2d(u + uSize, v)
GL11.glVertex3d(charWidth * s, -dh, 0)
GL11.glTexCoord2d(u, v)
GL11.glVertex3d(-dw, -dh, 0)
GL11.glEnd()
GL11.glTranslatef(charWidth, 0, 0)
GL11.glEndList()
}
// Special case for whitespace: just translate, don't render.
GL11.glNewList(charLists + ' ', GL11.GL_COMPILE)
GL11.glTranslatef(charWidth, 0, 0)
GL11.glEndList()
}
private val s = Settings.get.fontCharScale
private val dw = charWidth * s - charWidth
private val dh = charHeight * s - charHeight
def drawString(x: Int, y: Int, value: Array[Char], color: Array[Short], format: PackedColor.ColorFormat) = {
if (color.length != value.length) throw new IllegalArgumentException("Color count must match char count.")
@ -98,6 +62,7 @@ object MonospaceFontRenderer {
GL11.glDepthMask(false)
GL11.glDisable(GL11.GL_TEXTURE_2D)
GL11.glBegin(GL11.GL_QUADS)
// Background first. We try to merge adjacent backgrounds of the same
// color to reduce the number of quads we have to draw.
var cbg = 0x000000
@ -113,6 +78,8 @@ object MonospaceFontRenderer {
width = width + 1
}
draw(cbg, offset, width)
GL11.glEnd()
GL11.glEnable(GL11.GL_TEXTURE_2D)
if (Settings.get.textLinearFiltering) {
@ -121,7 +88,9 @@ object MonospaceFontRenderer {
// Foreground second. We only have to flush when the color changes, so
// unless every char has a different color this should be quite efficient.
GL11.glBegin(GL11.GL_QUADS)
var cfg = -1
var posX = 0.0
for ((ch, col) <- value.zip(color.map(PackedColor.unpackForeground(_, format)))) {
val index = 1 + (chars.indexOf(ch) match {
case -1 => chars.indexOf('?')
@ -129,18 +98,31 @@ object MonospaceFontRenderer {
})
if (col != cfg) {
// Color changed, force flush and adjust colors.
flush()
cfg = col
GL11.glColor3ub(
((cfg & 0xFF0000) >> 16).toByte,
((cfg & 0x00FF00) >> 8).toByte,
((cfg & 0x0000FF) >> 0).toByte)
}
listBuffer.put(charLists + index)
if (listBuffer.remaining == 0)
flush()
{
if (index != ' ') { // Don't render whitespace.
val x = (index - 1) % cols
val y = (index - 1) / cols
val u = x * uStep
val v = y * vStep
GL11.glTexCoord2d(u, v + vSize)
GL11.glVertex3d(posX - dw, charHeight * s, 0)
GL11.glTexCoord2d(u + uSize, v + vSize)
GL11.glVertex3d(posX + charWidth * s, charHeight * s, 0)
GL11.glTexCoord2d(u + uSize, v)
GL11.glVertex3d(posX + charWidth * s, -dh, 0)
GL11.glTexCoord2d(u, v)
GL11.glVertex3d(posX - dw, -dh, 0)
}
posX += charWidth
}
}
flush()
GL11.glEnd()
GL11.glPopAttrib()
GL11.glPopMatrix()
@ -153,19 +135,11 @@ object MonospaceFontRenderer {
// happen I have no idea why, and can only guess that it's related to
// using the VBO/ARB the tessellator uses inside a display list (since
// this stuff is eventually only rendered via display lists).
GL11.glBegin(GL11.GL_QUADS)
GL11.glColor3ub(((color >> 16) & 0xFF).toByte, ((color >> 8) & 0xFF).toByte, (color & 0xFF).toByte)
GL11.glVertex3d(charWidth * offset, charHeight, 0)
GL11.glVertex3d(charWidth * (offset + width), charHeight, 0)
GL11.glVertex3d(charWidth * (offset + width), 0, 0)
GL11.glVertex3d(charWidth * offset, 0, 0)
GL11.glEnd()
}
private def flush() = if (listBuffer.position > 0) {
listBuffer.flip()
GL11.glCallLists(listBuffer)
listBuffer.clear()
}
}