mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-13 19:50:31 +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 dan200.computercraft.ComputerCraft;
|
||||
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 net.minecraft.client.renderer.texture.TextureUtil;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.getColour;
|
||||
|
||||
class MonitorTextureBufferShader
|
||||
{
|
||||
public static final int UNIFORM_SIZE = 4 * 4 * 16 + 4 + 4;
|
||||
|
||||
static final int TEXTURE_INDEX = GL13.GL_TEXTURE3;
|
||||
|
||||
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 uniformFont;
|
||||
private static int uniformWidth;
|
||||
private static int uniformHeight;
|
||||
private static int uniformTbo;
|
||||
private static int uniformPalette;
|
||||
private static int uniformMonitor;
|
||||
|
||||
private static boolean initialised;
|
||||
private static boolean ok;
|
||||
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();
|
||||
transform.store( MATRIX_BUFFER );
|
||||
MATRIX_BUFFER.rewind();
|
||||
RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER );
|
||||
|
||||
RenderSystem.glUniform1i( uniformWidth, width );
|
||||
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 );
|
||||
GL31.glBindBufferBase( GL31.GL_UNIFORM_BUFFER, uniformMonitor, tboUniform );
|
||||
}
|
||||
|
||||
static boolean use()
|
||||
@ -116,10 +104,9 @@ class MonitorTextureBufferShader
|
||||
|
||||
uniformMv = getUniformLocation( program, "u_mv" );
|
||||
uniformFont = getUniformLocation( program, "u_font" );
|
||||
uniformWidth = getUniformLocation( program, "u_width" );
|
||||
uniformHeight = getUniformLocation( program, "u_height" );
|
||||
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." );
|
||||
return true;
|
||||
@ -159,4 +146,50 @@ class MonitorTextureBufferShader
|
||||
if( uniform == -1 ) throw new IllegalStateException( "Cannot find uniform " + name );
|
||||
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.DirectVertexBuffer;
|
||||
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.MonitorRenderer;
|
||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
@ -39,7 +37,8 @@ import org.lwjgl.opengl.GL31;
|
||||
import javax.annotation.Nonnull;
|
||||
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>
|
||||
{
|
||||
@ -172,22 +171,13 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
|
||||
|
||||
if( redraw )
|
||||
{
|
||||
ByteBuffer monitorBuffer = getBuffer( width * height * 3 );
|
||||
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++ )
|
||||
{
|
||||
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();
|
||||
ByteBuffer terminalBuffer = getBuffer( width * height * 3 );
|
||||
MonitorTextureBufferShader.setTerminalData( terminalBuffer, terminal );
|
||||
DirectBuffers.setBufferData( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer, terminalBuffer, GL20.GL_STATIC_DRAW );
|
||||
|
||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
|
||||
GlStateManager._glBufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
|
||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
|
||||
ByteBuffer uniformBuffer = getBuffer( MonitorTextureBufferShader.UNIFORM_SIZE );
|
||||
MonitorTextureBufferShader.setUniformData( uniformBuffer, terminal, !monitor.isColour() );
|
||||
DirectBuffers.setBufferData( GL31.GL_UNIFORM_BUFFER, monitor.tboUniform, uniformBuffer, GL20.GL_STATIC_DRAW );
|
||||
}
|
||||
|
||||
// Nobody knows what they're doing!
|
||||
@ -195,7 +185,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
|
||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture );
|
||||
GlStateManager._activeTexture( GL13.GL_TEXTURE0 );
|
||||
|
||||
MonitorTextureBufferShader.setupUniform( matrix, width, height, terminal.getPalette(), !monitor.isColour() );
|
||||
MonitorTextureBufferShader.setupUniform( matrix, monitor.tboUniform );
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder buffer = tessellator.getBuilder();
|
||||
|
@ -7,6 +7,7 @@ package dan200.computercraft.shared.peripheral.monitor;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import dan200.computercraft.client.util.DirectBuffers;
|
||||
import dan200.computercraft.client.util.DirectVertexBuffer;
|
||||
import dan200.computercraft.shared.common.ClientTerminal;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@ -32,6 +33,7 @@ public final class ClientMonitor extends ClientTerminal
|
||||
|
||||
public int tboBuffer;
|
||||
public int tboTexture;
|
||||
public int tboUniform;
|
||||
public DirectVertexBuffer buffer;
|
||||
|
||||
public ClientMonitor( boolean colour, TileMonitor origin )
|
||||
@ -63,15 +65,15 @@ public final class ClientMonitor extends ClientTerminal
|
||||
|
||||
deleteBuffers();
|
||||
|
||||
tboBuffer = GlStateManager._glGenBuffers();
|
||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, tboBuffer );
|
||||
GL15.glBufferData( GL31.GL_TEXTURE_BUFFER, 0, GL15.GL_STATIC_DRAW );
|
||||
tboBuffer = DirectBuffers.createBuffer();
|
||||
DirectBuffers.setEmptyBufferData( GL31.GL_TEXTURE_BUFFER, tboBuffer, GL15.GL_STATIC_DRAW );
|
||||
tboTexture = GlStateManager._genTexture();
|
||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, tboTexture );
|
||||
GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, tboBuffer );
|
||||
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();
|
||||
return true;
|
||||
@ -113,6 +115,12 @@ public final class ClientMonitor extends ClientTerminal
|
||||
tboTexture = 0;
|
||||
}
|
||||
|
||||
if( tboUniform != 0 )
|
||||
{
|
||||
RenderSystem.glDeleteBuffers( tboUniform );
|
||||
tboUniform = 0;
|
||||
}
|
||||
|
||||
if( buffer != null )
|
||||
{
|
||||
buffer.close();
|
||||
|
@ -4,10 +4,13 @@
|
||||
#define FONT_HEIGHT 9.0
|
||||
|
||||
uniform sampler2D u_font;
|
||||
uniform int u_width;
|
||||
uniform int u_height;
|
||||
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user