mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 04:00:30 +00:00
Use UBOs for the TBO renderer
Like #455, this sets our uniforms via a UBO rather than having separate ones for each value. There are a couple of small differences: - Have a UBO for each monitor, rather than sharing one and rewriting it every monitor. This means we only need to update the buffer when the monitor changes. - Use std140 rather than the default layout. This means we don't have to care about location/stride in the buffer. Also like #455, this doesn't actually seem to result in any performance improvements for me. However, it does make it a bit easier to handle a large number of uniforms. Also cleans up the generation of the main monitor texture buffer: - Move buffer generation into a separate method - just ensures that it shows up separately in profilers. - Explicitly pass the position when setting bytes, rather than incrementing the internal one. This saves some memory reads/writes (I thought Java optimised them out, evidently not!). Saves a few fps when updating. - Use DSA when possible. Unclear if it helps at all, but nice to do :).
This commit is contained in:
parent
78aa757549
commit
77a00b14ae
@ -10,61 +10,49 @@ import com.mojang.blaze3d.platform.GlStateManager;
|
|||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
||||||
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.core.terminal.TextBuffer;
|
||||||
|
import dan200.computercraft.shared.util.Colour;
|
||||||
import dan200.computercraft.shared.util.Palette;
|
import dan200.computercraft.shared.util.Palette;
|
||||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL13;
|
import org.lwjgl.opengl.GL13;
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL31;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
|
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.getColour;
|
||||||
|
|
||||||
class MonitorTextureBufferShader
|
class MonitorTextureBufferShader
|
||||||
{
|
{
|
||||||
|
public static final int UNIFORM_SIZE = 4 * 4 * 16 + 4 + 4;
|
||||||
|
|
||||||
static final int TEXTURE_INDEX = GL13.GL_TEXTURE3;
|
static final int TEXTURE_INDEX = GL13.GL_TEXTURE3;
|
||||||
|
|
||||||
private static final FloatBuffer MATRIX_BUFFER = BufferUtils.createFloatBuffer( 16 );
|
private static final FloatBuffer MATRIX_BUFFER = BufferUtils.createFloatBuffer( 16 );
|
||||||
private static final FloatBuffer PALETTE_BUFFER = BufferUtils.createFloatBuffer( 16 * 3 );
|
|
||||||
|
|
||||||
private static int uniformMv;
|
private static int uniformMv;
|
||||||
|
|
||||||
private static int uniformFont;
|
private static int uniformFont;
|
||||||
private static int uniformWidth;
|
|
||||||
private static int uniformHeight;
|
|
||||||
private static int uniformTbo;
|
private static int uniformTbo;
|
||||||
private static int uniformPalette;
|
private static int uniformMonitor;
|
||||||
|
|
||||||
private static boolean initialised;
|
private static boolean initialised;
|
||||||
private static boolean ok;
|
private static boolean ok;
|
||||||
private static int program;
|
private static int program;
|
||||||
|
|
||||||
static void setupUniform( Matrix4f transform, int width, int height, Palette palette, boolean greyscale )
|
static void setupUniform( Matrix4f transform, int tboUniform )
|
||||||
{
|
{
|
||||||
MATRIX_BUFFER.rewind();
|
MATRIX_BUFFER.rewind();
|
||||||
transform.store( MATRIX_BUFFER );
|
transform.store( MATRIX_BUFFER );
|
||||||
MATRIX_BUFFER.rewind();
|
MATRIX_BUFFER.rewind();
|
||||||
RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER );
|
RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER );
|
||||||
|
|
||||||
RenderSystem.glUniform1i( uniformWidth, width );
|
GL31.glBindBufferBase( GL31.GL_UNIFORM_BUFFER, uniformMonitor, tboUniform );
|
||||||
RenderSystem.glUniform1i( uniformHeight, height );
|
|
||||||
|
|
||||||
PALETTE_BUFFER.rewind();
|
|
||||||
for( int i = 0; i < 16; i++ )
|
|
||||||
{
|
|
||||||
double[] colour = palette.getColour( i );
|
|
||||||
if( greyscale )
|
|
||||||
{
|
|
||||||
float f = FixedWidthFontRenderer.toGreyscale( colour );
|
|
||||||
PALETTE_BUFFER.put( f ).put( f ).put( f );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PALETTE_BUFFER.put( (float) colour[0] ).put( (float) colour[1] ).put( (float) colour[2] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PALETTE_BUFFER.flip();
|
|
||||||
RenderSystem.glUniform3( uniformPalette, PALETTE_BUFFER );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean use()
|
static boolean use()
|
||||||
@ -116,10 +104,9 @@ class MonitorTextureBufferShader
|
|||||||
|
|
||||||
uniformMv = getUniformLocation( program, "u_mv" );
|
uniformMv = getUniformLocation( program, "u_mv" );
|
||||||
uniformFont = getUniformLocation( program, "u_font" );
|
uniformFont = getUniformLocation( program, "u_font" );
|
||||||
uniformWidth = getUniformLocation( program, "u_width" );
|
|
||||||
uniformHeight = getUniformLocation( program, "u_height" );
|
|
||||||
uniformTbo = getUniformLocation( program, "u_tbo" );
|
uniformTbo = getUniformLocation( program, "u_tbo" );
|
||||||
uniformPalette = getUniformLocation( program, "u_palette" );
|
uniformMonitor = GL31.glGetUniformBlockIndex( program, "u_monitor" );
|
||||||
|
if( uniformMonitor == -1 ) throw new IllegalStateException( "Could not find uniformMonitor uniform." );
|
||||||
|
|
||||||
ComputerCraft.log.info( "Loaded monitor shader." );
|
ComputerCraft.log.info( "Loaded monitor shader." );
|
||||||
return true;
|
return true;
|
||||||
@ -159,4 +146,50 @@ class MonitorTextureBufferShader
|
|||||||
if( uniform == -1 ) throw new IllegalStateException( "Cannot find uniform " + name );
|
if( uniform == -1 ) throw new IllegalStateException( "Cannot find uniform " + name );
|
||||||
return uniform;
|
return uniform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setTerminalData( ByteBuffer buffer, Terminal terminal )
|
||||||
|
{
|
||||||
|
int width = terminal.getWidth(), height = terminal.getHeight();
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
for( int y = 0; y < height; y++ )
|
||||||
|
{
|
||||||
|
TextBuffer text = terminal.getLine( y ), textColour = terminal.getTextColourLine( y ), background = terminal.getBackgroundColourLine( y );
|
||||||
|
for( int x = 0; x < width; x++ )
|
||||||
|
{
|
||||||
|
buffer.put( pos, (byte) (text.charAt( x ) & 0xFF) );
|
||||||
|
buffer.put( pos + 1, (byte) getColour( textColour.charAt( x ), Colour.WHITE ) );
|
||||||
|
buffer.put( pos + 2, (byte) getColour( background.charAt( x ), Colour.BLACK ) );
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.limit( pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setUniformData( ByteBuffer buffer, Terminal terminal, boolean greyscale )
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
Palette palette = terminal.getPalette();
|
||||||
|
for( int i = 0; i < 16; i++ )
|
||||||
|
{
|
||||||
|
double[] colour = palette.getColour( i );
|
||||||
|
if( greyscale )
|
||||||
|
{
|
||||||
|
float f = FixedWidthFontRenderer.toGreyscale( colour );
|
||||||
|
buffer.putFloat( pos, f ).putFloat( pos + 4, f ).putFloat( pos + 8, f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer.putFloat( pos, (float) colour[0] ).putFloat( pos + 4, (float) colour[1] ).putFloat( pos + 8, (float) colour[2] );
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 4 * 4; // std140 requires these are 4-wide
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = terminal.getWidth(), height = terminal.getHeight();
|
||||||
|
buffer.putInt( pos, width ).putInt( pos + 4, height );
|
||||||
|
|
||||||
|
buffer.limit( UNIFORM_SIZE );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,9 @@ import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
|||||||
import dan200.computercraft.client.util.DirectBuffers;
|
import dan200.computercraft.client.util.DirectBuffers;
|
||||||
import dan200.computercraft.client.util.DirectVertexBuffer;
|
import dan200.computercraft.client.util.DirectVertexBuffer;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.core.terminal.TextBuffer;
|
|
||||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||||
import dan200.computercraft.shared.util.Colour;
|
|
||||||
import dan200.computercraft.shared.util.DirectionUtil;
|
import dan200.computercraft.shared.util.DirectionUtil;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
@ -39,7 +37,8 @@ import org.lwjgl.opengl.GL31;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.*;
|
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT;
|
||||||
|
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_WIDTH;
|
||||||
|
|
||||||
public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
|
public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
|
||||||
{
|
{
|
||||||
@ -172,22 +171,13 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
|
|||||||
|
|
||||||
if( redraw )
|
if( redraw )
|
||||||
{
|
{
|
||||||
ByteBuffer monitorBuffer = getBuffer( width * height * 3 );
|
ByteBuffer terminalBuffer = getBuffer( width * height * 3 );
|
||||||
for( int y = 0; y < height; y++ )
|
MonitorTextureBufferShader.setTerminalData( terminalBuffer, terminal );
|
||||||
{
|
DirectBuffers.setBufferData( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer, terminalBuffer, GL20.GL_STATIC_DRAW );
|
||||||
TextBuffer text = terminal.getLine( y ), textColour = terminal.getTextColourLine( y ), background = terminal.getBackgroundColourLine( y );
|
|
||||||
for( int x = 0; x < width; x++ )
|
|
||||||
{
|
|
||||||
monitorBuffer.put( (byte) (text.charAt( x ) & 0xFF) );
|
|
||||||
monitorBuffer.put( (byte) getColour( textColour.charAt( x ), Colour.WHITE ) );
|
|
||||||
monitorBuffer.put( (byte) getColour( background.charAt( x ), Colour.BLACK ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
monitorBuffer.flip();
|
|
||||||
|
|
||||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
|
ByteBuffer uniformBuffer = getBuffer( MonitorTextureBufferShader.UNIFORM_SIZE );
|
||||||
GlStateManager._glBufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
|
MonitorTextureBufferShader.setUniformData( uniformBuffer, terminal, !monitor.isColour() );
|
||||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
|
DirectBuffers.setBufferData( GL31.GL_UNIFORM_BUFFER, monitor.tboUniform, uniformBuffer, GL20.GL_STATIC_DRAW );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nobody knows what they're doing!
|
// Nobody knows what they're doing!
|
||||||
@ -195,7 +185,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
|
|||||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture );
|
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture );
|
||||||
GlStateManager._activeTexture( GL13.GL_TEXTURE0 );
|
GlStateManager._activeTexture( GL13.GL_TEXTURE0 );
|
||||||
|
|
||||||
MonitorTextureBufferShader.setupUniform( matrix, width, height, terminal.getPalette(), !monitor.isColour() );
|
MonitorTextureBufferShader.setupUniform( matrix, monitor.tboUniform );
|
||||||
|
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
BufferBuilder buffer = tessellator.getBuilder();
|
BufferBuilder buffer = tessellator.getBuilder();
|
||||||
|
@ -7,6 +7,7 @@ package dan200.computercraft.shared.peripheral.monitor;
|
|||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import dan200.computercraft.client.util.DirectBuffers;
|
||||||
import dan200.computercraft.client.util.DirectVertexBuffer;
|
import dan200.computercraft.client.util.DirectVertexBuffer;
|
||||||
import dan200.computercraft.shared.common.ClientTerminal;
|
import dan200.computercraft.shared.common.ClientTerminal;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -32,6 +33,7 @@ public final class ClientMonitor extends ClientTerminal
|
|||||||
|
|
||||||
public int tboBuffer;
|
public int tboBuffer;
|
||||||
public int tboTexture;
|
public int tboTexture;
|
||||||
|
public int tboUniform;
|
||||||
public DirectVertexBuffer buffer;
|
public DirectVertexBuffer buffer;
|
||||||
|
|
||||||
public ClientMonitor( boolean colour, TileMonitor origin )
|
public ClientMonitor( boolean colour, TileMonitor origin )
|
||||||
@ -63,15 +65,15 @@ public final class ClientMonitor extends ClientTerminal
|
|||||||
|
|
||||||
deleteBuffers();
|
deleteBuffers();
|
||||||
|
|
||||||
tboBuffer = GlStateManager._glGenBuffers();
|
tboBuffer = DirectBuffers.createBuffer();
|
||||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, tboBuffer );
|
DirectBuffers.setEmptyBufferData( GL31.GL_TEXTURE_BUFFER, tboBuffer, GL15.GL_STATIC_DRAW );
|
||||||
GL15.glBufferData( GL31.GL_TEXTURE_BUFFER, 0, GL15.GL_STATIC_DRAW );
|
|
||||||
tboTexture = GlStateManager._genTexture();
|
tboTexture = GlStateManager._genTexture();
|
||||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, tboTexture );
|
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, tboTexture );
|
||||||
GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, tboBuffer );
|
GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, tboBuffer );
|
||||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, 0 );
|
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, 0 );
|
||||||
|
|
||||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
|
tboUniform = DirectBuffers.createBuffer();
|
||||||
|
DirectBuffers.setEmptyBufferData( GL31.GL_UNIFORM_BUFFER, tboUniform, GL15.GL_STATIC_DRAW );
|
||||||
|
|
||||||
addMonitor();
|
addMonitor();
|
||||||
return true;
|
return true;
|
||||||
@ -113,6 +115,12 @@ public final class ClientMonitor extends ClientTerminal
|
|||||||
tboTexture = 0;
|
tboTexture = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( tboUniform != 0 )
|
||||||
|
{
|
||||||
|
RenderSystem.glDeleteBuffers( tboUniform );
|
||||||
|
tboUniform = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if( buffer != null )
|
if( buffer != null )
|
||||||
{
|
{
|
||||||
buffer.close();
|
buffer.close();
|
||||||
|
@ -4,10 +4,13 @@
|
|||||||
#define FONT_HEIGHT 9.0
|
#define FONT_HEIGHT 9.0
|
||||||
|
|
||||||
uniform sampler2D u_font;
|
uniform sampler2D u_font;
|
||||||
uniform int u_width;
|
|
||||||
uniform int u_height;
|
|
||||||
uniform usamplerBuffer u_tbo;
|
uniform usamplerBuffer u_tbo;
|
||||||
uniform vec3 u_palette[16];
|
|
||||||
|
layout(std140) uniform u_monitor {
|
||||||
|
vec3 u_palette[16];
|
||||||
|
int u_width;
|
||||||
|
int u_height;
|
||||||
|
};
|
||||||
|
|
||||||
in vec2 f_pos;
|
in vec2 f_pos;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user