diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index ffbf1d43..f368328d 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -39,6 +39,7 @@ void main(){ skyLightColor.g *= 0.9; skyLightColor.b *= 0.8; skyLightColor = min(vec3(1.0), skyLightColor*SKY_LIGHT_MUL); + skyLightColor = max(vec3(0.1, 0.11, 0.14), skyLightColor); a_color.rgb = max(a_color.rgb, skyLightColor.rgb*decomp_light.a); a_distance = length(u_view * u_model * vec4(pos3d.x, pos3d.y*0.2, pos3d.z, 0.0)); diff --git a/res/shaders/skybox_gen.glslf b/res/shaders/skybox_gen.glslf index 8edff477..27c8f567 100644 --- a/res/shaders/skybox_gen.glslf +++ b/res/shaders/skybox_gen.glslf @@ -277,7 +277,7 @@ void main() { MIE_BETA, // Mie scattering coefficient ABSORPTION_BETA, // Absorbtion coefficient AMBIENT_BETA, // ambient scattering, turned off for now. This causes the air to glow a bit when no light reaches it - G*fog, // Mie preferred scattering direction + G*fog*0.7, // Mie preferred scattering direction HEIGHT_RAY, // Rayleigh scale height HEIGHT_MIE*u_mie*u_mie, // Mie scale height HEIGHT_ABSORPTION, // the height at which the most absorption happens diff --git a/res/textures/misc/moon.png b/res/textures/misc/moon.png new file mode 100644 index 00000000..8f68b989 Binary files /dev/null and b/res/textures/misc/moon.png differ diff --git a/res/textures/misc/sun.png b/res/textures/misc/sun.png new file mode 100644 index 00000000..1bb7320a Binary files /dev/null and b/res/textures/misc/sun.png differ diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index e5ab0d79..0087389d 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -60,6 +60,8 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, bool allAssets) { loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/menubg.png", "gui/menubg"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/delete_icon.png", "gui/delete_icon"); + loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon"); + loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/sun.png", "misc/sun"); loader.add(ASSET_FONT, FONTS_FOLDER"/font", "normal"); } loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks"); diff --git a/src/coders/gzip.h b/src/coders/gzip.h index f83cdfe6..75f3618c 100644 --- a/src/coders/gzip.h +++ b/src/coders/gzip.h @@ -6,7 +6,15 @@ namespace gzip { const unsigned char MAGIC[] = "\x1F\x8B"; + + /* Compress bytes array to GZIP format + @param src source bytes array + @param size length of source bytes array */ std::vector compress(const ubyte* src, size_t size); + + /* Decompress bytes array from GZIP + @param src GZIP data + @param size length of GZIP data */ std::vector decompress(const ubyte* src, size_t size); } diff --git a/src/coders/png.cpp b/src/coders/png.cpp index 36287669..9ac44525 100644 --- a/src/coders/png.cpp +++ b/src/coders/png.cpp @@ -355,7 +355,9 @@ Texture* png::load_texture(std::string filename) { std::cerr << "Could not load texture " << filename << std::endl; return nullptr; } - return Texture::from(image.get()); + auto texture = Texture::from(image.get()); + texture->setNearestFilter(); + return texture; } void png::write_image(std::string filename, const ImageData* image) { diff --git a/src/frontend/WorldRenderer.cpp b/src/frontend/WorldRenderer.cpp index 8ae83df0..d61394b4 100644 --- a/src/frontend/WorldRenderer.cpp +++ b/src/frontend/WorldRenderer.cpp @@ -5,13 +5,14 @@ #include #include -#include "../content/Content.h" -#include "../graphics/ChunksRenderer.h" #include "../window/Window.h" #include "../window/Camera.h" +#include "../content/Content.h" +#include "../graphics/ChunksRenderer.h" #include "../graphics/Mesh.h" #include "../graphics/Atlas.h" #include "../graphics/Shader.h" +#include "../graphics/Batch3D.h" #include "../graphics/Texture.h" #include "../graphics/LineBatch.h" #include "../voxels/Chunks.h" @@ -46,7 +47,8 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend) lineBatch(new LineBatch()), renderer(new ChunksRenderer(level, frontend->getContentGfxCache(), - engine->getSettings())) { + engine->getSettings())), + batch3d(new Batch3D(4096)) { auto& settings = engine->getSettings(); level->events->listen(EVT_CHUNK_HIDDEN, @@ -129,31 +131,24 @@ void WorldRenderer::drawChunks(Chunks* chunks, void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible){ + Window::clearDepth(); EngineSettings& settings = engine->getSettings(); - skybox->refresh(level->world->daytime, - 1.0f+fog*2.0f, 4); + skybox->refresh(pctx, level->world->daytime, 1.0f+fog*2.0f, 4); const Content* content = level->content; auto indices = content->getIndices(); Assets* assets = engine->getAssets(); Atlas* atlas = assets->getAtlas("blocks"); Shader* shader = assets->getShader("main"); - Shader* linesShader = assets->getShader("lines"); const Viewport& viewport = pctx.getViewport(); int displayWidth = viewport.getWidth(); int displayHeight = viewport.getHeight(); - Window::clearDepth(); - Window::viewport(0, 0, displayWidth, displayHeight); // Drawing background sky plane - Shader* backShader = assets->getShader("background"); - backShader->use(); - backShader->uniformMatrix("u_view", camera->getView(false)); - backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(3.141592*0.5f)); - backShader->uniform1f("u_ar", float(displayWidth)/float(displayHeight)); - skybox->draw(backShader); + skybox->draw(pctx, camera, assets, level->getWorld()->daytime, fog); + Shader* linesShader = assets->getShader("lines"); { GfxContext ctx = pctx.sub(); ctx.depthTest(true); diff --git a/src/frontend/WorldRenderer.h b/src/frontend/WorldRenderer.h index bb500c3b..c08b37fb 100644 --- a/src/frontend/WorldRenderer.h +++ b/src/frontend/WorldRenderer.h @@ -2,6 +2,7 @@ #define WORLD_RENDERER_CPP #include +#include #include #include #include @@ -14,6 +15,7 @@ class Level; class Camera; +class Batch3D; class LineBatch; class ChunksRenderer; class Shader; @@ -31,6 +33,7 @@ class WorldRenderer { LineBatch* lineBatch; ChunksRenderer* renderer; Skybox* skybox; + std::unique_ptr batch3d; bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); public: diff --git a/src/frontend/graphics/Skybox.cpp b/src/frontend/graphics/Skybox.cpp index 859dd380..82bc6f36 100644 --- a/src/frontend/graphics/Skybox.cpp +++ b/src/frontend/graphics/Skybox.cpp @@ -1,19 +1,28 @@ #include "Skybox.h" -#include + #include +#include #include +#include "../../assets/Assets.h" #include "../../graphics/Shader.h" #include "../../graphics/Mesh.h" +#include "../../graphics/Batch3D.h" #include "../../window/Window.h" +#include "../../window/Camera.h" #ifndef M_PI #define M_PI 3.141592 #endif // M_PI -using glm::vec3; +const int STARS_COUNT = 3000; +const int STARS_SEED = 632; -Skybox::Skybox(uint size, Shader* shader) : size(size), shader(shader) { +Skybox::Skybox(uint size, Shader* shader) + : size(size), + shader(shader), + batch3d(new Batch3D(4096)) +{ glGenTextures(1, &cubemap); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -31,30 +40,118 @@ Skybox::Skybox(uint size, Shader* shader) : size(size), shader(shader) { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f }; vattr attrs[] {2, 0}; - mesh = new Mesh(vertices, 6, attrs); + mesh = std::make_unique(vertices, 6, attrs); + + sprites.push_back(skysprite { + "misc/moon", + M_PI*0.5f, + 4.0f, + false + }); + + sprites.push_back(skysprite { + "misc/sun", + M_PI*1.5f, + 4.0f, + true + }); } Skybox::~Skybox() { glDeleteTextures(1, &cubemap); glDeleteFramebuffers(1, &fbo); - delete mesh; } -void Skybox::draw(Shader* shader) { - shader->uniform1i("u_cubemap", 1); +void Skybox::drawBackground(Camera* camera, Assets* assets, int width, int height) { + Shader* backShader = assets->getShader("background"); + backShader->use(); + backShader->uniformMatrix("u_view", camera->getView(false)); + backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f)); + backShader->uniform1f("u_ar", float(width)/float(height)); + backShader->uniform1i("u_cubemap", 1); bind(); mesh->draw(); unbind(); } -void Skybox::refresh(float t, float mie, uint quality) { +void Skybox::drawStars(Camera* camera, float angle, float opacity) { + batch3d->texture(nullptr); + random.setSeed(STARS_SEED); + for (int i = 0; i < STARS_COUNT; i++) { + float rx = (random.randFloat()) - 0.5f; + float ry = (random.randFloat()) - 0.5f; + float z = (random.randFloat()) - 0.5f; + float x = rx * sin(angle) + ry * -cos(angle); + float y = rx * cos(angle) + ry * sin(angle); + + float sopacity = random.randFloat(); + if (y < 0.0f) + continue; + + sopacity *= (0.2f+sqrt(cos(angle))*0.5) - 0.05; + glm::vec4 tint (1,1,1, sopacity * opacity); + batch3d->point(camera->position + glm::vec3(x, y, z), tint); + } + batch3d->flushPoints(); +} + +void Skybox::draw( + const GfxContext& pctx, + Camera* camera, + Assets* assets, + float daytime, + float fog) +{ + const Viewport& viewport = pctx.getViewport(); + int width = viewport.getWidth(); + int height = viewport.getHeight(); + + drawBackground(camera, assets, width, height); + + GfxContext ctx = pctx.sub(); + ctx.blendMode(blendmode::addition); + + Shader* shader = assets->getShader("ui3d"); + shader->use(); + shader->uniformMatrix("u_projview", camera->getProjView()); + shader->uniformMatrix("u_apply", glm::mat4(1.0f)); + batch3d->begin(); + + float angle = daytime * M_PI * 2; + float opacity = glm::pow(1.0f-fog, 7.0f); + + for (auto& sprite : sprites) { + batch3d->texture(assets->getTexture(sprite.texture)); + + float sangle = daytime * M_PI*2 + sprite.phase; + float distance = sprite.distance; + + glm::vec3 pos(-cos(sangle)*distance, sin(sangle)*distance, 0); + glm::vec3 up(-sin(-sangle), cos(-sangle), 0.0f); + glm::vec4 tint (1,1,1, opacity); + if (!sprite.emissive) { + tint *= 0.6f+cos(angle)*0.4; + } + batch3d->sprite(camera->position+pos, up, + glm::vec3(0, 0, -1), 1, 1, UVRegion(), tint); + } + + drawStars(camera, angle, opacity); +} + +void Skybox::refresh(const GfxContext& pctx, float t, float mie, uint quality) { + GfxContext ctx = pctx.sub(); + ctx.depthMask(false); + ctx.depthTest(false); + ready = true; glBindFramebuffer(GL_FRAMEBUFFER, fbo); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap); shader->use(); - Window::viewport(0,0, size,size); - const vec3 xaxs[] = { + Window::viewport(0,0, size, size); + + const glm::vec3 xaxs[] = { {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}, @@ -63,7 +160,7 @@ void Skybox::refresh(float t, float mie, uint quality) { {-1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, }; - const vec3 yaxs[] = { + const glm::vec3 yaxs[] = { {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, @@ -73,7 +170,7 @@ void Skybox::refresh(float t, float mie, uint quality) { {0.0f, 1.0f, 0.0f}, }; - const vec3 zaxs[] = { + const glm::vec3 zaxs[] = { {1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, @@ -87,7 +184,7 @@ void Skybox::refresh(float t, float mie, uint quality) { shader->uniform1i("u_quality", quality); shader->uniform1f("u_mie", mie); shader->uniform1f("u_fog", mie - 1.0f); - shader->uniform3f("u_lightDir", glm::normalize(vec3(sin(t), -cos(t), -0.7f))); + shader->uniform3f("u_lightDir", glm::normalize(glm::vec3(sin(t), -cos(t), 0.0f))); for (uint face = 0; face < 6; face++) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, 0); shader->uniform3f("u_xaxis", xaxs[face]); diff --git a/src/frontend/graphics/Skybox.h b/src/frontend/graphics/Skybox.h index cdf18966..cc949617 100644 --- a/src/frontend/graphics/Skybox.h +++ b/src/frontend/graphics/Skybox.h @@ -1,25 +1,52 @@ #ifndef FRONTEND_GRAPHICS_SKYBOX_H_ #define FRONTEND_GRAPHICS_SKYBOX_H_ +#include +#include +#include #include "../../typedefs.h" +#include "../../maths/fastmaths.h" +#include "../../graphics/GfxContext.h" class Mesh; class Shader; +class Assets; +class Camera; +class Batch3D; + +struct skysprite { + std::string texture; + float phase; + float distance; + bool emissive; +}; class Skybox { uint fbo; uint cubemap; uint size; - Mesh* mesh; Shader* shader; bool ready = false; + FastRandom random; + + std::unique_ptr mesh; + std::unique_ptr batch3d; + std::vector sprites; + + void drawStars(Camera* camera, float angle, float opacity); + void drawBackground(Camera* camera, Assets* assets, int width, int height); public: Skybox(uint size, Shader* shader); ~Skybox(); - void draw(Shader* shader); + void draw( + const GfxContext& pctx, + Camera* camera, + Assets* assets, + float daytime, + float fog); - void refresh(float t, float mie, uint quality); + void refresh(const GfxContext& pctx, float t, float mie, uint quality); void bind() const; void unbind() const; bool isReady() const { diff --git a/src/graphics/Batch3D.cpp b/src/graphics/Batch3D.cpp index cf47dd2e..58b64a7b 100644 --- a/src/graphics/Batch3D.cpp +++ b/src/graphics/Batch3D.cpp @@ -134,9 +134,9 @@ void Batch3D::sprite(vec3 pos, vec3 up, vec3 right, float w, float h, const UVRe uv.u2, uv.v2, 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, + 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, uv.u1, uv.v2, r,g,b,a); @@ -146,9 +146,9 @@ void Batch3D::sprite(vec3 pos, vec3 up, vec3 right, float w, float h, const UVRe uv.u1, uv.v1, 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, + 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, uv.u2, uv.v1, r,g,b,a); @@ -178,8 +178,18 @@ void Batch3D::blockCube(const vec3 size, const UVRegion(&texfaces)[6], const vec face(coord+vec3(size.x, 0.0f, 0.0f), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], (shading ? do_tint(0.9f)*tint : tint)); } +void Batch3D::point(glm::vec3 coord, glm::vec4 tint) { + vertex(coord, glm::vec2(), tint.r, tint.g, tint.b, tint.a); +} + void Batch3D::flush() { mesh->reload(buffer, index / B3D_VERTEX_SIZE); mesh->draw(); index = 0; } + +void Batch3D::flushPoints() { + mesh->reload(buffer, index / B3D_VERTEX_SIZE); + mesh->draw(GL_POINTS); + index = 0; +} diff --git a/src/graphics/Batch3D.h b/src/graphics/Batch3D.h index 5de47c84..d5f5ae5a 100644 --- a/src/graphics/Batch3D.h +++ b/src/graphics/Batch3D.h @@ -43,7 +43,9 @@ public: void sprite(glm::vec3 pos, glm::vec3 up, glm::vec3 right, float w, float h, const UVRegion& uv, glm::vec4 tint); void xSprite(float w, float h, const UVRegion& uv, const glm::vec4 tint, bool shading=true); void blockCube(const glm::vec3 size, const UVRegion(&texfaces)[6], const glm::vec4 tint, bool shading=true); + void point(glm::vec3 pos, glm::vec4 tint); void flush(); + void flushPoints(); }; #endif /* GRAPHICS_BATCH3D_H_ */ diff --git a/src/graphics/GfxContext.cpp b/src/graphics/GfxContext.cpp index e15dd5bf..44e915cb 100644 --- a/src/graphics/GfxContext.cpp +++ b/src/graphics/GfxContext.cpp @@ -11,6 +11,9 @@ GfxContext::GfxContext(const GfxContext* parent, Viewport& viewport, Batch2D* g2 GfxContext::~GfxContext() { if (parent == nullptr) return; + if (depthMask_ != parent->depthMask_) { + glDepthMask(parent->depthMask_); + } if (depthTest_ != parent->depthTest_) { if (depthTest_) glDisable(GL_DEPTH_TEST); else glEnable(GL_DEPTH_TEST); @@ -19,6 +22,9 @@ GfxContext::~GfxContext() { if (cullFace_) glDisable(GL_CULL_FACE); else glEnable(GL_CULL_FACE); } + if (blendMode_ != parent->blendMode_) { + Window::setBlendMode(parent->blendMode_); + } } const Viewport& GfxContext::getViewport() const { @@ -36,11 +42,18 @@ GfxContext GfxContext::sub() const { return ctx; } +void GfxContext::depthMask(bool flag) { + if (depthMask_ == flag) + return; + depthMask_ = flag; + glDepthMask(GL_FALSE + flag); +} + void GfxContext::depthTest(bool flag) { if (depthTest_ == flag) return; depthTest_ = flag; - if (depthTest_) { + if (flag) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); @@ -51,9 +64,16 @@ void GfxContext::cullFace(bool flag) { if (cullFace_ == flag) return; cullFace_ = flag; - if (cullFace_) { + if (flag) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } -} \ No newline at end of file +} + +void GfxContext::blendMode(blendmode mode) { + if (blendMode_ == mode) + return; + blendMode_ = mode; + Window::setBlendMode(mode); +} diff --git a/src/graphics/GfxContext.h b/src/graphics/GfxContext.h index 43e97b5c..7da9dd90 100644 --- a/src/graphics/GfxContext.h +++ b/src/graphics/GfxContext.h @@ -3,6 +3,7 @@ #include "../typedefs.h" #include "Viewport.h" +#include "../window/Window.h" class Batch2D; @@ -10,8 +11,10 @@ class GfxContext { const GfxContext* parent; Viewport& viewport; Batch2D* const g2d; + bool depthMask_ = true; bool depthTest_ = false; bool cullFace_ = false; + blendmode blendMode_ = blendmode::normal; public: GfxContext(const GfxContext* parent, Viewport& viewport, Batch2D* g2d); ~GfxContext(); @@ -20,8 +23,10 @@ public: const Viewport& getViewport() const; GfxContext sub() const; + void depthMask(bool flag); void depthTest(bool flag); void cullFace(bool flag); + void blendMode(blendmode mode); }; #endif // GRAPHICS_GFX_CONTEXT_H_ \ No newline at end of file diff --git a/src/graphics/Texture.cpp b/src/graphics/Texture.cpp index 5531be1e..42bfb622 100644 --- a/src/graphics/Texture.cpp +++ b/src/graphics/Texture.cpp @@ -46,6 +46,13 @@ ImageData* Texture::readData() { return new ImageData(ImageFormat::rgba8888, width, height, data.release()); } +void Texture::setNearestFilter() { + bind(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glBindTexture(GL_TEXTURE_2D, 0); +} + Texture* Texture::from(const ImageData* image) { uint width = image->getWidth(); uint height = image->getHeight(); diff --git a/src/graphics/Texture.h b/src/graphics/Texture.h index 2dc9064e..8ece550a 100644 --- a/src/graphics/Texture.h +++ b/src/graphics/Texture.h @@ -18,6 +18,8 @@ public: void bind(); void reload(ubyte* data); + void setNearestFilter(); + ImageData* readData(); static Texture* from(const ImageData* image); diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 5378010a..46a548d4 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -125,9 +125,9 @@ void BlocksController::randomTick(int tickid, int parts) { continue; for (int s = 0; s < segments; s++) { for (int i = 0; i < 4; i++) { - int bx = fastmaths::rand() % CHUNK_W; - int by = fastmaths::rand() % segheight + s * segheight; - int bz = fastmaths::rand() % CHUNK_D; + int bx = random.rand() % CHUNK_W; + int by = random.rand() % segheight + s * segheight; + int bz = random.rand() % CHUNK_D; const voxel& vox = chunk->voxels[(by * CHUNK_D + bz) * CHUNK_W + bx]; Block* block = indices->getBlockDef(vox.id); if (block->rt.funcsset.randupdate) { diff --git a/src/logic/BlocksController.h b/src/logic/BlocksController.h index b0dc0fe7..83bc8b02 100644 --- a/src/logic/BlocksController.h +++ b/src/logic/BlocksController.h @@ -2,6 +2,7 @@ #define LOGIC_BLOCKS_CONTROLLER_H_ #include "../typedefs.h" +#include "../maths/fastmaths.h" class Player; class Block; @@ -33,6 +34,7 @@ class BlocksController { Clock randTickClock; Clock blocksTickClock; uint padding; + FastRandom random; public: BlocksController(Level* level, uint padding); diff --git a/src/maths/fastmaths.h b/src/maths/fastmaths.h index 73ea99e5..3d6a800a 100644 --- a/src/maths/fastmaths.h +++ b/src/maths/fastmaths.h @@ -1,17 +1,23 @@ #ifndef MATHS_FASTMATHS_H_ #define MATHS_FASTMATHS_H_ -namespace fastmaths { - static unsigned int g_seed; +#include "../typedefs.h" - inline void srand(int seed) { - g_seed = seed; +class FastRandom { + uint seed; +public: + inline void setSeed(uint seed) { + this->seed = seed; } - inline int rand(void) { - g_seed = (214013*g_seed+2531011); - return (g_seed>>16)&0x7FFF; + inline int rand() { + seed = (214013 * seed + 2531011); + return (seed>>16) & 0x7FFF; } -} + + inline float randFloat() { + return rand() / float(0x7FFF); + } +}; #endif // MATHS_FASTMATHS_H_ diff --git a/src/window/Window.cpp b/src/window/Window.cpp index 6a692902..4470d117 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -167,6 +167,17 @@ int Window::initialize(DisplaySettings& settings){ return 0; } +void Window::setBlendMode(blendmode mode) { + switch (mode) { + case blendmode::normal: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case blendmode::addition: + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + } +} + void Window::clear() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } diff --git a/src/window/Window.h b/src/window/Window.h index e9f925cd..96bd210a 100644 --- a/src/window/Window.h +++ b/src/window/Window.h @@ -14,6 +14,10 @@ class ImageData; struct DisplaySettings; struct GLFWmonitor; +enum class blendmode { + normal, addition +}; + class Window { static GLFWwindow* window; static DisplaySettings* settings; @@ -53,6 +57,8 @@ public: static const char* getClipboardText(); static DisplaySettings* getSettings(); + static void setBlendMode(blendmode mode); + static glm::vec2 size() { return glm::vec2(width, height); }