Advertisement
bobmarley12345

C++ Minecraft Tessellator (1.6.4)

Nov 25th, 2023 (edited)
591
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.17 KB | None | 0 0
  1. #ifndef RZUIGL_TESSELLATOR_H
  2. #define RZUIGL_TESSELLATOR_H
  3.  
  4. #define FLOAT_TO_INT_BITS(floatVar) (*(int*) &floatVar)
  5.  
  6. #include "GL/glew.h"
  7. #include "glm/glm.hpp"
  8. #include "../glfw/deps/linmath.h"
  9.  
  10. class Tessellator {
  11. private:
  12.     int* rawBuffer;
  13.  
  14.     /**
  15.      * The number of vertices to be drawn in the next draw call. Reset to 0 between draw calls.
  16.      */
  17.     int vertexCount;
  18.  
  19.     /**
  20.      * The first coordinate to be used for the texture.
  21.      */
  22.     double textureU;
  23.  
  24.     /**
  25.      * The second coordinate to be used for the texture.
  26.      */
  27.     double textureV;
  28.     int brightness;
  29.  
  30.     /**
  31.      * The color (RGBA) value to be used for the following draw call.
  32.      */
  33.     int color;
  34.  
  35.     /**
  36.      * Whether the current draw object for this tessellator has color values.
  37.      */
  38.     bool hasColor;
  39.  
  40.     /**
  41.      * Whether the current draw object for this tessellator has texture coordinates.
  42.      */
  43.     bool hasTexture;
  44.     bool hasBrightness;
  45.  
  46.     /**
  47.      * Whether the current draw object for this tessellator has normal values.
  48.      */
  49.     bool hasNormals;
  50.  
  51.     /**
  52.      * The index into the raw buffer to be used for the next data.
  53.      */
  54.     int rawBufferIndex;
  55.  
  56.     /**
  57.      * The number of vertices manually added to the given draw call. This differs from vertexCount because it adds extra
  58.      * vertices when converting quads to triangles.
  59.      */
  60.     int addedVertices;
  61.  
  62.     /**
  63.      * Disables all color information for the following draw call.
  64.      */
  65.     bool isColourEnabled = true;
  66.  
  67.     /**
  68.      * The draw mode currently being used by the tessellator.
  69.      */
  70. public:
  71.     int drawMode;
  72.  
  73.     /**
  74.      * An offset to be applied along the x-axis for all vertices in this draw call.
  75.      */
  76.     double offsetX;
  77.  
  78.     /**
  79.      * An offset to be applied along the y-axis for all vertices in this draw call.
  80.      */
  81.     double offsetY;
  82.  
  83.     /**
  84.      * An offset to be applied along the z-axis for all vertices in this draw call.
  85.      */
  86.     double offsetZ;
  87.  
  88.     /**
  89.      * The normal to be applied to the face being drawn.
  90.      */
  91. private:
  92.     int normal;
  93.  
  94.     /**
  95.      * Whether this tessellator is currently in draw mode.
  96.      */
  97. public:
  98.     bool isDrawing;
  99.  
  100.     /**
  101.      * The size of the buffers used (in integers).
  102.      */
  103. private:
  104.     int bufferSize;
  105.  
  106. public:
  107.     bool autoGrow;
  108.  
  109. public:
  110.  
  111.     explicit Tessellator(int bufferSize) {
  112.         this->autoGrow = true;
  113.         this->bufferSize = bufferSize;
  114.         this->rawBuffer = new int[bufferSize];
  115.         this->vertexCount = 0;
  116.         this->textureU = 0;
  117.         this->textureV = 0;
  118.         this->brightness = 0;
  119.         this->color = 0;
  120.         this->hasColor = false;
  121.         this->hasTexture = false;
  122.         this->hasBrightness = false;
  123.         this->hasNormals = false;
  124.         this->rawBufferIndex = 0;
  125.         this->addedVertices = 0;
  126.         this->isColourEnabled = false;
  127.         this->drawMode = 0;
  128.         this->offsetX = 0;
  129.         this->offsetY = 0;
  130.         this->offsetZ = 0;
  131.         this->normal = 0;
  132.         this->isDrawing = false;
  133.         this->bufferSize = 0;
  134.         this->autoGrow = false;
  135.  
  136.     }
  137.  
  138.     /**
  139.      * Draws the data set up in this tessellator and resets the state to prepare for new drawing.
  140.      */
  141. public:
  142.     int draw() {
  143.         if (!this->isDrawing) {
  144.             // throw "Not tessellating!"
  145.             return 0;
  146.         }
  147.  
  148.         this->isDrawing = false;
  149.         if (this->vertexCount > 0) {
  150.             if (this->hasTexture) {
  151.                 glTexCoordPointer(2, GL_FLOAT, 32, (void*) (sizeof(float) * 3));
  152.                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  153.             }
  154.  
  155.             if (this->hasBrightness) {
  156.                 // OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
  157.                 glTexCoordPointer(2, GL_FLOAT, 32, (void*) (sizeof(int16_t) * 14));
  158.                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  159.                 // OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
  160.             }
  161.  
  162.             if (this->hasColor) {
  163.                 glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*) 20);
  164.                 glEnableClientState(GL_COLOR_ARRAY);
  165.             }
  166.  
  167.             if (this->hasNormals) {
  168.                 glNormalPointer(GL_FLOAT, 32, (void*) 24);
  169.                 glEnableClientState(GL_NORMAL_ARRAY);
  170.             }
  171.  
  172.             glVertexPointer(3, GL_FLOAT, 32, this->rawBuffer);
  173.             glEnableClientState(GL_VERTEX_ARRAY);
  174.             glDrawArrays(this->drawMode, 0, this->vertexCount);
  175.             glDisableClientState(GL_VERTEX_ARRAY);
  176.  
  177.             if (this->hasTexture) {
  178.                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  179.             }
  180.  
  181.             if (this->hasBrightness) {
  182.                 // OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
  183.                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  184.                 // OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
  185.             }
  186.  
  187.             if (this->hasColor) {
  188.                 glDisableClientState(GL_COLOR_ARRAY);
  189.             }
  190.  
  191.             if (this->hasNormals) {
  192.                 glDisableClientState(GL_NORMAL_ARRAY);
  193.             }
  194.         }
  195.  
  196.         int index = this->rawBufferIndex * 4;
  197.         this->reset();
  198.         return index;
  199.     }
  200.  
  201. private:
  202.  
  203.     /**
  204.  * Clears the tessellator state in preparation for new drawing.
  205.  */
  206.     void reset() {
  207.         this->vertexCount = 0;
  208.         this->rawBufferIndex = 0;
  209.         this->addedVertices = 0;
  210.     }
  211.  
  212. public:
  213.  
  214.     /**
  215.     * Sets draw mode in the tessellator to draw quads.
  216.     */
  217.     void startDrawingQuads() {
  218.         this->startDrawing(GL_QUADS);
  219.     }
  220.  
  221.     /**
  222.      * Resets tessellator state and prepares for drawing (with the specified draw mode).
  223.      */
  224.  
  225.     void startDrawing(int glMode) {
  226.         if (this->isDrawing) {
  227.             return; // throw new IllegalStateException("Already tessellating!");
  228.         }
  229.         this->isDrawing = true;
  230.         this->reset();
  231.         this->drawMode = glMode;
  232.         this->hasNormals = false;
  233.         this->hasColor = false;
  234.         this->hasTexture = false;
  235.         this->hasBrightness = false;
  236.         this->isColourEnabled = true;
  237.     }
  238.  
  239.     /**
  240.      * Sets the texture coordinates.
  241.      */
  242.  
  243.     void setTextureUV(double u, double v) {
  244.         this->hasTexture = true;
  245.         this->textureU = u;
  246.         this->textureV = v;
  247.     }
  248.  
  249.  
  250.     void setBrightness(int brightness) {
  251.         this->hasBrightness = true;
  252.         this->brightness = brightness;
  253.     }
  254.  
  255.     /**
  256.      * Sets the RGB values as specified, converting from floats between 0 and 1 to integers from 0-255.
  257.      */
  258.  
  259.     void setColourOpaque(float r, float g, float b) {
  260.         this->setColourOpaque((int) (r * 255.0F), (int) (g * 255.0F), (int) (b * 255.0F));
  261.     }
  262.  
  263.     /**
  264.      * Sets the RGBA values for the color, converting from floats between 0 and 1 to integers from 0-255.
  265.      */
  266.  
  267.     void setColourRGBA(float r, float g, float b, float a) {
  268.         this->setColourRGBA((int) (r * 255.0F), (int) (g * 255.0F), (int) (b * 255.0F), (int) (a * 255.0F));
  269.     }
  270.  
  271.     /**
  272.      * Sets the RGB values as specified, and sets alpha to opaque.
  273.      */
  274.  
  275.     void setColourOpaque(int r, int g, int b) {
  276.         this->setColourRGBA(r, g, b, 255);
  277.     }
  278.  
  279.     /**
  280.      * Sets the RGBA values for the color. Also clamps them to 0-255.
  281.      */
  282.  
  283.     #define MIN(a,b) (a < b ? a : b)
  284.  
  285.     void setColourRGBA(int r, int g, int b, int a) {
  286.         if (this->isColourEnabled) {
  287.             this->hasColor = true;
  288.             r = (r < 0 ? 0 : (MIN(r, 255)));
  289.             g = (g < 0 ? 0 : (MIN(g, 255)));
  290.             b = (b < 0 ? 0 : (MIN(b, 255)));
  291.             a = (a < 0 ? 0 : (MIN(a, 255)));
  292.             if (true) { // little endian
  293.                 this->color = a << 24 | b << 16 | g << 8 | r;
  294.             }
  295.             else {
  296.                 this->color = r << 24 | g << 16 | b << 8 | a;
  297.             }
  298.         }
  299.     }
  300.  
  301.     #undef MIN
  302.  
  303.     void setColourRGBA(uint8_t r, uint8_t g, uint8_t b) {
  304.         this->setColourOpaque(r & 255, g & 255, b & 255);
  305.     }
  306.  
  307.     /**
  308.      * Adds a vertex specifying both x,y,z and the texture u,v for it.
  309.      */
  310.  
  311.     void addVertexWithUV(double x, double y, double z, double u, double v) {
  312.         this->setTextureUV(u, v);
  313.         this->addVertex(x, y, z);
  314.     }
  315.  
  316.  
  317.     void addVertex(glm::vec3 vec) {
  318.         addVertex(vec.x, vec.y, vec.z);
  319.     }
  320.  
  321.  
  322.     void addVertex(glm::vec4 vec) {
  323.         addVertex(glm::vec3(vec.x / vec.w, vec.y / vec.w, vec.z / vec.w));
  324.     }
  325.  
  326.     /**
  327.      * Adds a vertex with the specified x,y,z to the current draw call. It will trigger a draw() if the buffer gets full
  328.      */
  329.  
  330.     void addVertex(double x, double y, double z) {
  331.         if (this->rawBufferIndex >= this->bufferSize - 32 && this->autoGrow) {
  332.             this->bufferSize *= 2;
  333.             int* newRawBuffer = new int[this->bufferSize];
  334.             memcpy(newRawBuffer, this->rawBuffer, this->rawBufferIndex * sizeof(int));
  335.             delete[](this->rawBuffer);
  336.             this->rawBuffer = newRawBuffer;
  337.         }
  338.  
  339.         ++this->addedVertices;
  340.         if (this->hasTexture) {
  341.             float p1 = (float) this->textureU, p2 = (float) this->textureV;
  342.             this->rawBuffer[this->rawBufferIndex + 3] = FLOAT_TO_INT_BITS(p1);
  343.             this->rawBuffer[this->rawBufferIndex + 4] = FLOAT_TO_INT_BITS(p2);
  344.         }
  345.  
  346.         if (this->hasBrightness) {
  347.             this->rawBuffer[this->rawBufferIndex + 7] = this->brightness;
  348.         }
  349.  
  350.         if (this->hasColor) {
  351.             this->rawBuffer[this->rawBufferIndex + 5] = this->color;
  352.         }
  353.  
  354.         if (this->hasNormals) {
  355.             this->rawBuffer[this->rawBufferIndex + 6] = this->normal;
  356.         }
  357.  
  358.         float pX = (float) (x + this->offsetX), pY = (float) (y + this->offsetY), pZ = (float) (z + this->offsetZ);
  359.         this->rawBuffer[this->rawBufferIndex + 0] = FLOAT_TO_INT_BITS(pX);
  360.         this->rawBuffer[this->rawBufferIndex + 1] = FLOAT_TO_INT_BITS(pY);
  361.         this->rawBuffer[this->rawBufferIndex + 2] = FLOAT_TO_INT_BITS(pZ);
  362.         this->rawBufferIndex += 8;
  363.         ++this->vertexCount;
  364.  
  365.         if (this->autoGrow || this->addedVertices % 4 != 0 || this->rawBufferIndex < this->bufferSize - 32) {
  366.             return;
  367.         }
  368.  
  369.         assert(false);
  370.  
  371.         // throw new RuntimeException("Draw buffer overflow; too many vertices. Added = " + this->addedVertices + ", bufferSize = " + this->bufferSize + ", rawIndex = " + this->rawBufferIndex);
  372.  
  373.         // this->draw();
  374.         // this->isDrawing = true;
  375.     }
  376.  
  377.     /**
  378.      * Sets the color to the given opaque value (stored as byte values packed in an integer).
  379.      */
  380.  
  381.     void setColourOpaque(int colour) {
  382.         int r = colour >> 16 & 255;
  383.         int g = colour >> 8 & 255;
  384.         int b = colour & 255;
  385.         this->setColourOpaque(r, g, b);
  386.     }
  387.  
  388.     /**
  389.      * Sets the color to the given color (packed as bytes in integer) and alpha values.
  390.      */
  391.  
  392.     void setColourRGBA(int rgb, int alpha) {
  393.         int r = rgb >> 16 & 255;
  394.         int g = rgb >> 8 & 255;
  395.         int b = rgb & 255;
  396.         this->setColourRGBA(r, g, b, alpha);
  397.     }
  398.  
  399.     /**
  400.      * Disables colors for the current draw call.
  401.      */
  402.  
  403.     void disableColour() {
  404.         this->isColourEnabled = false;
  405.     }
  406.  
  407.     /**
  408.      * Sets the normal for the current draw call.
  409.      */
  410.     void setNormal(float par1, float par2, float par3) {
  411.         this->hasNormals = true;
  412.         uint8_t var4 = (uint8_t) ((int) (par1 * 127.0F));
  413.         uint8_t var5 = (uint8_t) ((int) (par2 * 127.0F));
  414.         uint8_t var6 = (uint8_t) ((int) (par3 * 127.0F));
  415.         this->normal = var4 & 255 | (var5 & 255) << 8 | (var6 & 255) << 16;
  416.     }
  417.  
  418.     /**
  419.      * Sets the translation for all vertices in the current draw call.
  420.      */
  421.     void setTranslation(double par1, double par3, double par5) {
  422.         this->offsetX = par1;
  423.         this->offsetY = par3;
  424.         this->offsetZ = par5;
  425.     }
  426.  
  427.     /**
  428.      * Offsets the translation for all vertices in the current draw call.
  429.      */
  430.  
  431.     void addTranslation(double x, double y, double z) {
  432.         this->offsetX += x;
  433.         this->offsetY += y;
  434.         this->offsetZ += z;
  435.     }
  436.  
  437. private:
  438.  
  439.     void draw(int startQuadVertex, int endQuadVertex) {
  440.         int vxQuadCount = endQuadVertex - startQuadVertex;
  441.         if (vxQuadCount > 0) {
  442.             int startVertex = startQuadVertex * 4;
  443.             int vxCount = vxQuadCount * 4;
  444.             glTexCoordPointer(2, GL_FLOAT, 32, this->rawBuffer + (sizeof(float) * 3));
  445.             // OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
  446.             glTexCoordPointer(2, GL_FLOAT, 32, this->rawBuffer + (sizeof(int16_t) * 14));
  447.             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  448.             // OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
  449.             glColorPointer(4, GL_UNSIGNED_BYTE, 32, this->rawBuffer + 20);
  450.             glVertexPointer(3, GL_FLOAT, 32, this->rawBuffer);
  451.             glDrawArrays(this->drawMode, startVertex, vxCount);
  452.         }
  453.     }
  454. };
  455.  
  456.  
  457. #endif //RZUIGL_TESSELLATOR_H
  458.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement