Advertisement
Corosus

Untitled

Nov 30th, 2013
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 18.51 KB | None | 0 0
  1. package net.minecraft.client.renderer;
  2.  
  3. import cpw.mods.fml.relauncher.Side;
  4. import cpw.mods.fml.relauncher.SideOnly;
  5. import java.nio.ByteBuffer;
  6. import java.nio.ByteOrder;
  7. import java.nio.FloatBuffer;
  8. import java.nio.IntBuffer;
  9. import java.nio.ShortBuffer;
  10. import java.util.Arrays;
  11.  
  12. import org.lwjgl.opengl.ARBVertexBufferObject;
  13. import org.lwjgl.opengl.GL11;
  14. import org.lwjgl.opengl.GLContext;
  15.  
  16. @SideOnly(Side.CLIENT)
  17. public class Tessellator
  18. {
  19.     private static int nativeBufferSize = 0x200000;
  20.     private static int trivertsInBuffer = (nativeBufferSize / 48) * 6;
  21.     public static boolean renderingWorldRenderer = false;
  22.     public boolean defaultTexture = false;
  23.     private int rawBufferSize = 0;
  24.     public int textureID = 0;
  25.     /**
  26.      * Boolean used to check whether quads should be drawn as two triangles. Initialized to false and never changed.
  27.      */
  28.     private static boolean convertQuadsToTriangles;
  29.  
  30.     /**
  31.      * Boolean used to check if we should use vertex buffers. Initialized to false and never changed.
  32.      */
  33.     private static boolean tryVBO;
  34.  
  35.     /** The byte buffer used for GL allocation. */
  36.     private static ByteBuffer byteBuffer = GLAllocation.createDirectByteBuffer(nativeBufferSize * 4);
  37.  
  38.     /** The same memory as byteBuffer, but referenced as an integer buffer. */
  39.     private static IntBuffer intBuffer = byteBuffer.asIntBuffer();
  40.  
  41.     /** The same memory as byteBuffer, but referenced as an float buffer. */
  42.     private static FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
  43.  
  44.     /** Short buffer */
  45.     private static ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
  46.  
  47.     /** Raw integer array. */
  48.     private int[] rawBuffer;
  49.  
  50.     /**
  51.      * The number of vertices to be drawn in the next draw call. Reset to 0 between draw calls.
  52.      */
  53.     private int vertexCount;
  54.  
  55.     /** The first coordinate to be used for the texture. */
  56.     private double textureU;
  57.  
  58.     /** The second coordinate to be used for the texture. */
  59.     private double textureV;
  60.     private int brightness;
  61.  
  62.     /** The color (RGBA) value to be used for the following draw call. */
  63.     private int color;
  64.  
  65.     /**
  66.      * Whether the current draw object for this tessellator has color values.
  67.      */
  68.     private boolean hasColor;
  69.  
  70.     /**
  71.      * Whether the current draw object for this tessellator has texture coordinates.
  72.      */
  73.     private boolean hasTexture;
  74.     private boolean hasBrightness;
  75.  
  76.     /**
  77.      * Whether the current draw object for this tessellator has normal values.
  78.      */
  79.     private boolean hasNormals;
  80.  
  81.     /** The index into the raw buffer to be used for the next data. */
  82.     private int rawBufferIndex;
  83.  
  84.     /**
  85.      * The number of vertices manually added to the given draw call. This differs from vertexCount because it adds extra
  86.      * vertices when converting quads to triangles.
  87.      */
  88.     private int addedVertices;
  89.  
  90.     /** Disables all color information for the following draw call. */
  91.     private boolean isColorDisabled;
  92.  
  93.     /** The draw mode currently being used by the tessellator. */
  94.     public int drawMode;
  95.  
  96.     /**
  97.      * An offset to be applied along the x-axis for all vertices in this draw call.
  98.      */
  99.     public double xOffset;
  100.  
  101.     /**
  102.      * An offset to be applied along the y-axis for all vertices in this draw call.
  103.      */
  104.     public double yOffset;
  105.  
  106.     /**
  107.      * An offset to be applied along the z-axis for all vertices in this draw call.
  108.      */
  109.     public double zOffset;
  110.  
  111.     /** The normal to be applied to the face being drawn. */
  112.     private int normal;
  113.  
  114.     /** The static instance of the Tessellator. */
  115.     public static Tessellator instance = new Tessellator(2097152);
  116.  
  117.     /** Whether this tessellator is currently in draw mode. */
  118.     public boolean isDrawing;
  119.  
  120.     /** Whether we are currently using VBO or not. */
  121.     private static boolean useVBO = false;
  122.  
  123.     /** An IntBuffer used to store the indices of vertex buffer objects. */
  124.     private static IntBuffer vertexBuffers;
  125.  
  126.     /**
  127.      * The index of the last VBO used. This is used in round-robin fashion, sequentially, through the vboCount vertex
  128.      * buffers.
  129.      */
  130.     private int vboIndex;
  131.  
  132.     /** Number of vertex buffer objects allocated for use. */
  133.     private static int vboCount = 10;
  134.  
  135.     /** The size of the buffers used (in integers). */
  136.     private int bufferSize;
  137.  
  138.     private Tessellator(int par1)
  139.     {
  140.     }
  141.    
  142.     public Tessellator()
  143.     {
  144.     }
  145.    
  146.     static
  147.     {
  148.         instance.defaultTexture = true;
  149.         useVBO = tryVBO && GLContext.getCapabilities().GL_ARB_vertex_buffer_object;
  150.  
  151.         if (useVBO)
  152.         {
  153.             vertexBuffers = GLAllocation.createDirectIntBuffer(vboCount);
  154.             ARBVertexBufferObject.glGenBuffersARB(vertexBuffers);
  155.         }
  156.     }
  157.  
  158.     /**
  159.      * Draws the data set up in this tessellator and resets the state to prepare for new drawing.
  160.      */
  161.     public int draw()
  162.     {
  163.         if (!this.isDrawing)
  164.         {
  165.             throw new IllegalStateException("Not tesselating!");
  166.         }
  167.         else
  168.         {
  169.             this.isDrawing = false;
  170.  
  171.             int offs = 0;
  172.             while (offs < vertexCount)
  173.             {
  174.                 int vtc = 0;
  175.                 if (drawMode == 7 && convertQuadsToTriangles)
  176.                 {
  177.                     vtc = Math.min(vertexCount - offs, trivertsInBuffer);
  178.                 }
  179.                 else
  180.                 {
  181.                     vtc = Math.min(vertexCount - offs, nativeBufferSize >> 5);
  182.                 }
  183.                 this.intBuffer.clear();
  184.                 this.intBuffer.put(this.rawBuffer, offs * 8, vtc * 8);
  185.                 this.byteBuffer.position(0);
  186.                 this.byteBuffer.limit(vtc * 32);
  187.                 offs += vtc;
  188.  
  189.                 if (this.useVBO)
  190.                 {
  191.                     this.vboIndex = (this.vboIndex + 1) % this.vboCount;
  192.                     ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.vertexBuffers.get(this.vboIndex));
  193.                     ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.byteBuffer, ARBVertexBufferObject.GL_STREAM_DRAW_ARB);
  194.                 }
  195.  
  196.                 if (this.hasTexture)
  197.                 {
  198.                     if (this.useVBO)
  199.                     {
  200.                         GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 32, 12L);
  201.                     }
  202.                     else
  203.                     {
  204.                         this.floatBuffer.position(3);
  205.                         GL11.glTexCoordPointer(2, 32, this.floatBuffer);
  206.                     }
  207.  
  208.                     GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
  209.                 }
  210.  
  211.                 if (this.hasBrightness)
  212.                 {
  213.                     OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
  214.  
  215.                     if (this.useVBO)
  216.                     {
  217.                         GL11.glTexCoordPointer(2, GL11.GL_SHORT, 32, 28L);
  218.                     }
  219.                     else
  220.                     {
  221.                         this.shortBuffer.position(14);
  222.                         GL11.glTexCoordPointer(2, 32, this.shortBuffer);
  223.                     }
  224.  
  225.                     GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
  226.                     OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
  227.                 }
  228.  
  229.                 if (this.hasColor)
  230.                 {
  231.                     if (this.useVBO)
  232.                     {
  233.                         GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 32, 20L);
  234.                     }
  235.                     else
  236.                     {
  237.                         this.byteBuffer.position(20);
  238.                         GL11.glColorPointer(4, true, 32, this.byteBuffer);
  239.                     }
  240.  
  241.                     GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
  242.                 }
  243.  
  244.                 if (this.hasNormals)
  245.                 {
  246.                     if (this.useVBO)
  247.                     {
  248.                         GL11.glNormalPointer(GL11.GL_UNSIGNED_BYTE, 32, 24L);
  249.                     }
  250.                     else
  251.                     {
  252.                         this.byteBuffer.position(24);
  253.                         GL11.glNormalPointer(32, this.byteBuffer);
  254.                     }
  255.  
  256.                     GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
  257.                 }
  258.  
  259.                 if (this.useVBO)
  260.                 {
  261.                     GL11.glVertexPointer(3, GL11.GL_FLOAT, 32, 0L);
  262.                 }
  263.                 else
  264.                 {
  265.                     this.floatBuffer.position(0);
  266.                     GL11.glVertexPointer(3, 32, this.floatBuffer);
  267.                 }
  268.  
  269.                 GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
  270.  
  271.                 if (this.drawMode == 7 && convertQuadsToTriangles)
  272.                 {
  273.                     GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vtc);
  274.                 }
  275.                 else
  276.                 {
  277.                     GL11.glDrawArrays(this.drawMode, 0, vtc);
  278.                 }
  279.  
  280.                 GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
  281.  
  282.                 if (this.hasTexture)
  283.                 {
  284.                     GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
  285.                 }
  286.  
  287.                 if (this.hasBrightness)
  288.                 {
  289.                     OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
  290.                     GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
  291.                     OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
  292.                 }
  293.  
  294.                 if (this.hasColor)
  295.                 {
  296.                     GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
  297.                 }
  298.  
  299.                 if (this.hasNormals)
  300.                 {
  301.                     GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
  302.                 }
  303.             }
  304.  
  305.             if (rawBufferSize > 0x20000 && rawBufferIndex < (rawBufferSize << 3))
  306.             {
  307.                 rawBufferSize = 0;
  308.                 rawBuffer = null;
  309.             }
  310.  
  311.             int i = this.rawBufferIndex * 4;
  312.             this.reset();
  313.             return i;
  314.         }
  315.     }
  316.  
  317.     /**
  318.      * Clears the tessellator state in preparation for new drawing.
  319.      */
  320.     private void reset()
  321.     {
  322.         this.vertexCount = 0;
  323.         this.byteBuffer.clear();
  324.         this.rawBufferIndex = 0;
  325.         this.addedVertices = 0;
  326.     }
  327.  
  328.     /**
  329.      * Sets draw mode in the tessellator to draw quads.
  330.      */
  331.     public void startDrawingQuads()
  332.     {
  333.         this.startDrawing(7);
  334.     }
  335.  
  336.     /**
  337.      * Resets tessellator state and prepares for drawing (with the specified draw mode).
  338.      */
  339.     public void startDrawing(int par1)
  340.     {
  341.         if (this.isDrawing)
  342.         {
  343.             throw new IllegalStateException("Already tesselating!");
  344.         }
  345.         else
  346.         {
  347.             this.isDrawing = true;
  348.             this.reset();
  349.             this.drawMode = par1;
  350.             this.hasNormals = false;
  351.             this.hasColor = false;
  352.             this.hasTexture = false;
  353.             this.hasBrightness = false;
  354.             this.isColorDisabled = false;
  355.         }
  356.     }
  357.  
  358.     /**
  359.      * Sets the texture coordinates.
  360.      */
  361.     public void setTextureUV(double par1, double par3)
  362.     {
  363.         this.hasTexture = true;
  364.         this.textureU = par1;
  365.         this.textureV = par3;
  366.     }
  367.  
  368.     public void setBrightness(int par1)
  369.     {
  370.         this.hasBrightness = true;
  371.         this.brightness = par1;
  372.     }
  373.  
  374.     /**
  375.      * Sets the RGB values as specified, converting from floats between 0 and 1 to integers from 0-255.
  376.      */
  377.     public void setColorOpaque_F(float par1, float par2, float par3)
  378.     {
  379.         this.setColorOpaque((int)(par1 * 255.0F), (int)(par2 * 255.0F), (int)(par3 * 255.0F));
  380.     }
  381.  
  382.     /**
  383.      * Sets the RGBA values for the color, converting from floats between 0 and 1 to integers from 0-255.
  384.      */
  385.     public void setColorRGBA_F(float par1, float par2, float par3, float par4)
  386.     {
  387.         this.setColorRGBA((int)(par1 * 255.0F), (int)(par2 * 255.0F), (int)(par3 * 255.0F), (int)(par4 * 255.0F));
  388.     }
  389.  
  390.     /**
  391.      * Sets the RGB values as specified, and sets alpha to opaque.
  392.      */
  393.     public void setColorOpaque(int par1, int par2, int par3)
  394.     {
  395.         this.setColorRGBA(par1, par2, par3, 255);
  396.     }
  397.  
  398.     /**
  399.      * Sets the RGBA values for the color. Also clamps them to 0-255.
  400.      */
  401.     public void setColorRGBA(int par1, int par2, int par3, int par4)
  402.     {
  403.         if (!this.isColorDisabled)
  404.         {
  405.             if (par1 > 255)
  406.             {
  407.                 par1 = 255;
  408.             }
  409.  
  410.             if (par2 > 255)
  411.             {
  412.                 par2 = 255;
  413.             }
  414.  
  415.             if (par3 > 255)
  416.             {
  417.                 par3 = 255;
  418.             }
  419.  
  420.             if (par4 > 255)
  421.             {
  422.                 par4 = 255;
  423.             }
  424.  
  425.             if (par1 < 0)
  426.             {
  427.                 par1 = 0;
  428.             }
  429.  
  430.             if (par2 < 0)
  431.             {
  432.                 par2 = 0;
  433.             }
  434.  
  435.             if (par3 < 0)
  436.             {
  437.                 par3 = 0;
  438.             }
  439.  
  440.             if (par4 < 0)
  441.             {
  442.                 par4 = 0;
  443.             }
  444.  
  445.             this.hasColor = true;
  446.  
  447.             if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN)
  448.             {
  449.                 this.color = par4 << 24 | par3 << 16 | par2 << 8 | par1;
  450.             }
  451.             else
  452.             {
  453.                 this.color = par1 << 24 | par2 << 16 | par3 << 8 | par4;
  454.             }
  455.         }
  456.     }
  457.  
  458.     /**
  459.      * Adds a vertex specifying both x,y,z and the texture u,v for it.
  460.      */
  461.     public void addVertexWithUV(double par1, double par3, double par5, double par7, double par9)
  462.     {
  463.         this.setTextureUV(par7, par9);
  464.         this.addVertex(par1, par3, par5);
  465.     }
  466.  
  467.     /**
  468.      * Adds a vertex with the specified x,y,z to the current draw call. It will trigger a draw() if the buffer gets
  469.      * full.
  470.      */
  471.     public void addVertex(double par1, double par3, double par5)
  472.     {
  473.         if (rawBufferIndex >= rawBufferSize - 32)
  474.         {
  475.             if (rawBufferSize == 0)
  476.             {
  477.                 rawBufferSize = 0x10000;
  478.                 rawBuffer = new int[rawBufferSize];
  479.             }
  480.             else
  481.             {
  482.                 rawBufferSize *= 2;
  483.                 rawBuffer = Arrays.copyOf(rawBuffer, rawBufferSize);
  484.             }
  485.         }
  486.         ++this.addedVertices;
  487.  
  488.         if (this.drawMode == 7 && convertQuadsToTriangles && this.addedVertices % 4 == 0)
  489.         {
  490.             for (int i = 0; i < 2; ++i)
  491.             {
  492.                 int j = 8 * (3 - i);
  493.  
  494.                 if (this.hasTexture)
  495.                 {
  496.                     this.rawBuffer[this.rawBufferIndex + 3] = this.rawBuffer[this.rawBufferIndex - j + 3];
  497.                     this.rawBuffer[this.rawBufferIndex + 4] = this.rawBuffer[this.rawBufferIndex - j + 4];
  498.                 }
  499.  
  500.                 if (this.hasBrightness)
  501.                 {
  502.                     this.rawBuffer[this.rawBufferIndex + 7] = this.rawBuffer[this.rawBufferIndex - j + 7];
  503.                 }
  504.  
  505.                 if (this.hasColor)
  506.                 {
  507.                     this.rawBuffer[this.rawBufferIndex + 5] = this.rawBuffer[this.rawBufferIndex - j + 5];
  508.                 }
  509.  
  510.                 this.rawBuffer[this.rawBufferIndex + 0] = this.rawBuffer[this.rawBufferIndex - j + 0];
  511.                 this.rawBuffer[this.rawBufferIndex + 1] = this.rawBuffer[this.rawBufferIndex - j + 1];
  512.                 this.rawBuffer[this.rawBufferIndex + 2] = this.rawBuffer[this.rawBufferIndex - j + 2];
  513.                 ++this.vertexCount;
  514.                 this.rawBufferIndex += 8;
  515.             }
  516.         }
  517.  
  518.         if (this.hasTexture)
  519.         {
  520.             this.rawBuffer[this.rawBufferIndex + 3] = Float.floatToRawIntBits((float)this.textureU);
  521.             this.rawBuffer[this.rawBufferIndex + 4] = Float.floatToRawIntBits((float)this.textureV);
  522.         }
  523.  
  524.         if (this.hasBrightness)
  525.         {
  526.             this.rawBuffer[this.rawBufferIndex + 7] = this.brightness;
  527.         }
  528.  
  529.         if (this.hasColor)
  530.         {
  531.             this.rawBuffer[this.rawBufferIndex + 5] = this.color;
  532.         }
  533.  
  534.         if (this.hasNormals)
  535.         {
  536.             this.rawBuffer[this.rawBufferIndex + 6] = this.normal;
  537.         }
  538.  
  539.         this.rawBuffer[this.rawBufferIndex + 0] = Float.floatToRawIntBits((float)(par1 + this.xOffset));
  540.         this.rawBuffer[this.rawBufferIndex + 1] = Float.floatToRawIntBits((float)(par3 + this.yOffset));
  541.         this.rawBuffer[this.rawBufferIndex + 2] = Float.floatToRawIntBits((float)(par5 + this.zOffset));
  542.         this.rawBufferIndex += 8;
  543.         ++this.vertexCount;
  544.     }
  545.  
  546.     /**
  547.      * Sets the color to the given opaque value (stored as byte values packed in an integer).
  548.      */
  549.     public void setColorOpaque_I(int par1)
  550.     {
  551.         int j = par1 >> 16 & 255;
  552.         int k = par1 >> 8 & 255;
  553.         int l = par1 & 255;
  554.         this.setColorOpaque(j, k, l);
  555.     }
  556.  
  557.     /**
  558.      * Sets the color to the given color (packed as bytes in integer) and alpha values.
  559.      */
  560.     public void setColorRGBA_I(int par1, int par2)
  561.     {
  562.         int k = par1 >> 16 & 255;
  563.         int l = par1 >> 8 & 255;
  564.         int i1 = par1 & 255;
  565.         this.setColorRGBA(k, l, i1, par2);
  566.     }
  567.  
  568.     /**
  569.      * Disables colors for the current draw call.
  570.      */
  571.     public void disableColor()
  572.     {
  573.         this.isColorDisabled = true;
  574.     }
  575.  
  576.     /**
  577.      * Sets the normal for the current draw call.
  578.      */
  579.     public void setNormal(float par1, float par2, float par3)
  580.     {
  581.         this.hasNormals = true;
  582.         byte b0 = (byte)((int)(par1 * 127.0F));
  583.         byte b1 = (byte)((int)(par2 * 127.0F));
  584.         byte b2 = (byte)((int)(par3 * 127.0F));
  585.         this.normal = b0 & 255 | (b1 & 255) << 8 | (b2 & 255) << 16;
  586.     }
  587.  
  588.     /**
  589.      * Sets the translation for all vertices in the current draw call.
  590.      */
  591.     public void setTranslation(double par1, double par3, double par5)
  592.     {
  593.         this.xOffset = par1;
  594.         this.yOffset = par3;
  595.         this.zOffset = par5;
  596.     }
  597.  
  598.     /**
  599.      * Offsets the translation for all vertices in the current draw call.
  600.      */
  601.     public void addTranslation(float par1, float par2, float par3)
  602.     {
  603.         this.xOffset += (double)par1;
  604.         this.yOffset += (double)par2;
  605.         this.zOffset += (double)par3;
  606.     }
  607. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement