diff --git a/src/graphics/Batch3D.cpp b/src/graphics/Batch3D.cpp new file mode 100644 index 00000000..40c91cb6 --- /dev/null +++ b/src/graphics/Batch3D.cpp @@ -0,0 +1,165 @@ +#include "Batch3D.h" + +#include "Mesh.h" +#include "Texture.h" + +#include + +#define VERTEX_SIZE 9 + +Batch3D::Batch3D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){ + const int attrs[] = { + 3, 2, 4, 0 //null terminator + }; + + buffer = new float[capacity * VERTEX_SIZE]; + mesh = new Mesh(buffer, 0, attrs); + index = 0; + + unsigned char pixels[] = { + 255, 255, 255, 255, + }; + blank = new Texture(pixels, 1, 1); + _texture = nullptr; +} + +Batch3D::~Batch3D(){ + delete blank; + delete[] buffer; + delete mesh; +} + +void Batch3D::begin(){ + _texture = nullptr; + blank->bind(); +} + +void Batch3D::vertex(float x, float y, float z, float u, float v, + float r, float g, float b, float a) { + buffer[index++] = x; + buffer[index++] = y; + buffer[index++] = z; + buffer[index++] = u; + buffer[index++] = v; + buffer[index++] = r; + buffer[index++] = g; + buffer[index++] = b; + buffer[index++] = a; +} +void Batch3D::vertex(vec3 point, + vec2 uvpoint, + float r, float g, float b, float a) { + buffer[index++] = point.x; + buffer[index++] = point.y; + buffer[index++] = point.z; + buffer[index++] = uvpoint.x; + buffer[index++] = uvpoint.y; + buffer[index++] = r; + buffer[index++] = g; + buffer[index++] = b; + buffer[index++] = a; +} + +void Batch3D::texture(Texture* new_texture){ + if (_texture == new_texture) + return; + render(); + _texture = new_texture; + if (new_texture == nullptr) + blank->bind(); + else + new_texture->bind(); +} + +void Batch3D::sprite(vec3 pos, vec3 up, vec3 right, float w, float h){ + const float r = color.r; + const float g = color.g; + const float b = color.b; + const float a = color.a; + if (index + 6*VERTEX_SIZE >= capacity) + render(); + + vertex(pos.x - right.x * w - up.x * h, + pos.y - right.y * w - up.y * h, + pos.z - right.z * w - up.z * h, + 0, 0, + r,g,b,a); + + vertex(pos.x + right.x * w + up.x * h, + pos.y + right.y * w + up.y * h, + pos.z + right.z * w + up.z * h, + 1, 1, + r,g,b,a); + + vertex(pos.x - right.x * w - up.x * h, + pos.y + right.y * w + up.y * h, + pos.z - right.z * w - up.z * h, + 0, 1, + r,g,b,a); + + vertex(pos.x - right.x * w - up.x * h, + pos.y - right.y * w - up.y * h, + pos.z - right.z * w - up.z * h, + 0, 0, + r,g,b,a); + + vertex(pos.x + right.x * w + up.x * h, + pos.y - right.y * w - up.y * h, + pos.z + right.z * w + up.z * h, + 1, 0, + r,g,b,a); + + vertex(pos.x + right.x * w + up.x * h, + pos.y + right.y * w + up.y * h, + pos.z + right.z * w + up.z * h, + 1, 1, + r,g,b,a); +} + +void Batch3D::sprite(vec3 pos, vec3 up, vec3 right, float w, float h, int atlasRes, int index, vec4 tint){ + float scale = 1.0f / (float)atlasRes; + float u = (index % atlasRes) * scale; + float v = 1.0f - ((index / atlasRes) * scale) - scale; + + vertex(pos.x - right.x * w - up.x * h, + pos.y - right.y * w - up.y * h, + pos.z - right.z * w - up.z * h, + u, v, + tint.r,tint.g,tint.b,tint.a); + + vertex(pos.x + right.x * w + up.x * h, + pos.y + right.y * w + up.y * h, + pos.z + right.z * w + up.z * h, + u+scale, v+scale, + tint.r,tint.g,tint.b,tint.a); + + vertex(pos.x - right.x * w - up.x * h, + pos.y + right.y * w + up.y * h, + pos.z - right.z * w - up.z * h, + u, v+scale, + tint.r,tint.g,tint.b,tint.a); + + vertex(pos.x - right.x * w - up.x * h, + pos.y - right.y * w - up.y * h, + pos.z - right.z * w - up.z * h, + u, v, + tint.r,tint.g,tint.b,tint.a); + + vertex(pos.x + right.x * w + up.x * h, + pos.y - right.y * w - up.y * h, + pos.z + right.z * w + up.z * h, + u+scale, v, + tint.r,tint.g,tint.b,tint.a); + + vertex(pos.x + right.x * w + up.x * h, + pos.y + right.y * w + up.y * h, + pos.z + right.z * w + up.z * h, + u+scale, v+scale, + tint.r,tint.g,tint.b,tint.a); +} + +void Batch3D::render() { + mesh->reload(buffer, index / VERTEX_SIZE); + mesh->draw(GL_TRIANGLES); + index = 0; +} diff --git a/src/graphics/Batch3D.h b/src/graphics/Batch3D.h new file mode 100644 index 00000000..a63f7c20 --- /dev/null +++ b/src/graphics/Batch3D.h @@ -0,0 +1,40 @@ +#ifndef GRAPHICS_BATCH3D_H_ +#define GRAPHICS_BATCH3D_H_ + +#include +#include + +using namespace glm; + +class Mesh; +class Texture; + +class Batch3D { + float* buffer; + size_t capacity; + size_t offset; + glm::vec4 color; + Mesh* mesh; + size_t index; + + Texture* blank; + Texture* _texture; + + void vertex(float x, float y, float z, + float u, float v, + float r, float g, float b, float a); + void vertex(vec3 point, vec2 uvpoint, + float r, float g, float b, float a); + +public: + Batch3D(size_t capacity); + ~Batch3D(); + + void begin(); + void texture(Texture* texture); + void sprite(vec3 pos, vec3 up, vec3 right, float w, float h, int atlasRes, int index, vec4 tint); + void sprite(vec3 pos, vec3 up, vec3 right, float w, float h); + void render(); +}; + +#endif /* GRAPHICS_BATCH3D_H_ */ diff --git a/src/world_render.h b/src/world_render.h index b5c7e380..eb2e363b 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -19,6 +19,7 @@ #include "graphics/Shader.h" #include "graphics/Texture.h" #include "graphics/LineBatch.h" +#include "graphics/Batch3D.h" #include "voxels/Chunks.h" #include "voxels/Chunk.h" @@ -45,6 +46,7 @@ int uiscale = 1; LineBatch *lineBatch; Batch2D *batch; +Batch3D *batch3d; Camera *uicamera; VoxelRenderer *renderer; @@ -53,6 +55,7 @@ void init_renderer(){ lineBatch = new LineBatch(4096); batch = new Batch2D(1024); + batch3d = new Batch3D(1024); uicamera = new Camera(glm::vec3(), Window::height / uiscale); uicamera->perspective = false; uicamera->flipped = true; @@ -146,8 +149,6 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) batch->texture(blocks); Block* cblock = Block::blocks[player->choosenBlock]; - // int texid = Block::blocks[player->choosenBlock]->textureFaces[3]; // face-3 is top face of block - cblock->textureFaces; if (cblock->type == 1){ batch->blockSprite(24, 648, 48, 48, 16, cblock->textureFaces, vec4(1.0f)); } else if (cblock->type == 2){ @@ -203,6 +204,11 @@ void draw_world(World* world, Level* level, Camera* camera, Assets* assets, bool draw_chunk(indices[i], camera, shader, occlusion); } + shader->uniformMatrix("u_model", mat4(1.0f)); + batch3d->begin(); + // draw 3D stuff here + batch3d->render(); + crosshairShader->use(); crosshairShader->uniform1f("u_ar", (float)Window::height / (float)Window::width); crosshairShader->uniform1f("u_scale", 1.0f / ((float)Window::height / 1000.0f));