Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef RZUIGL_TESSELLATOR_H
- #define RZUIGL_TESSELLATOR_H
- #define FLOAT_TO_INT_BITS(floatVar) (*(int*) &floatVar)
- #include "GL/glew.h"
- #include "glm/glm.hpp"
- #include "../glfw/deps/linmath.h"
- class Tessellator {
- private:
- int* rawBuffer;
- /**
- * The number of vertices to be drawn in the next draw call. Reset to 0 between draw calls.
- */
- int vertexCount;
- /**
- * The first coordinate to be used for the texture.
- */
- double textureU;
- /**
- * The second coordinate to be used for the texture.
- */
- double textureV;
- int brightness;
- /**
- * The color (RGBA) value to be used for the following draw call.
- */
- int color;
- /**
- * Whether the current draw object for this tessellator has color values.
- */
- bool hasColor;
- /**
- * Whether the current draw object for this tessellator has texture coordinates.
- */
- bool hasTexture;
- bool hasBrightness;
- /**
- * Whether the current draw object for this tessellator has normal values.
- */
- bool hasNormals;
- /**
- * The index into the raw buffer to be used for the next data.
- */
- int rawBufferIndex;
- /**
- * The number of vertices manually added to the given draw call. This differs from vertexCount because it adds extra
- * vertices when converting quads to triangles.
- */
- int addedVertices;
- /**
- * Disables all color information for the following draw call.
- */
- bool isColourEnabled = true;
- /**
- * The draw mode currently being used by the tessellator.
- */
- public:
- int drawMode;
- /**
- * An offset to be applied along the x-axis for all vertices in this draw call.
- */
- double offsetX;
- /**
- * An offset to be applied along the y-axis for all vertices in this draw call.
- */
- double offsetY;
- /**
- * An offset to be applied along the z-axis for all vertices in this draw call.
- */
- double offsetZ;
- /**
- * The normal to be applied to the face being drawn.
- */
- private:
- int normal;
- /**
- * Whether this tessellator is currently in draw mode.
- */
- public:
- bool isDrawing;
- /**
- * The size of the buffers used (in integers).
- */
- private:
- int bufferSize;
- public:
- bool autoGrow;
- public:
- explicit Tessellator(int bufferSize) {
- this->autoGrow = true;
- this->bufferSize = bufferSize;
- this->rawBuffer = new int[bufferSize];
- this->vertexCount = 0;
- this->textureU = 0;
- this->textureV = 0;
- this->brightness = 0;
- this->color = 0;
- this->hasColor = false;
- this->hasTexture = false;
- this->hasBrightness = false;
- this->hasNormals = false;
- this->rawBufferIndex = 0;
- this->addedVertices = 0;
- this->isColourEnabled = false;
- this->drawMode = 0;
- this->offsetX = 0;
- this->offsetY = 0;
- this->offsetZ = 0;
- this->normal = 0;
- this->isDrawing = false;
- this->bufferSize = 0;
- this->autoGrow = false;
- }
- /**
- * Draws the data set up in this tessellator and resets the state to prepare for new drawing.
- */
- public:
- int draw() {
- if (!this->isDrawing) {
- // throw "Not tessellating!"
- return 0;
- }
- this->isDrawing = false;
- if (this->vertexCount > 0) {
- if (this->hasTexture) {
- glTexCoordPointer(2, GL_FLOAT, 32, (void*) (sizeof(float) * 3));
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- if (this->hasBrightness) {
- // OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
- glTexCoordPointer(2, GL_FLOAT, 32, (void*) (sizeof(int16_t) * 14));
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- // OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
- }
- if (this->hasColor) {
- glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*) 20);
- glEnableClientState(GL_COLOR_ARRAY);
- }
- if (this->hasNormals) {
- glNormalPointer(GL_FLOAT, 32, (void*) 24);
- glEnableClientState(GL_NORMAL_ARRAY);
- }
- glVertexPointer(3, GL_FLOAT, 32, this->rawBuffer);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(this->drawMode, 0, this->vertexCount);
- glDisableClientState(GL_VERTEX_ARRAY);
- if (this->hasTexture) {
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- if (this->hasBrightness) {
- // OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- // OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
- }
- if (this->hasColor) {
- glDisableClientState(GL_COLOR_ARRAY);
- }
- if (this->hasNormals) {
- glDisableClientState(GL_NORMAL_ARRAY);
- }
- }
- int index = this->rawBufferIndex * 4;
- this->reset();
- return index;
- }
- private:
- /**
- * Clears the tessellator state in preparation for new drawing.
- */
- void reset() {
- this->vertexCount = 0;
- this->rawBufferIndex = 0;
- this->addedVertices = 0;
- }
- public:
- /**
- * Sets draw mode in the tessellator to draw quads.
- */
- void startDrawingQuads() {
- this->startDrawing(GL_QUADS);
- }
- /**
- * Resets tessellator state and prepares for drawing (with the specified draw mode).
- */
- void startDrawing(int glMode) {
- if (this->isDrawing) {
- return; // throw new IllegalStateException("Already tessellating!");
- }
- this->isDrawing = true;
- this->reset();
- this->drawMode = glMode;
- this->hasNormals = false;
- this->hasColor = false;
- this->hasTexture = false;
- this->hasBrightness = false;
- this->isColourEnabled = true;
- }
- /**
- * Sets the texture coordinates.
- */
- void setTextureUV(double u, double v) {
- this->hasTexture = true;
- this->textureU = u;
- this->textureV = v;
- }
- void setBrightness(int brightness) {
- this->hasBrightness = true;
- this->brightness = brightness;
- }
- /**
- * Sets the RGB values as specified, converting from floats between 0 and 1 to integers from 0-255.
- */
- void setColourOpaque(float r, float g, float b) {
- this->setColourOpaque((int) (r * 255.0F), (int) (g * 255.0F), (int) (b * 255.0F));
- }
- /**
- * Sets the RGBA values for the color, converting from floats between 0 and 1 to integers from 0-255.
- */
- void setColourRGBA(float r, float g, float b, float a) {
- this->setColourRGBA((int) (r * 255.0F), (int) (g * 255.0F), (int) (b * 255.0F), (int) (a * 255.0F));
- }
- /**
- * Sets the RGB values as specified, and sets alpha to opaque.
- */
- void setColourOpaque(int r, int g, int b) {
- this->setColourRGBA(r, g, b, 255);
- }
- /**
- * Sets the RGBA values for the color. Also clamps them to 0-255.
- */
- #define MIN(a,b) (a < b ? a : b)
- void setColourRGBA(int r, int g, int b, int a) {
- if (this->isColourEnabled) {
- this->hasColor = true;
- r = (r < 0 ? 0 : (MIN(r, 255)));
- g = (g < 0 ? 0 : (MIN(g, 255)));
- b = (b < 0 ? 0 : (MIN(b, 255)));
- a = (a < 0 ? 0 : (MIN(a, 255)));
- if (true) { // little endian
- this->color = a << 24 | b << 16 | g << 8 | r;
- }
- else {
- this->color = r << 24 | g << 16 | b << 8 | a;
- }
- }
- }
- #undef MIN
- void setColourRGBA(uint8_t r, uint8_t g, uint8_t b) {
- this->setColourOpaque(r & 255, g & 255, b & 255);
- }
- /**
- * Adds a vertex specifying both x,y,z and the texture u,v for it.
- */
- void addVertexWithUV(double x, double y, double z, double u, double v) {
- this->setTextureUV(u, v);
- this->addVertex(x, y, z);
- }
- void addVertex(glm::vec3 vec) {
- addVertex(vec.x, vec.y, vec.z);
- }
- void addVertex(glm::vec4 vec) {
- addVertex(glm::vec3(vec.x / vec.w, vec.y / vec.w, vec.z / vec.w));
- }
- /**
- * Adds a vertex with the specified x,y,z to the current draw call. It will trigger a draw() if the buffer gets full
- */
- void addVertex(double x, double y, double z) {
- if (this->rawBufferIndex >= this->bufferSize - 32 && this->autoGrow) {
- this->bufferSize *= 2;
- int* newRawBuffer = new int[this->bufferSize];
- memcpy(newRawBuffer, this->rawBuffer, this->rawBufferIndex * sizeof(int));
- delete[](this->rawBuffer);
- this->rawBuffer = newRawBuffer;
- }
- ++this->addedVertices;
- if (this->hasTexture) {
- float p1 = (float) this->textureU, p2 = (float) this->textureV;
- this->rawBuffer[this->rawBufferIndex + 3] = FLOAT_TO_INT_BITS(p1);
- this->rawBuffer[this->rawBufferIndex + 4] = FLOAT_TO_INT_BITS(p2);
- }
- if (this->hasBrightness) {
- this->rawBuffer[this->rawBufferIndex + 7] = this->brightness;
- }
- if (this->hasColor) {
- this->rawBuffer[this->rawBufferIndex + 5] = this->color;
- }
- if (this->hasNormals) {
- this->rawBuffer[this->rawBufferIndex + 6] = this->normal;
- }
- float pX = (float) (x + this->offsetX), pY = (float) (y + this->offsetY), pZ = (float) (z + this->offsetZ);
- this->rawBuffer[this->rawBufferIndex + 0] = FLOAT_TO_INT_BITS(pX);
- this->rawBuffer[this->rawBufferIndex + 1] = FLOAT_TO_INT_BITS(pY);
- this->rawBuffer[this->rawBufferIndex + 2] = FLOAT_TO_INT_BITS(pZ);
- this->rawBufferIndex += 8;
- ++this->vertexCount;
- if (this->autoGrow || this->addedVertices % 4 != 0 || this->rawBufferIndex < this->bufferSize - 32) {
- return;
- }
- assert(false);
- // throw new RuntimeException("Draw buffer overflow; too many vertices. Added = " + this->addedVertices + ", bufferSize = " + this->bufferSize + ", rawIndex = " + this->rawBufferIndex);
- // this->draw();
- // this->isDrawing = true;
- }
- /**
- * Sets the color to the given opaque value (stored as byte values packed in an integer).
- */
- void setColourOpaque(int colour) {
- int r = colour >> 16 & 255;
- int g = colour >> 8 & 255;
- int b = colour & 255;
- this->setColourOpaque(r, g, b);
- }
- /**
- * Sets the color to the given color (packed as bytes in integer) and alpha values.
- */
- void setColourRGBA(int rgb, int alpha) {
- int r = rgb >> 16 & 255;
- int g = rgb >> 8 & 255;
- int b = rgb & 255;
- this->setColourRGBA(r, g, b, alpha);
- }
- /**
- * Disables colors for the current draw call.
- */
- void disableColour() {
- this->isColourEnabled = false;
- }
- /**
- * Sets the normal for the current draw call.
- */
- void setNormal(float par1, float par2, float par3) {
- this->hasNormals = true;
- uint8_t var4 = (uint8_t) ((int) (par1 * 127.0F));
- uint8_t var5 = (uint8_t) ((int) (par2 * 127.0F));
- uint8_t var6 = (uint8_t) ((int) (par3 * 127.0F));
- this->normal = var4 & 255 | (var5 & 255) << 8 | (var6 & 255) << 16;
- }
- /**
- * Sets the translation for all vertices in the current draw call.
- */
- void setTranslation(double par1, double par3, double par5) {
- this->offsetX = par1;
- this->offsetY = par3;
- this->offsetZ = par5;
- }
- /**
- * Offsets the translation for all vertices in the current draw call.
- */
- void addTranslation(double x, double y, double z) {
- this->offsetX += x;
- this->offsetY += y;
- this->offsetZ += z;
- }
- private:
- void draw(int startQuadVertex, int endQuadVertex) {
- int vxQuadCount = endQuadVertex - startQuadVertex;
- if (vxQuadCount > 0) {
- int startVertex = startQuadVertex * 4;
- int vxCount = vxQuadCount * 4;
- glTexCoordPointer(2, GL_FLOAT, 32, this->rawBuffer + (sizeof(float) * 3));
- // OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
- glTexCoordPointer(2, GL_FLOAT, 32, this->rawBuffer + (sizeof(int16_t) * 14));
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- // OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
- glColorPointer(4, GL_UNSIGNED_BYTE, 32, this->rawBuffer + 20);
- glVertexPointer(3, GL_FLOAT, 32, this->rawBuffer);
- glDrawArrays(this->drawMode, startVertex, vxCount);
- }
- }
- };
- #endif //RZUIGL_TESSELLATOR_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement