Skip to content

Commit 50797bb

Browse files
committed
Rewrite printout rendering
- The current page is always centred when rendering in a GUI, with the turned pages moving from the sides. - Pages are no longer evenly distributed from the centre - they follow an exponential decay curve, so ones further out are closer together (a bit like an open book). - Render pages and books in item frames/in-hand (rather than just single pages). This currently does some very dirty things with z values in order to prevent z-fighting. It would be nice to avoid that, though turning off writing to the z buffer causes issues with the bounding box.
1 parent c0bdd4f commit 50797bb

3 files changed

Lines changed: 209 additions & 149 deletions

File tree

src/main/java/dan200/computercraft/client/gui/GuiPrintout.java

Lines changed: 23 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,19 @@
66

77
package dan200.computercraft.client.gui;
88

9-
import dan200.computercraft.ComputerCraft;
109
import dan200.computercraft.core.terminal.TextBuffer;
1110
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
1211
import dan200.computercraft.shared.media.items.ItemPrintout;
13-
import dan200.computercraft.shared.util.Palette;
1412
import net.minecraft.client.gui.inventory.GuiContainer;
1513
import net.minecraft.client.renderer.GlStateManager;
16-
import net.minecraft.util.ResourceLocation;
1714
import org.lwjgl.input.Mouse;
1815

1916
import java.io.IOException;
2017

18+
import static dan200.computercraft.client.render.PrintoutRenderer.*;
19+
2120
public class GuiPrintout extends GuiContainer
2221
{
23-
public static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/printout.png" );
24-
public static final int X_SIZE = 172;
25-
public static final int Y_SIZE = 209;
26-
2722
private final boolean m_book;
2823
private final int m_pages;
2924
private final TextBuffer[] m_text;
@@ -33,23 +28,18 @@ public class GuiPrintout extends GuiContainer
3328
public GuiPrintout( ContainerHeldItem container )
3429
{
3530
super( container );
36-
m_book = (ItemPrintout.getType( container.getStack() ) == ItemPrintout.Type.Book);
3731

3832
String[] text = ItemPrintout.getText( container.getStack() );
3933
m_text = new TextBuffer[ text.length ];
40-
for( int i=0; i<m_text.length; ++i )
41-
{
42-
m_text[i] = new TextBuffer( text[i] );
43-
}
34+
for( int i = 0; i < m_text.length; ++i ) m_text[ i ] = new TextBuffer( text[ i ] );
35+
4436
String[] colours = ItemPrintout.getColours( container.getStack() );
4537
m_colours = new TextBuffer[ colours.length ];
46-
for( int i=0; i<m_colours.length; ++i )
47-
{
48-
m_colours[i] = new TextBuffer( colours[i] );
49-
}
38+
for( int i = 0; i < m_colours.length; ++i ) m_colours[ i ] = new TextBuffer( colours[ i ] );
5039

51-
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
5240
m_page = 0;
41+
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
42+
m_book = ItemPrintout.getType( container.getStack() ) == ItemPrintout.Type.Book;
5343
}
5444

5545
@Override
@@ -77,25 +67,19 @@ public void updateScreen()
7767
}
7868

7969
@Override
80-
protected void keyTyped(char c, int k) throws IOException
70+
protected void keyTyped( char c, int k ) throws IOException
8171
{
8272
super.keyTyped( c, k );
8373

8474
if( k == 205 )
8575
{
8676
// Right
87-
if( m_page < m_pages - 1 )
88-
{
89-
m_page = m_page + 1;
90-
}
77+
if( m_page < m_pages - 1 ) m_page++;
9178
}
9279
else if( k == 203 )
9380
{
94-
// Left
95-
if( m_page > 0 )
96-
{
97-
m_page = m_page - 1;
98-
}
81+
// Left
82+
if( m_page > 0 ) m_page--;
9983
}
10084
}
10185

@@ -105,21 +89,15 @@ public void handleMouseInput() throws IOException
10589
super.handleMouseInput();
10690

10791
int mouseWheelChange = Mouse.getEventDWheel();
108-
if (mouseWheelChange < 0)
92+
if( mouseWheelChange < 0 )
10993
{
11094
// Up
111-
if( m_page < m_pages - 1 )
112-
{
113-
m_page = m_page + 1;
114-
}
95+
if( m_page < m_pages - 1 ) m_page++;
11596
}
116-
else if (mouseWheelChange > 0)
97+
else if( mouseWheelChange > 0 )
11798
{
11899
// Down
119-
if( m_page > 0 )
120-
{
121-
m_page = m_page - 1;
122-
}
100+
if( m_page > 0 ) m_page--;
123101
}
124102
}
125103

@@ -134,78 +112,20 @@ protected void drawGuiContainerBackgroundLayer( float var1, int var2, int var3 )
134112
}
135113

136114
@Override
137-
public void drawScreen(int mouseX, int mouseY, float f)
115+
public void drawScreen( int mouseX, int mouseY, float f )
138116
{
139117
// Draw background
118+
zLevel = zLevel - 1;
140119
drawDefaultBackground();
141-
120+
zLevel = zLevel + 1;
121+
142122
// Draw the printout
143123
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
144-
this.mc.getTextureManager().bindTexture( BACKGROUND );
145-
124+
146125
int startY = (height - Y_SIZE) / 2;
147-
//int startX = (width - X_SIZE) / 2 - (m_page * 8);
148-
int startX = (width - (X_SIZE + (m_pages - 1)*8)) / 2;
149-
150-
if( m_book )
151-
{
152-
// Border
153-
drawTexturedModalRect( startX - 8, startY - 8, X_SIZE + 48, 0, 12, Y_SIZE + 24);
154-
drawTexturedModalRect( startX + X_SIZE + (m_pages - 1)*8 - 4, startY - 8, X_SIZE + 48 + 12, 0, 12, Y_SIZE + 24);
155-
156-
drawTexturedModalRect( startX, startY - 8, 0, Y_SIZE, X_SIZE, 12);
157-
drawTexturedModalRect( startX, startY + Y_SIZE - 4, 0, Y_SIZE + 12, X_SIZE, 12);
158-
for( int n=1; n<m_pages; ++n )
159-
{
160-
drawTexturedModalRect( startX + X_SIZE + (n-1)*8, startY - 8, 0, Y_SIZE, 8, 12);
161-
drawTexturedModalRect( startX + X_SIZE + (n-1)*8, startY + Y_SIZE - 4, 0, Y_SIZE + 12, 8, 12);
162-
}
163-
}
164-
165-
// Left half
166-
if( m_page == 0 )
167-
{
168-
drawTexturedModalRect( startX, startY, 24, 0, X_SIZE / 2, Y_SIZE );
169-
drawTexturedModalRect( startX, startY, 0, 0, 12, Y_SIZE );
170-
}
171-
else
172-
{
173-
drawTexturedModalRect( startX, startY, 0, 0, 12, Y_SIZE );
174-
for( int n=1; n<m_page; ++n )
175-
{
176-
drawTexturedModalRect( startX + n*8, startY, 12, 0, 12, Y_SIZE );
177-
}
178-
drawTexturedModalRect( startX + m_page*8, startY, 24, 0, X_SIZE / 2, Y_SIZE );
179-
}
180-
181-
// Right half
182-
if( m_page == (m_pages - 1) )
183-
{
184-
drawTexturedModalRect( startX + m_page*8 + X_SIZE /2, startY, 24 + X_SIZE / 2, 0, X_SIZE / 2, Y_SIZE );
185-
drawTexturedModalRect( startX + m_page*8 + (X_SIZE - 12), startY, 24 + X_SIZE + 12, 0, 12, Y_SIZE );
186-
}
187-
else
188-
{
189-
drawTexturedModalRect( startX + (m_pages - 1)*8 + (X_SIZE - 12), startY, 24 + X_SIZE + 12, 0, 12, Y_SIZE );
190-
for( int n=m_pages-2; n>=m_page; --n )
191-
{
192-
drawTexturedModalRect( startX + n*8 + (X_SIZE - 12), startY, 24 + X_SIZE, 0, 12, Y_SIZE );
193-
}
194-
drawTexturedModalRect( startX + m_page*8 + X_SIZE /2, startY, 24 + X_SIZE / 2, 0, X_SIZE / 2, Y_SIZE );
195-
}
126+
int startX = (width - X_SIZE) / 2;
196127

197-
// Draw the text
198-
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer)ComputerCraft.getFixedWidthFontRenderer();
199-
int x = startX + m_page * 8 + 13;
200-
int y = startY + 11;
201-
for( int line=0; line<ItemPrintout.LINES_PER_PAGE; ++line )
202-
{
203-
int lineIdx = ItemPrintout.LINES_PER_PAGE * m_page + line;
204-
if( lineIdx >= 0 && lineIdx < m_text.length )
205-
{
206-
fontRenderer.drawString( m_text[lineIdx], x, y, m_colours[lineIdx], null, 0, 0, false, Palette.DEFAULT );
207-
}
208-
y = y + FixedWidthFontRenderer.FONT_HEIGHT;
209-
}
128+
drawBorder( startX, startY, zLevel, m_page, m_pages, m_book );
129+
drawText( startX + X_TEXT_MARGIN, startY + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
210130
}
211131
}

src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java

Lines changed: 24 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
package dan200.computercraft.client.render;
22

33
import dan200.computercraft.ComputerCraft;
4-
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
5-
import dan200.computercraft.client.gui.GuiPrintout;
6-
import dan200.computercraft.core.terminal.TextBuffer;
74
import dan200.computercraft.shared.media.items.ItemPrintout;
8-
import dan200.computercraft.shared.util.Palette;
95
import net.minecraft.client.Minecraft;
10-
import net.minecraft.client.renderer.BufferBuilder;
116
import net.minecraft.client.renderer.GlStateManager;
127
import net.minecraft.client.renderer.ItemRenderer;
13-
import net.minecraft.client.renderer.Tessellator;
14-
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
158
import net.minecraft.entity.player.EntityPlayer;
169
import net.minecraft.item.ItemStack;
1710
import net.minecraft.util.EnumHand;
@@ -20,10 +13,10 @@
2013
import net.minecraftforge.client.event.RenderItemInFrameEvent;
2114
import net.minecraftforge.client.event.RenderSpecificHandEvent;
2215
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
23-
import org.lwjgl.opengl.GL11;
2416

2517
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
2618
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
19+
import static dan200.computercraft.client.render.PrintoutRenderer.*;
2720
import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE;
2821
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
2922

@@ -35,9 +28,6 @@ public void onRenderInHand( RenderSpecificHandEvent event )
3528
ItemStack stack = event.getItemStack();
3629
if( stack.getItem() != ComputerCraft.Items.printout ) return;
3730

38-
// We only allow single pages to be viewed in-hand for now
39-
if( ItemPrintout.getType( stack ) != ItemPrintout.Type.Single ) return;
40-
4131
event.setCanceled( true );
4232

4333
EntityPlayer player = Minecraft.getMinecraft().player;
@@ -145,8 +135,8 @@ private static void renderPrintoutFirstPerson( ItemStack stack )
145135

146136
GlStateManager.rotate( 180f, 0f, 1f, 0f );
147137
GlStateManager.rotate( 180f, 0f, 0f, 1f );
148-
GlStateManager.scale( 0.38f, 0.38f, 0.38f );
149-
GlStateManager.translate( -0.5f, -0.5f, 0.0f );
138+
GlStateManager.scale( 0.42f, 0.42f, -0.42f );
139+
GlStateManager.translate( -0.5f, -0.48f, 0.0f );
150140

151141
drawPrintout( stack );
152142

@@ -159,16 +149,14 @@ public void onRenderInFrame( RenderItemInFrameEvent event )
159149
ItemStack stack = event.getItem();
160150
if( stack.getItem() != ComputerCraft.Items.printout ) return;
161151

162-
// We only allow single pages to be viewed in-hand for now
163-
if( ItemPrintout.getType( stack ) != ItemPrintout.Type.Single ) return;
164-
165152
event.setCanceled( true );
166153

167154
GlStateManager.disableLighting();
168155

169156
// Move a little bit forward to ensure we're not clipping with the frame
170157
GlStateManager.translate( 0.0f, 0.0f, -0.001f );
171158
GlStateManager.rotate( 180f, 0f, 0f, 1f );
159+
GlStateManager.scale( 0.95f, 0.95f, -0.95f );
172160
GlStateManager.translate( -0.5f, -0.5f, 0.0f );
173161

174162
drawPrintout( stack );
@@ -178,42 +166,32 @@ public void onRenderInFrame( RenderItemInFrameEvent event )
178166

179167
private static void drawPrintout( ItemStack stack )
180168
{
181-
int xMargin = 13;
182-
int yMargin = 11;
183-
184-
int width = LINE_MAX_LENGTH * FONT_WIDTH + xMargin * 2;
185-
int height = LINES_PER_PAGE * FONT_HEIGHT + yMargin * 2;
186-
int max = Math.max( height, width );
169+
int pages = ItemPrintout.getPageCount( stack );
170+
boolean book = ItemPrintout.getType( stack ) == ItemPrintout.Type.Book;
187171

188-
// Scale the printout to fit correctly.
189-
double scale = 1.0 / max;
190-
GlStateManager.scale( scale, scale, scale );
191-
GlStateManager.translate( (max - width) / 2.0f, (max - height) / 2.0f, 0.0f );
172+
double width = LINE_MAX_LENGTH * FONT_WIDTH + X_TEXT_MARGIN * 2;
173+
double height = LINES_PER_PAGE * FONT_HEIGHT + Y_TEXT_MARGIN * 2;
192174

193-
drawBackground( 0, 0, 0.01 );
175+
// Non-books will be left aligned
176+
if( !book ) width += offsetAt( pages );
194177

195-
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer) ComputerCraft.getFixedWidthFontRenderer();
178+
double visualWidth = width, visualHeight = height;
196179

197-
String[] text = ItemPrintout.getText( stack );
198-
String[] colours = ItemPrintout.getColours( stack );
199-
for( int line = 0; line < LINES_PER_PAGE && line < text.length; ++line )
180+
// Meanwhile books will be centred
181+
if( book )
200182
{
201-
fontRenderer.drawString( new TextBuffer( text[ line ] ), xMargin, yMargin + line * FONT_HEIGHT, new TextBuffer( colours[ line ] ), null, 0, 0, false, Palette.DEFAULT );
183+
visualWidth += 2 * COVER_SIZE + 2 * offsetAt( pages );
184+
visualHeight += 2 * COVER_SIZE;
202185
}
203-
}
204186

205-
private static void drawBackground( double x, double y, double z )
206-
{
207-
Minecraft mc = Minecraft.getMinecraft();
208-
mc.getTextureManager().bindTexture( GuiPrintout.BACKGROUND );
209-
210-
Tessellator tessellator = Tessellator.getInstance();
211-
BufferBuilder buffer = tessellator.getBuffer();
212-
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX );
213-
buffer.pos( x, y + GuiPrintout.Y_SIZE, z ).tex( 24 / 256.0, GuiPrintout.Y_SIZE / 256.0 ).endVertex();
214-
buffer.pos( x + GuiPrintout.X_SIZE, y + GuiPrintout.Y_SIZE, z ).tex( (24 + GuiPrintout.X_SIZE) / 256.0, GuiPrintout.Y_SIZE / 256.0 ).endVertex();
215-
buffer.pos( x + GuiPrintout.X_SIZE, y, z ).tex( (24 + GuiPrintout.X_SIZE) / 256.0, 0 ).endVertex();
216-
buffer.pos( x, y, z ).tex( 24 / 256.0, 0 ).endVertex();
217-
tessellator.draw();
187+
double max = Math.max( visualHeight, visualWidth );
188+
189+
// Scale the printout to fit correctly.
190+
double scale = 1.0 / max;
191+
GlStateManager.scale( scale, scale, scale );
192+
GlStateManager.translate( (max - width) / 2.0f, (max - height) / 2.0f, 0.0f );
193+
194+
drawBorder( 0, 0, -0.01, 0, pages, book );
195+
drawText( X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack ) );
218196
}
219197
}

0 commit comments

Comments
 (0)