From 3a95e44b674dfc0077ce4fb4a4cb66d682ca05dc Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 20 Mar 2022 23:45:36 +0300 Subject: [PATCH 01/56] Delete ascii.png --- res/ascii.png | Bin 2027 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 res/ascii.png diff --git a/res/ascii.png b/res/ascii.png deleted file mode 100644 index 3278f04cf6ece29ea3c3b9f7ed7d042702092dc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2027 zcmVxr^0dAyo)a6&VPm%%iUV-rFdvpNU_C=mu{Y!%* zD^l3!tayrwc60_-KeP3XE;Av7RLxKp{ig$fS>tIPU?jlV&k_mXey)@-JETyg^P}G* zI!d(vKa=(+cgIIf)bdVXD~T=@3M*hxOblR#poxf4hA67w0gf5m)c{6+gD`EK06yy! zFt|VS$eL^lqJ>dHUo8PL0Ehs@MTA_{WA%O|=`vjZ0DxE`q62U@aCZQ^s|QLVy-vYX zC}|99=VH>bJ94A;7b%<5`3DjiSu4R|$0L7NeIIGt(Ztja07SKPL=R#25)|({nY(*F zBFr#WS#`CKQG#C$fUE>S2Oky1ECARE;QpQ-N4Ers5=AIcRSkd+5};iAtk&p^TNk1u zxOIR>17ODzz*+&!5}>jos`~c?-D6Vs0a7VptXC__OH zau74I(kHNkBw*VAj}ql#)S_BGawL72~$U zJ2RP+PPX%%JVC}rXI#Qu9zPkU(j8WYBfroIVb|fr?q>_t0T!}*6&dU5ZUVsl8L`VV zGf+JMigSA`)2Om?7=WT)(P02wZK!lS4__fdDsT<~Ov%$__1>8GsHFz|k%T03}PnX#iLaAkCBk zrl5*LXa@jC1dkm6h{P9A)$eftxTA?>cIb!OuXipXk-xKX3|Ssx(xkAGpJoCT5@bhy zuCsye@b_&FhMWw5PW5l2-MhrdodU+XT_ZY#f{DDVzfuAy975Rk%Mq>IJ#<`&5+$-! z#LCKH1C>ejW$l{pq2 z#T^H)!>wGM?+sLxPe~|M0EMc%c@+b^qkb;3h;CmOw{X|{4!dn`08mQqE+(w%ef90; z)e<0Nr6_Oi>_+8g+vhOTssWIyOSc)Uc;BIY?E&!g{p{JVH+GUD9zVkaFm`m5CYFg< zpzl>glw|^BH(5^P8FqLSId!1hamr}1F28iAUwd~YG_%Gd676RoLoC{VO4f1L_pHzTDsTF=8TQKgKNmF|ID$sNU-ma9)MK9 z8D~)WJsV?abylAh#R`DZlc3{nU!;NPrB6{{M3i60df=(;I5ujqyB+pv-o9OuM->Xop z2&cfjUzM$r5|Or{l7h{jIv$=?!mh5CyAziKfQA6*E&(!T7BT?Hy@;6s`rag0{#zwL zboQSh0W!zX7zw~kgvUt$wO>9v1KkopQ9q{sFb{CL4#3VJHh;H{LQA-(TLA-ri*nzh z0}KEH0B#g_mH^djbanj(00V#lz^egJy`AbtuA+QqV9+&~{e8In0l)wty<3$% zAQ2q^=9Eyje8kEa32@L190{-}|7%WBJDZgN-;HS}kKzW5Obg#(hE(nbqV*d93;+fI z1AvDBVCVirxAHTmpCV zT0dAB?QT!1Z1=AAbDR3CW(S)`#-82THaG834uT93!gOL*L?g;#MiKh?|6L$haTIs$ zDs}UUYMiWuVEBSa2O{8h13)2V;U%oA1Yo%K&g(G(fEIfIJ9Ge-L&%EjPyrxgB}4&$ z`XU^u1vB2V(KWQ9Z98{L<@r0kc$5I>o{rn5?PT*lrQ Date: Sun, 20 Mar 2022 23:45:50 +0300 Subject: [PATCH 02/56] Delete block (copy).png --- res/block (copy).png | Bin 8247 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 res/block (copy).png diff --git a/res/block (copy).png b/res/block (copy).png deleted file mode 100644 index 5e2512c7d531cc21c8c2cb913134d300f2800ef2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8247 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 Date: Sun, 20 Mar 2022 23:46:05 +0300 Subject: [PATCH 03/56] Delete block_.png --- res/block_.png | Bin 4870 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 res/block_.png diff --git a/res/block_.png b/res/block_.png deleted file mode 100644 index d4941919d6900bc32cb8e080a2950892ea537d27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4870 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 s?fxl!E~&S(MAClfjW&igqol Date: Sun, 20 Mar 2022 23:46:14 +0300 Subject: [PATCH 04/56] Delete block_white.png --- res/block_white.png | Bin 2039 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 res/block_white.png diff --git a/res/block_white.png b/res/block_white.png deleted file mode 100644 index cfb6a408bfb953e38b121086104d4ec7724e342b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2039 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe*p<*Gs=N`ey06$*;-(=u~X z6-p`#QWa7wGSe6sDsH`<<~d15o2TvjoJX>XrivDP$u0R09`Bbo%FZg^aa%C1BG6MM zgiDdLw&|Tg-M<+R?QN!PW;69SJYMnO;+mP&^r?Z^Dd3ny` zJFyo#a*nN@wXM6rnAx=<=;rBZj>ofqyxpC;rDV!tMjv<0kS%UAC0x`rzdE$4@xGFf zZZy^AFY7ten|gYZMS9*Qi(iF#o+Y$QJVF^?Pc|cgd-RoZ)f`5NU(gBxk$=3 z%e#z`;|tH@N~IIO7aiN}C9;qA-~$c~*@;IqEE2rjEp?+ikLleszDVhySvsTDoZ;{ecTb3qvRyT5+&?1*!vE(m1^maUY z^y=BgyOY!PJtwJo8&-O0E}vw{{m%ZhVYQ#-^PmTtGc>|B>~dH<&3=uf7|ay84IQyx{#>MC!hHwP%SI>)RjzQzxkQZBHvxn zTeW|S{Q@^}(|b#%&AY$S@zp+_T;VP6B%{wb^h|ZQBhDydqMzoj6dLzLY_qblU#nr$ zmZQrq2Qs-TTye~q{O*n1lYM7(6|Tn@K7K!eoBM9O!tult?0NG8UZ?)IoaCD^_t4bK z&IP}sm|jHe_!f{Pd-Hj~^qaRY%=|qgps?R)R>C5g*SmN0w`p(cw>nzgfA!Llu%JYV z)2b&9T-~z&nreNYv8=pneBVQV@jbkIk>FqNHno53Cm+^7QQvf9?YT$Sff`F4nJa0`PlBg3pY5H=O_9xt|yn?J+DP^}A7+9h_T^vJz znd$CEUIs-0=7XQR|3#ar))XijTRIhOQBs^+CT4U~X8yZ%>6)Hv7(UE9&%&SpG>MUc zfrEj;0muSoTLA`!1|W-t0jt!3`IB$fvfp1R%6Nbqy9x}=2m^t}j)Kt;7!84;76Ko- YxWDe^aC%-I_z2{5Pgg&ebxsLQ023<5`Tzg` From e96fd909eae12547525ce690d55ac0323d80c7c6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 20 Mar 2022 23:46:43 +0300 Subject: [PATCH 05/56] New assets --- res/font.png | Bin 0 -> 2027 bytes res/ui.glslf | 11 +++++++++++ res/ui.glslv | 16 ++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 res/font.png create mode 100644 res/ui.glslf create mode 100644 res/ui.glslv diff --git a/res/font.png b/res/font.png new file mode 100644 index 0000000000000000000000000000000000000000..3278f04cf6ece29ea3c3b9f7ed7d042702092dc8 GIT binary patch literal 2027 zcmVxr^0dAyo)a6&VPm%%iUV-rFdvpNU_C=mu{Y!%* zD^l3!tayrwc60_-KeP3XE;Av7RLxKp{ig$fS>tIPU?jlV&k_mXey)@-JETyg^P}G* zI!d(vKa=(+cgIIf)bdVXD~T=@3M*hxOblR#poxf4hA67w0gf5m)c{6+gD`EK06yy! zFt|VS$eL^lqJ>dHUo8PL0Ehs@MTA_{WA%O|=`vjZ0DxE`q62U@aCZQ^s|QLVy-vYX zC}|99=VH>bJ94A;7b%<5`3DjiSu4R|$0L7NeIIGt(Ztja07SKPL=R#25)|({nY(*F zBFr#WS#`CKQG#C$fUE>S2Oky1ECARE;QpQ-N4Ers5=AIcRSkd+5};iAtk&p^TNk1u zxOIR>17ODzz*+&!5}>jos`~c?-D6Vs0a7VptXC__OH zau74I(kHNkBw*VAj}ql#)S_BGawL72~$U zJ2RP+PPX%%JVC}rXI#Qu9zPkU(j8WYBfroIVb|fr?q>_t0T!}*6&dU5ZUVsl8L`VV zGf+JMigSA`)2Om?7=WT)(P02wZK!lS4__fdDsT<~Ov%$__1>8GsHFz|k%T03}PnX#iLaAkCBk zrl5*LXa@jC1dkm6h{P9A)$eftxTA?>cIb!OuXipXk-xKX3|Ssx(xkAGpJoCT5@bhy zuCsye@b_&FhMWw5PW5l2-MhrdodU+XT_ZY#f{DDVzfuAy975Rk%Mq>IJ#<`&5+$-! z#LCKH1C>ejW$l{pq2 z#T^H)!>wGM?+sLxPe~|M0EMc%c@+b^qkb;3h;CmOw{X|{4!dn`08mQqE+(w%ef90; z)e<0Nr6_Oi>_+8g+vhOTssWIyOSc)Uc;BIY?E&!g{p{JVH+GUD9zVkaFm`m5CYFg< zpzl>glw|^BH(5^P8FqLSId!1hamr}1F28iAUwd~YG_%Gd676RoLoC{VO4f1L_pHzTDsTF=8TQKgKNmF|ID$sNU-ma9)MK9 z8D~)WJsV?abylAh#R`DZlc3{nU!;NPrB6{{M3i60df=(;I5ujqyB+pv-o9OuM->Xop z2&cfjUzM$r5|Or{l7h{jIv$=?!mh5CyAziKfQA6*E&(!T7BT?Hy@;6s`rag0{#zwL zboQSh0W!zX7zw~kgvUt$wO>9v1KkopQ9q{sFb{CL4#3VJHh;H{LQA-(TLA-ri*nzh z0}KEH0B#g_mH^djbanj(00V#lz^egJy`AbtuA+QqV9+&~{e8In0l)wty<3$% zAQ2q^=9Eyje8kEa32@L190{-}|7%WBJDZgN-;HS}kKzW5Obg#(hE(nbqV*d93;+fI z1AvDBVCVirxAHTmpCV zT0dAB?QT!1Z1=AAbDR3CW(S)`#-82THaG834uT93!gOL*L?g;#MiKh?|6L$haTIs$ zDs}UUYMiWuVEBSa2O{8h13)2V;U%oA1Yo%K&g(G(fEIfIJ9Ge-L&%EjPyrxgB}4&$ z`XU^u1vB2V(KWQ9Z98{L<@r0kc$5I>o{rn5?PT*lrQ Date: Sun, 20 Mar 2022 23:48:21 +0300 Subject: [PATCH 06/56] Audio module, simple text rendering --- src/Assets.cpp | 14 +++ src/Assets.h | 5 + src/audio/Audio.cpp | 180 ++++++++++++++++++++++++++++++++++++ src/audio/Audio.h | 61 ++++++++++++ src/audio/audioutil.cpp | 194 +++++++++++++++++++++++++++++++++++++++ src/audio/audioutil.h | 44 +++++++++ src/declarations.h | 19 ++++ src/graphics/Batch2D.cpp | 76 ++++++++++++++- src/graphics/Batch2D.h | 10 ++ src/graphics/Font.cpp | 40 ++++++++ src/graphics/Font.h | 18 ++++ src/voxel_engine.cpp | 29 +++--- src/window/Camera.cpp | 5 +- src/window/Camera.h | 1 + src/world_render.h | 23 +++++ 15 files changed, 702 insertions(+), 17 deletions(-) create mode 100644 src/audio/Audio.cpp create mode 100644 src/audio/Audio.h create mode 100644 src/audio/audioutil.cpp create mode 100644 src/audio/audioutil.h create mode 100644 src/graphics/Font.cpp create mode 100644 src/graphics/Font.h diff --git a/src/Assets.cpp b/src/Assets.cpp index fbaaa21e..64f7d6b5 100644 --- a/src/Assets.cpp +++ b/src/Assets.cpp @@ -2,6 +2,7 @@ #include "graphics/Texture.h" #include "graphics/Shader.h" +#include "graphics/Font.h" Assets::~Assets() { for (auto& iter : shaders){ @@ -11,6 +12,10 @@ Assets::~Assets() { for (auto& iter : textures){ delete iter.second; } + + for (auto& iter : fonts){ + delete iter.second; + } } Texture* Assets::getTexture(std::string name){ @@ -29,3 +34,12 @@ Shader* Assets::getShader(std::string name){ void Assets::store(Shader* shader, std::string name){ shaders[name] = shader; } + + +Font* Assets::getFont(std::string name){ + return fonts[name]; +} + +void Assets::store(Font* font, std::string name){ + fonts[name] = font; +} diff --git a/src/Assets.h b/src/Assets.h index daca7d19..3dc9fa5d 100644 --- a/src/Assets.h +++ b/src/Assets.h @@ -6,10 +6,12 @@ class Texture; class Shader; +class Font; class Assets { std::unordered_map textures; std::unordered_map shaders; + std::unordered_map fonts; public: ~Assets(); Texture* getTexture(std::string name); @@ -17,6 +19,9 @@ public: Shader* getShader(std::string name); void store(Shader* shader, std::string name); + + Font* getFont(std::string name); + void store(Font* font, std::string name); }; #endif /* SRC_ASSETS_H_ */ diff --git a/src/audio/Audio.cpp b/src/audio/Audio.cpp new file mode 100644 index 00000000..1dec8ff8 --- /dev/null +++ b/src/audio/Audio.cpp @@ -0,0 +1,180 @@ +#include "Audio.h" +#include "audioutil.h" +#include +#include + +#include +#include + +ALCdevice* Audio::device; +ALCcontext* Audio::context; +unsigned Audio::maxSources; +unsigned Audio::maxBuffers = 1024; +std::vector Audio::allsources; +std::vector Audio::freesources; +std::vector Audio::allbuffers; +std::vector Audio::freebuffers; + +bool ALSource::setBuffer(ALBuffer* buffer){ + alSourcei(id, AL_BUFFER, buffer->id); + return alCheck(); +} + +bool ALSource::play(){ + alSourcePlay(id); + return alCheck(); +} + +bool ALSource::setPosition(glm::vec3 position){ + alSource3f(id, AL_POSITION, position.x, position.y, position.z); + return alCheck(); +} + +bool ALSource::setVelocity(glm::vec3 velocity){ + alSource3f(id, AL_VELOCITY, velocity.x, velocity.y, velocity.z); + return alCheck(); +} + +bool ALSource::setLoop(bool loop){ + alSourcei(id, AL_LOOPING, AL_TRUE ? loop : AL_FALSE); + return alCheck(); +} + +bool ALSource::setGain(float gain) { + alSourcef(id, AL_GAIN, gain); + return alCheck(); +} + + +bool ALSource::setPitch(float pitch) { + alSourcef(id, AL_PITCH, pitch); + return alCheck(); +} + +bool ALBuffer::load(int format, const char* data, int size, int freq){ + alBufferData(id, format, data, size, freq); + return alCheck(); +} + + +bool Audio::initialize(){ + device = alcOpenDevice(nullptr); + if (device == nullptr) + return false; + context = alcCreateContext(device, nullptr); + if (!alcMakeContextCurrent(context)){ + alcCloseDevice(device); + return false; + } + if (!alCheck()) + return false; + + ALCint size; + alcGetIntegerv(device, ALC_ATTRIBUTES_SIZE, 1, &size); + std::vector attrs(size); + alcGetIntegerv(device, ALC_ALL_ATTRIBUTES, size, &attrs[0]); + for(size_t i=0; iid); alCheck(); + alDeleteSources(1, &source->id); alCheck(); + } + + for (ALBuffer* buffer : allbuffers){ + alDeleteBuffers(1, &buffer->id); alCheck(); + } + + alcMakeContextCurrent(context); + alcDestroyContext(context); + if (!alcCloseDevice(device)){ + std::cerr << "device not closed!" << std::endl; + } + device = nullptr; + context = nullptr; +} + +ALSource* Audio::getFreeSource(){ + if (!freesources.empty()){ + ALSource* source = freesources.back(); + freesources.pop_back(); + return source; + } + if (allsources.size() == maxSources){ + std::cerr << "attempted to create new source, but limit is " << maxSources << std::endl; + return nullptr; + } + ALuint id; + alGenSources(1, &id); + if (!alCheck()) + return nullptr; + + ALSource* source = new ALSource(id); + allsources.push_back(source); + return source; +} + +ALBuffer* Audio::getFreeBuffer(){ + if (!freebuffers.empty()){ + ALBuffer* buffer = freebuffers.back(); + freebuffers.pop_back(); + return buffer; + } + if (allbuffers.size() == maxBuffers){ + std::cerr << "attempted to create new ALbuffer, but limit is " << maxBuffers << std::endl; + return nullptr; + } + ALuint id; + alGenBuffers(1, &id); + if (!alCheck()) + return nullptr; + + ALBuffer* buffer = new ALBuffer(id); + allbuffers.push_back(buffer); + return buffer; +} + +void Audio::freeSource(ALSource* source){ + freesources.push_back(source); +} + +void Audio::freeBuffer(ALBuffer* buffer){ + freebuffers.push_back(buffer); +} + +bool Audio::get_available_devices(std::vector& devicesVec){ + const ALCchar* devices; + devices = alcGetString(device, ALC_DEVICE_SPECIFIER); + if (!alCheck()) + return false; + + const char* ptr = devices; + + devicesVec.clear(); + + do { + devicesVec.push_back(std::string(ptr)); + ptr += devicesVec.back().size() + 1; + } + while(*(ptr + 1) != '\0'); + + return true; +} + +void Audio::setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up){ + ALfloat listenerOri[] = { at.x, at.y, at.z, up.x, up.y, up.z }; + + alListener3f(AL_POSITION, position.x, position.y, position.z); + alCheck(); + alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); + alCheck(); + alListenerfv(AL_ORIENTATION, listenerOri); + alCheck(); +} diff --git a/src/audio/Audio.h b/src/audio/Audio.h new file mode 100644 index 00000000..9861c0bb --- /dev/null +++ b/src/audio/Audio.h @@ -0,0 +1,61 @@ +#ifndef SRC_AUDIO_AUDIO_H_ +#define SRC_AUDIO_AUDIO_H_ + +#include +#include + +#include +#include + +#include + + +struct ALBuffer; + +struct ALSource { + ALuint id; + ALSource(ALuint id) : id(id) {} + + bool setPosition(glm::vec3 position); + bool setVelocity(glm::vec3 velocity); + bool setBuffer(ALBuffer* buffer); + bool setLoop(bool loop); + bool setGain(float gain); + bool setPitch(float pitch); + bool play(); +}; + +struct ALBuffer { + ALuint id; + ALBuffer(ALuint id) : id(id) {} + bool load(int format, const char* data, int size, int freq); +}; + +class Audio { + static ALCdevice* device; + static ALCcontext* context; + + static std::vector allsources; + static std::vector freesources; + + static std::vector allbuffers; + static std::vector freebuffers; + + static unsigned maxSources; + static unsigned maxBuffers; + +public: + static ALSource* getFreeSource(); + static ALBuffer* getFreeBuffer(); + static void freeSource(ALSource* source); + static void freeBuffer(ALBuffer* buffer); + + static bool initialize(); + static void finalize(); + static bool get_available_devices(std::vector& devicesVec); + + static void setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up); + +}; + +#endif /* SRC_AUDIO_AUDIO_H_ */ diff --git a/src/audio/audioutil.cpp b/src/audio/audioutil.cpp new file mode 100644 index 00000000..cfedfdec --- /dev/null +++ b/src/audio/audioutil.cpp @@ -0,0 +1,194 @@ +#include "audioutil.h" + +#include +#include +#include +#include +#include +#include + + +bool is_big_endian(void){ + union { + uint32_t i; + char c[4]; + } bint = {0x01020304}; + + return bint.c[0] == 1; +} + +std::int32_t convert_to_int(char* buffer, std::size_t len){ + std::int32_t a = 0; + if(!is_big_endian()) + std::memcpy(&a, buffer, len); + else + for(std::size_t i = 0; i < len; ++i) + reinterpret_cast(&a)[3 - i] = buffer[i]; + return a; +} + +bool check_al_errors(const std::string& filename, const std::uint_fast32_t line){ + ALenum error = alGetError(); + if(error != AL_NO_ERROR){ + std::cerr << "OpenAL ERROR (" << filename << ": " << line << ")\n" ; + switch(error){ + case AL_INVALID_NAME: + std::cerr << "AL_INVALID_NAME: a bad name (ID) was passed to an OpenAL function"; + break; + case AL_INVALID_ENUM: + std::cerr << "AL_INVALID_ENUM: an invalid enum value was passed to an OpenAL function"; + break; + case AL_INVALID_VALUE: + std::cerr << "AL_INVALID_VALUE: an invalid value was passed to an OpenAL function"; + break; + case AL_INVALID_OPERATION: + std::cerr << "AL_INVALID_OPERATION: the requested operation is not valid"; + break; + case AL_OUT_OF_MEMORY: + std::cerr << "AL_OUT_OF_MEMORY: the requested operation resulted in OpenAL running out of memory"; + break; + default: + std::cerr << "UNKNOWN AL ERROR: " << error; + } + std::cerr << std::endl; + return false; + } + return true; +} + +bool load_wav_file_header(std::ifstream& file, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size){ + char buffer[4]; + if(!file.is_open()) + return false; + + // the RIFF + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read RIFF" << std::endl; + return false; + } + if(std::strncmp(buffer, "RIFF", 4) != 0){ + std::cerr << "ERROR: file is not a valid WAVE file (header doesn't begin with RIFF)" << std::endl; + return false; + } + + // the size of the file + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read size of file" << std::endl; + return false; + } + + // the WAVE + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read WAVE" << std::endl; + return false; + } + if(std::strncmp(buffer, "WAVE", 4) != 0){ + std::cerr << "ERROR: file is not a valid WAVE file (header doesn't contain WAVE)" << std::endl; + return false; + } + + // "fmt/0" + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read fmt/0" << std::endl; + return false; + } + + // this is always 16, the size of the fmt data chunk + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read the 16" << std::endl; + return false; + } + + // PCM should be 1? + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read PCM" << std::endl; + return false; + } + + // the number of channels + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read number of channels" << std::endl; + return false; + } + channels = convert_to_int(buffer, 2); + + // sample rate + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read sample rate" << std::endl; + return false; + } + sampleRate = convert_to_int(buffer, 4); + + // (sampleRate * bitsPerSample * channels) / 8 + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read (sampleRate * bitsPerSample * channels) / 8" << std::endl; + return false; + } + + // ?? dafaq + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read dafaq" << std::endl; + return false; + } + + // bitsPerSample + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read bits per sample" << std::endl; + return false; + } + bitsPerSample = convert_to_int(buffer, 2); + + // data chunk header "data" + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read data chunk header" << std::endl; + return false; + } + if(std::strncmp(buffer, "data", 4) != 0){ + std::cerr << "ERROR: file is not a valid WAVE file (doesn't have 'data' tag)" << std::endl; + return false; + } + + // size of data + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read data size" << std::endl; + return false; + } + size = convert_to_int(buffer, 4); + + /* cannot be at the end of file */ + if(file.eof()){ + std::cerr << "ERROR: reached EOF on the file" << std::endl; + return false; + } + if(file.fail()){ + std::cerr << "ERROR: fail state set on the file" << std::endl; + return false; + } + return true; +} + +char* load_wav(const std::string& filename, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size){ + std::ifstream in(filename, std::ios::binary); + if(!in.is_open()){ + std::cerr << "ERROR: Could not open \"" << filename << "\"" << std::endl; + return nullptr; + } + if(!load_wav_file_header(in, channels, sampleRate, bitsPerSample, size)){ + std::cerr << "ERROR: Could not load wav header of \"" << filename << "\"" << std::endl; + return nullptr; + } + + char* data = new char[size]; + + in.read(data, size); + + return data; +} diff --git a/src/audio/audioutil.h b/src/audio/audioutil.h new file mode 100644 index 00000000..f62a06cb --- /dev/null +++ b/src/audio/audioutil.h @@ -0,0 +1,44 @@ +#ifndef SRC_AUDIO_AUDIOUTIL_H_ +#define SRC_AUDIO_AUDIOUTIL_H_ + +#include +#include + +#include + +#define alCheck() check_al_errors(__FILE__, __LINE__) + +bool check_al_errors(const std::string& filename, const std::uint_fast32_t line); + +bool load_wav_file_header(std::ifstream& file, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size); + +char* load_wav(const std::string& filename, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size); + +static inline ALenum to_al_format(short channels, short samples){ + bool stereo = (channels > 1); + + switch (samples) { + case 16: + if (stereo) + return AL_FORMAT_STEREO16; + else + return AL_FORMAT_MONO16; + case 8: + if (stereo) + return AL_FORMAT_STEREO8; + else + return AL_FORMAT_MONO8; + default: + return -1; + } +} + +#endif /* SRC_AUDIO_AUDIOUTIL_H_ */ diff --git a/src/declarations.h b/src/declarations.h index b49304bf..2abce32e 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -5,6 +5,7 @@ #include "Assets.h" #include "graphics/Shader.h" #include "graphics/Texture.h" +#include "graphics/Font.h" #include "window/Window.h" #include "voxels/Block.h" @@ -32,6 +33,17 @@ bool _load_texture(Assets* assets, std::string filename, std::string name){ return true; } +bool _load_font(Assets* assets, std::string filename, std::string name){ + Texture* texture = load_texture(filename); + if (texture == nullptr){ + std::cerr << "failed to load bitmap font '" << name << "'" << std::endl; + return false; + } + Font* font = new Font(texture); + assets->store(font, name); + return true; +} + int initialize_assets(Assets* assets) { #define LOAD_SHADER(VERTEX, FRAGMENT, NAME) \ if (!_load_shader(assets, VERTEX, FRAGMENT, NAME))\ @@ -39,12 +51,19 @@ int initialize_assets(Assets* assets) { #define LOAD_TEXTURE(FILENAME, NAME) \ if (!_load_texture(assets, FILENAME, NAME))\ return 1; +#define LOAD_FONT(FILENAME, NAME) \ + if (!_load_font(assets, FILENAME, NAME))\ + return 1; LOAD_SHADER("res/main.glslv", "res/main.glslf", "main"); LOAD_SHADER("res/crosshair.glslv", "res/crosshair.glslf", "crosshair"); LOAD_SHADER("res/lines.glslv", "res/lines.glslf", "lines"); + LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui"); LOAD_TEXTURE("res/block.png", "block"); + //LOAD_TEXTURE("res/font.png", "font"); + + LOAD_FONT("res/font.png", "normal"); return 0; } diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index e6b43770..9c114576 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -1,5 +1,8 @@ #include "Batch2D.h" #include "Mesh.h" +#include "Texture.h" + +#include Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), @@ -8,11 +11,80 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), 2, 2, 4, 0 //null terminator }; - buffer = new float[capacity]; - mesh = new Mesh(nullptr, 0, attrs); + buffer = new float[capacity * 8]; + mesh = new Mesh(buffer, 0, attrs); + index = 0; + + unsigned char pixels[] = { + 255, 255, 255, 255, + }; + blank = new Texture(pixels, 1, 1); + _texture = nullptr; } Batch2D::~Batch2D(){ + delete blank; delete buffer; delete mesh; } + +void Batch2D::begin(){ + _texture = nullptr; + blank->bind(); +} + +void Batch2D::vertex(float x, float y, + float u, float v, + float r, float g, float b, float a) { + buffer[index++] = x; + buffer[index++] = y; + buffer[index++] = u; + buffer[index++] = v; + buffer[index++] = r; + buffer[index++] = g; + buffer[index++] = b; + buffer[index++] = a; +} + +void Batch2D::texture(Texture* new_texture){ + if (_texture == new_texture) + return; + _texture = new_texture; + if (new_texture == nullptr) + blank->bind(); + else + new_texture->bind(); +} + +void Batch2D::rect(float x, float y, float w, float h){ + const float r = color.r; + const float g = color.g; + const float b = color.b; + const float a = color.a; + + vertex(x, y, 0, 0, r,g,b,a); + vertex(x+w, y+h, 1, 1, r,g,b,a); + vertex(x, y+h, 0, 1, r,g,b,a); + + vertex(x, y, 0, 0, r,g,b,a); + vertex(x+w, y, 1, 0, r,g,b,a); + vertex(x+w, y+h, 1, 1, r,g,b,a); +} + +void Batch2D::rect(float x, float y, float w, float h, + float u, float v, float tx, float ty, + float r, float g, float b, float a){ + vertex(x, y, u, v, r,g,b,a); + vertex(x+w, y+h, u+tx, v+ty, r,g,b,a); + vertex(x, y+h, u, v+ty, r,g,b,a); + + vertex(x, y, u, v, r,g,b,a); + vertex(x+w, y, u+tx, v, r,g,b,a); + vertex(x+w, y+h, u+tx, v+ty, r,g,b,a); +} + +void Batch2D::render() { + mesh->reload(buffer, index / 8); + mesh->draw(GL_TRIANGLES); + index = 0; +} diff --git a/src/graphics/Batch2D.h b/src/graphics/Batch2D.h index 7e756eda..1ea7657a 100644 --- a/src/graphics/Batch2D.h +++ b/src/graphics/Batch2D.h @@ -5,6 +5,7 @@ #include class Mesh; +class Texture; class Batch2D { float* buffer; @@ -12,6 +13,10 @@ class Batch2D { size_t offset; glm::vec4 color; Mesh* mesh; + size_t index; + + Texture* blank; + Texture* _texture; void vertex(float x, float y, float u, float v, @@ -20,7 +25,12 @@ public: Batch2D(size_t capacity); ~Batch2D(); + void begin(); + void texture(Texture* texture); void rect(float x, float y, float w, float h); + void rect(float x, float y, float w, float h, + float u, float v, float tx, float ty, + float r, float g, float b, float a); void render(); }; diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp new file mode 100644 index 00000000..0947357b --- /dev/null +++ b/src/graphics/Font.cpp @@ -0,0 +1,40 @@ +#include "Font.h" +#include "Texture.h" +#include "Batch2D.h" + +Font::Font(Texture* texture) : texture(texture) { +} + +Font::~Font(){ + delete texture; +} + + +void Font::draw(Batch2D* batch, std::string text, int x, int y) { + for (char c : text){ + float u = (c % 16) / 16.0f; + float v = 1.0f - ((c / 16) / 16.0f) - 1.0f/16.0f; + batch->rect(x, y, 8, 8, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); + + int gw = 7; + switch (c){ + case 'l': + case 'i': + case 'j': + case '|': + case '.': + case ',': + case ':': + case ';': + gw = 3; + break; + case 't': + gw = 5; + break; + case ' ': + gw = 3; + break; + } + x += gw; + } +} diff --git a/src/graphics/Font.h b/src/graphics/Font.h new file mode 100644 index 00000000..c771b3e4 --- /dev/null +++ b/src/graphics/Font.h @@ -0,0 +1,18 @@ +#ifndef GRAPHICS_FONT_H_ +#define GRAPHICS_FONT_H_ + +#include + +class Texture; +class Batch2D; + +class Font { +public: + Texture* texture; + Font(Texture* texture); + ~Font(); + + void draw(Batch2D* batch, std::string text, int x, int y); +}; + +#endif /* GRAPHICS_FONT_H_ */ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 3cb54bef..5fcdee75 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -2,6 +2,7 @@ // sudo apt install libgl-dev libglew-dev libglfw3-dev libpng-dev libglm-dev #include #include +#include #define GLEW_STATIC #include @@ -22,6 +23,7 @@ using namespace glm; #include "graphics/Mesh.h" #include "graphics/VoxelRenderer.h" #include "graphics/LineBatch.h" +#include "graphics/Batch2D.h" #include "window/Window.h" #include "window/Events.h" #include "window/Camera.h" @@ -40,6 +42,8 @@ using namespace glm; #include "physics/Hitbox.h" #include "physics/PhysicsSolver.h" +#include "audio/Audio.h" +#include "audio/audioutil.h" #include "Assets.h" #include "objects/Player.h" @@ -86,6 +90,9 @@ void update_controls(PhysicsSolver* physics, Player* player, float delta){ + if (Events::jpressed(GLFW_KEY_ESCAPE)){ + Window::setShouldClose(true); + } if (Events::jpressed(GLFW_KEY_TAB)){ Events::toogleCursor(); } @@ -244,16 +251,13 @@ void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, int WIDTH = 1280; int HEIGHT = 720; -#define GRAVITY 19.6f -#define DEFAULT_PLAYER_SPEED 4.0f - -vec3 spawnpoint(-320, 255, 32); - int main() { setup_definitions(); - Window::initialize(WIDTH, HEIGHT, "VoxelEngine Part-11"); + Audio::initialize(); + + Window::initialize(WIDTH, HEIGHT, "Window 2.0"); Events::initialize(); std::cout << "-- loading assets" << std::endl; @@ -266,12 +270,12 @@ int main() { } std::cout << "-- loading world" << std::endl; - Camera *camera = new Camera(spawnpoint, radians(90.0f)); + Camera *camera = new Camera(vec3(-320,255,32), radians(90.0f)); WorldFiles *wfile = new WorldFiles("world/", REGION_VOL * (CHUNK_VOL * 2 + 8)); Chunks *chunks = new Chunks(34,1,34, 0,0,0); - Player* player = new Player(vec3(camera->position), DEFAULT_PLAYER_SPEED, camera); + Player* player = new Player(vec3(camera->position), 4.0f, camera); wfile->readPlayer(player); camera->rotation = mat4(1.0f); camera->rotate(player->camY, player->camX, 0); @@ -279,7 +283,7 @@ int main() { std::cout << "-- preparing systems" << std::endl; VoxelRenderer renderer(1024*1024); - PhysicsSolver physics(vec3(0,-GRAVITY,0)); + PhysicsSolver physics(vec3(0,-9.8f*2.0f,0)); Lighting lighting(chunks); init_renderer(); @@ -297,16 +301,13 @@ int main() { std::cout << "-- initializing finished" << std::endl; + while (!Window::isShouldClose()){ frame++; float currentTime = glfwGetTime(); delta = currentTime - lastTime; lastTime = currentTime; - if (Events::jpressed(GLFW_KEY_ESCAPE)){ - Window::setShouldClose(true); - } - if (Events::jpressed(GLFW_KEY_O)){ occlusion = !occlusion; } @@ -336,8 +337,8 @@ int main() { delete assets; finalize_renderer(); + Audio::finalize(); Events::finalize(); Window::terminate(); return 0; } - diff --git a/src/window/Camera.cpp b/src/window/Camera.cpp index 4dfcc2b7..4875bd95 100644 --- a/src/window/Camera.cpp +++ b/src/window/Camera.cpp @@ -37,7 +37,10 @@ void Camera::rotate(float x, float y, float z){ mat4 Camera::getProjection(){ float aspect = (float)Window::width / (float)Window::height; - return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f); + if (perspective) + return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f); + else + return glm::ortho(0.0f, fov*aspect, 0.0f, fov); } mat4 Camera::getView(){ diff --git a/src/window/Camera.h b/src/window/Camera.h index 91648adb..4d8a4462 100644 --- a/src/window/Camera.h +++ b/src/window/Camera.h @@ -23,6 +23,7 @@ public: float fov; float zoom; mat4 rotation; + bool perspective = true; Camera(vec3 position, float fov); void rotate(float x, float y, float z); diff --git a/src/world_render.h b/src/world_render.h index d2909d9a..890c4203 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -37,17 +37,26 @@ int attrs[] = { 2, 0 //null terminator }; +int uiscale = 2; + LineBatch *lineBatch; +Batch2D *batch; +Camera *uicamera; void init_renderer(){ crosshair = new Mesh(vertices, 4, attrs); lineBatch = new LineBatch(4096); + + batch = new Batch2D(1024); + uicamera = new Camera(glm::vec3(), Window::height / uiscale); + uicamera->perspective = false; } void finalize_renderer(){ delete crosshair; delete lineBatch; + delete batch; } void draw_chunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ @@ -100,6 +109,7 @@ void draw_world(Camera* camera, Assets* assets, Chunks* chunks, bool occlusion){ glClearColor(0.7f,0.71f,0.73f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); _chunks = chunks; @@ -151,6 +161,19 @@ void draw_world(Camera* camera, Assets* assets, lineBatch->line(camera->position.x, camera->position.y-0.5f, camera->position.z, camera->position.x+0.1f, camera->position.y-0.5f, camera->position.z, 1, 0, 0, 1); lineBatch->line(camera->position.x, camera->position.y-0.5f, camera->position.z, camera->position.x, camera->position.y-0.5f, camera->position.z+0.1f, 0, 0, 1, 1); lineBatch->render(); + + + glDisable(GL_DEPTH_TEST); + Shader* uishader = assets->getShader("ui"); + uishader->use(); + uishader->uniformMatrix("u_projview", uicamera->getProjection()); + + Font* font = assets->getFont("normal"); + batch->begin(); + batch->texture(font->texture); + font->draw(batch, "void Font::draw(Batch2D* batch, std::string text, int x, int y) {", 10, 10); + //batch->rect(0, 0, 256, 256); + batch->render(); } #endif // WORLD_RENDERER_CPP From 5363d0e7ba2418039e6dceb17df1f91a26010ce2 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 20 Mar 2022 23:49:26 +0300 Subject: [PATCH 07/56] Linux makefiles updated --- Debug/makefile | 1 + Debug/objects.mk | 2 +- Debug/sources.mk | 1 + Debug/src/audio/subdir.mk | 27 +++++++++++++++++++++++++++ Debug/src/graphics/subdir.mk | 3 +++ 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 Debug/src/audio/subdir.mk diff --git a/Debug/makefile b/Debug/makefile index cbc3aa03..9c5b3843 100644 --- a/Debug/makefile +++ b/Debug/makefile @@ -16,6 +16,7 @@ RM := rm -rf -include src/lighting/subdir.mk -include src/graphics/subdir.mk -include src/files/subdir.mk +-include src/audio/subdir.mk -include src/subdir.mk -include subdir.mk -include objects.mk diff --git a/Debug/objects.mk b/Debug/objects.mk index 471b1bf6..f076e108 100644 --- a/Debug/objects.mk +++ b/Debug/objects.mk @@ -4,5 +4,5 @@ USER_OBJS := -LIBS := -lglfw -lpng -lGL -lGLEW -lstdc++fs +LIBS := -lglfw -lpng -lopenal -lGL -lGLEW -lstdc++fs diff --git a/Debug/sources.mk b/Debug/sources.mk index fb65165d..b2849f80 100644 --- a/Debug/sources.mk +++ b/Debug/sources.mk @@ -24,6 +24,7 @@ CPP_DEPS := # Every subdirectory with source files must be described here SUBDIRS := \ src \ +src/audio \ src/files \ src/graphics \ src/lighting \ diff --git a/Debug/src/audio/subdir.mk b/Debug/src/audio/subdir.mk new file mode 100644 index 00000000..a12515df --- /dev/null +++ b/Debug/src/audio/subdir.mk @@ -0,0 +1,27 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +CPP_SRCS += \ +../src/audio/Audio.cpp \ +../src/audio/audioutil.cpp + +OBJS += \ +./src/audio/Audio.o \ +./src/audio/audioutil.o + +CPP_DEPS += \ +./src/audio/Audio.d \ +./src/audio/audioutil.d + + +# Each subdirectory must supply rules for building sources it contributes +src/audio/%.o: ../src/audio/%.cpp src/audio/subdir.mk + @echo 'Building file: $<' + @echo 'Invoking: Cross G++ Compiler' + g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/Debug/src/graphics/subdir.mk b/Debug/src/graphics/subdir.mk index db314574..0797e63c 100644 --- a/Debug/src/graphics/subdir.mk +++ b/Debug/src/graphics/subdir.mk @@ -5,6 +5,7 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ ../src/graphics/Batch2D.cpp \ +../src/graphics/Font.cpp \ ../src/graphics/LineBatch.cpp \ ../src/graphics/Mesh.cpp \ ../src/graphics/Shader.cpp \ @@ -13,6 +14,7 @@ CPP_SRCS += \ OBJS += \ ./src/graphics/Batch2D.o \ +./src/graphics/Font.o \ ./src/graphics/LineBatch.o \ ./src/graphics/Mesh.o \ ./src/graphics/Shader.o \ @@ -21,6 +23,7 @@ OBJS += \ CPP_DEPS += \ ./src/graphics/Batch2D.d \ +./src/graphics/Font.d \ ./src/graphics/LineBatch.d \ ./src/graphics/Mesh.d \ ./src/graphics/Shader.d \ From 3d7c3c334d067dc08137d0f0bae50b7be19dcb78 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 20 Mar 2022 23:50:36 +0300 Subject: [PATCH 08/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 80e6234f..f1fdcdf4 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ### Debian-based distro: - $ sudo apt install libglfw3-dev libglfw3 libglew-dev libglm-dev libpng-dev + $ sudo apt install libglfw3-dev libglfw3 libglew-dev libglm-dev libpng-dev libopenal-dev ### RHEL-based distro: From cbcfcc1fd363afe527fe61af6e6620a5a8b41942 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 7 Jun 2022 22:50:23 +0300 Subject: [PATCH 09/56] gitignore_update --- .gitignore | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 6bf13089..492224c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -Debug/src/*.d -Debug/src/*.o -Debug/src/*/*.d -Debug/src/*/*.o +Debug/src/**/*.d +Debug/src/**/*.o Debug/voxel_engine + +.vscode \ No newline at end of file From 9571da03f1e8fd2cc7361367864edb729adb5993 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 7 Jun 2022 22:51:24 +0300 Subject: [PATCH 10/56] fix string erorr --- src/files/WorldFiles.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index e79aed04..69d2bda3 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -3,6 +3,7 @@ #include #include +// #include class Player; From 329ce2ec8f1b35bea766b67badc8e639b9eaee17 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 7 Jun 2022 22:52:34 +0300 Subject: [PATCH 11/56] project structure updates --- Debug/res | 1 + 1 file changed, 1 insertion(+) create mode 120000 Debug/res diff --git a/Debug/res b/Debug/res new file mode 120000 index 00000000..85ee7023 --- /dev/null +++ b/Debug/res @@ -0,0 +1 @@ +../res \ No newline at end of file From 58ef13e402d0a5855ad46687d5979ac96995f0bc Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 7 Jun 2022 22:52:59 +0300 Subject: [PATCH 12/56] README update --- README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index f1fdcdf4..e51becaa 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,29 @@ -# Run in windows with compiled executable file +# Run in windows with compiled executable file: [EXE for windows](https://drive.google.com/file/d/1lkFc5nyYOs0Yyu1wmOoAAwEp4r9jO1tE/view?usp=sharing)
[MinGW libraries (include & lib) + glew32.dll](https://drive.google.com/file/d/1k1Hnbz2Uhr4-03upt2yHxKws396HQDra/view?usp=sharing) -# Run in linux with +# Run in linux: `$ git clone https://github.com/MihailRis/VoxelEngine-Cpp.git` `$ cd VoxelEngine-Cpp/Debug` -### Debian-based distro: - - $ sudo apt install libglfw3-dev libglfw3 libglew-dev libglm-dev libpng-dev libopenal-dev - -### RHEL-based distro: - - $ sudo dnf install glfw-devel glfw glew-devel glm-devel libpng-devel - `$ make` -`$ cd ..` +`$ ./voxel_engine` -`$ ./Debug/voxel_engine` +## Instal libs: +#### Debian-based distro: +`$ sudo apt install libglfw3-dev libglfw3 libglew-dev libglm-dev libpng-dev libopenal-dev` -# Note for MinGW compiling +#### RHEL-based distro: +`$ sudo dnf install glfw-devel glfw glew-devel glm-devel libpng-devel` + +# Note for fix string erorr: +To fix problem, uncomment `#include ` in `src/files/WorldFiles.h`. + + +# Note for MinGW compiling: To fix problem with `#include ` get headers `mingw.thread.h` and `mingw.invoke.h` from: https://github.com/meganz/mingw-std-threads From 8cc5bdf0b125ae30dfe7a1173a54b76750334dee Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Wed, 8 Jun 2022 16:19:25 +0300 Subject: [PATCH 13/56] F3 add --- src/voxel_engine.cpp | 6 +++++- src/world_render.h | 14 +++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 5fcdee75..3f6f9841 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -296,6 +296,7 @@ int main() { long frame = 0; bool occlusion = false; + bool devdata = false; glfwSwapInterval(1); @@ -311,6 +312,9 @@ int main() { if (Events::jpressed(GLFW_KEY_O)){ occlusion = !occlusion; } + if (Events::jpressed(GLFW_KEY_F3)){ + devdata = !devdata; + } update_controls(&physics, chunks, player, delta); update_interaction(chunks, &physics, player, &lighting); @@ -322,7 +326,7 @@ int main() { for (int i = 0; i < freeLoaders; i++) chunksController.loadVisible(wfile); - draw_world(camera, assets, chunks, occlusion); + draw_world(camera, assets, chunks, occlusion, devdata); Window::swapBuffers(); Events::pullEvents(); diff --git a/src/world_render.h b/src/world_render.h index 890c4203..f19872ae 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -105,8 +105,8 @@ bool chunks_comparator(size_t i, size_t j) { } -void draw_world(Camera* camera, Assets* assets, - Chunks* chunks, bool occlusion){ +void draw_world(Camera* camera, Assets* assets, Chunks* chunks, + bool occlusion, bool devdata){ glClearColor(0.7f,0.71f,0.73f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); @@ -158,8 +158,9 @@ void draw_world(Camera* camera, Assets* assets, linesShader->use(); linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView()); glLineWidth(2.0f); - lineBatch->line(camera->position.x, camera->position.y-0.5f, camera->position.z, camera->position.x+0.1f, camera->position.y-0.5f, camera->position.z, 1, 0, 0, 1); - lineBatch->line(camera->position.x, camera->position.y-0.5f, camera->position.z, camera->position.x, camera->position.y-0.5f, camera->position.z+0.1f, 0, 0, 1, 1); + lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x+0.01f, camera->position.y-0.1f, camera->position.z, 1, 0, 0, 1); + lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f, camera->position.z+0.01f, 0, 0, 1, 1); + lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f+0.01f, camera->position.z, 0, 1, 0, 1); lineBatch->render(); @@ -171,7 +172,10 @@ void draw_world(Camera* camera, Assets* assets, Font* font = assets->getFont("normal"); batch->begin(); batch->texture(font->texture); - font->draw(batch, "void Font::draw(Batch2D* batch, std::string text, int x, int y) {", 10, 10); + // font->draw(batch, "void Font::draw(Batch2D* batch, std::string text, int x, int y) {", 10, 10); + if (devdata){ + font->draw(batch, "devdata does not exist", 10, 10); + } //batch->rect(0, 0, 256, 256); batch->render(); } From cf3a4fa09648007a4b451bf6733e70c593ff8021 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 28 Jun 2022 15:17:25 +0300 Subject: [PATCH 14/56] texture update --- res/block.png | Bin 8247 -> 9156 bytes res/block.png.old | Bin 0 -> 8247 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/block.png.old diff --git a/res/block.png b/res/block.png index 5e2512c7d531cc21c8c2cb913134d300f2800ef2..3b8f692181aba04455d58e74f0e38b77f8a7b766 100644 GIT binary patch literal 9156 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 Date: Tue, 28 Jun 2022 15:17:42 +0300 Subject: [PATCH 15/56] README update --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index e51becaa..608b3fa8 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,6 @@ `$ sudo dnf install glfw-devel glfw glew-devel glm-devel libpng-devel` -# Note for fix string erorr: -To fix problem, uncomment `#include ` in `src/files/WorldFiles.h`. - - # Note for MinGW compiling: To fix problem with `#include ` get headers `mingw.thread.h` and `mingw.invoke.h` from: https://github.com/meganz/mingw-std-threads From 1bae1c1c7fd4f71c60122c7213c62594061f6a45 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 28 Jun 2022 15:18:31 +0300 Subject: [PATCH 16/56] string in WorldFiles fix --- src/files/WorldFiles.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index 69d2bda3..9495f58b 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -3,8 +3,9 @@ #include #include -// #include - +#ifndef std::string +#include +#endif class Player; #define REGION_SIZE_BIT 5 From 6162bf5573079697a869c53f5cae476d2ef8f81c Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 28 Jun 2022 15:28:06 +0300 Subject: [PATCH 17/56] shader update --- res/main.glslf | 2 +- src/world_render.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/main.glslf b/res/main.glslf index 1b998767..f8197996 100644 --- a/res/main.glslf +++ b/res/main.glslf @@ -12,6 +12,6 @@ void main(){ vec4 tex_color = texture(u_texture0, a_texCoord); //if (tex_color.a < 0.5) // discard; - float depth = (a_distance/256.0)*(a_distance/256.0)*256.0; + float depth = (a_distance/256.0)*(a_distance/256.0)*256.0/6; f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth/256.0/1.0f)); } diff --git a/src/world_render.h b/src/world_render.h index f19872ae..923c2c2c 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -122,7 +122,7 @@ void draw_world(Camera* camera, Assets* assets, Chunks* chunks, shader->uniformMatrix("u_proj", camera->getProjection()); shader->uniformMatrix("u_view", camera->getView()); shader->uniform1f("u_gamma", 1.6f); - shader->uniform3f("u_skyLightColor", 1.8f,1.8f,1.8f); + shader->uniform3f("u_skyLightColor", 2.2f,2.2f,2.2f); shader->uniform3f("u_fogColor", 0.7f,0.71f,0.73f); shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); texture->bind(); From c38eeaa57d82dc05351f3f6bdf0dc7853ae19483 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 28 Jun 2022 15:36:55 +0300 Subject: [PATCH 18/56] color update --- src/world_render.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world_render.h b/src/world_render.h index 923c2c2c..b56dfa0d 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -107,7 +107,7 @@ bool chunks_comparator(size_t i, size_t j) { void draw_world(Camera* camera, Assets* assets, Chunks* chunks, bool occlusion, bool devdata){ - glClearColor(0.7f,0.71f,0.73f,1); + glClearColor(0.7f,0.81f,1.0f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); From 0aa891f35fe27f656ff910fe8f020f6373e7468e Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 28 Jun 2022 18:35:15 +0300 Subject: [PATCH 19/56] generation update --- res/block.png | Bin 9156 -> 264609 bytes src/declarations.h | 29 +++++++++++++++++++---------- src/voxels/WorldGenerator.cpp | 28 +++++++++++++++++++--------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/res/block.png b/res/block.png index 3b8f692181aba04455d58e74f0e38b77f8a7b766..cf25628e477bf3ef0f05f1333e575c6970a6e8bf 100644 GIT binary patch literal 264609 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 = 1; block->lightPassing = true; @@ -79,48 +79,48 @@ void setup_definitions() { block->selectable = false; Block::blocks[block->id] = block; - // STONE + // DIRT 1 block = new Block(1,2); Block::blocks[block->id] = block; - // GRASS + // GRASS 2 block = new Block(2,4); block->textureFaces[2] = 2; block->textureFaces[3] = 1; Block::blocks[block->id] = block; - // LAMP + // LAMP 3 block = new Block(3,3); block->emission[0] = 15; block->emission[1] = 14; block->emission[2] = 13; Block::blocks[block->id] = block; - // GLASS + // GLASS 4 block = new Block(4,5); block->drawGroup = 2; block->lightPassing = true; Block::blocks[block->id] = block; - // PLANKS + // PLANKS 5 block = new Block(5,6); Block::blocks[block->id] = block; - // WOOD + // WOOD 6 block = new Block(6,7); block->textureFaces[2] = 8; block->textureFaces[3] = 8; Block::blocks[block->id] = block; - // LEAVES + // LEAVES 7 block = new Block(7,9); Block::blocks[block->id] = block; - // ACTUAL STONE + // STONE 8 block = new Block(8,10); Block::blocks[block->id] = block; - // WATER + // WATER 9 block = new Block(9,11); block->drawGroup = 4; block->lightPassing = true; @@ -128,6 +128,15 @@ void setup_definitions() { block->obstacle = false; block->selectable = false; Block::blocks[block->id] = block; + + // SEND 10 + block = new Block(10,12); + Block::blocks[block->id] = block; + + // BEDROCK 11 + block = new Block(11,13); + block->selectable = false; + Block::blocks[block->id] = block; } #endif // DECLARATIONS_H diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index 0e27ff3e..60938091 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -34,7 +34,8 @@ float calc_height(fnl_state *noise, int real_x, int real_z){ height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f; height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f; height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f; - height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F; + height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.0625f; + // height += fnlGetNoise3D(noise, real_x*s*32,real_z*s*32, 0.0f)*0.03f; height = height * 0.5f + 0.5f; height *= height; height *= (140.0f)*0.12f/s; @@ -71,7 +72,7 @@ int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights, int centerX = tileX * tileSize + tileSize/2 + randomX; int centerY = tileY * tileSize + tileSize/2 + randomZ; int height = (int)calc_height_faster(noise, centerX, centerY); - if (height < 55) + if ((height < 57) || (fnlGetNoise3D(noise, real_x*0.025f,real_z*0.025f, 0.0f)*0.5f > 0.5)) return 0; int lx = real_x - centerX; int radius = random->rand() % 4 + 3; @@ -102,20 +103,19 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz){ } for (int z = 0; z < CHUNK_D; z++){ + int real_z = z + cz * CHUNK_D; for (int x = 0; x < CHUNK_W; x++){ int real_x = x + cx * CHUNK_W; - int real_z = z + cz * CHUNK_D; float height = heights[z*CHUNK_W+x]; for (int y = 0; y < CHUNK_H; y++){ int real_y = y + cy * CHUNK_H; int id = real_y < 55 ? 9 : 0; - if (real_y == (int)height) + if ((real_y == (int)height) && (54 < real_y)) id = 2; - else if (real_y < height){ - if (real_y < height-6) + else if (real_y < (height - 6)){ id = 8; - else + } else if (real_y < height){ id = 1; } else { int tree = generate_tree(&noise, &random, heights, real_x, real_y, real_z, 16); @@ -127,11 +127,21 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz){ id = tree; } } + // if ((real_y < height) && (57 > height) && (height > 51) && ((int)height == real_y)){ + // id = 10; + // } + // if ( ((height - (1 - 0.1 * pow(height - 55, 4))) < real_y) && (real_y < height)){ + // id = 10; + // } + + if ( ((height - (1.5 - 0.2 * pow(height - 55, 4))) < real_y) && (real_y < height)){ + id = 10; + } if (real_y <= 2) - id = 2; + id = 11; voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id; } } } -} +} \ No newline at end of file From 4e5869882e441bf02ab8998e8369d196eb043c55 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 28 Jun 2022 19:03:01 +0300 Subject: [PATCH 20/56] micro fix --- res/block.png | Bin 264609 -> 264603 bytes src/voxel_engine.cpp | 8 +++++++- src/voxels/WorldGenerator.cpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/res/block.png b/res/block.png index cf25628e477bf3ef0f05f1333e575c6970a6e8bf..b89677861bda446d15759012688719499c6ded2b 100644 GIT binary patch delta 1890 zcmV-o2c7t#lMtJe5RfDRj*%rIe<==y_kM~x0s;w%<1m`_4f^=?5jp%*S}&@4neG`q$orUl&XVVsA3olM z`>XNHv+yi$gP;4AYpDFRpng8(t8ua4#>?k6`4^Ak!%*h_X}s?n*iTpdfB2lU;t=z5 zXKU9=e(HNrAECV7m^esGc`d8l&c}H7*WI`y^)w&Rw9-t2drFfmB^^;&(&fm0J*P}u z)V#Cv%z5VW8jIq&+=nPvgzR zF!{l)^1Og9Of;VQw%FIZ0aC=?hBHz?AXO5%Z5r@x9z%p$8NhHsCLTHW2YWJaoXvhsJ&2qe!=Wd&f9(EYLavO#e<{9J9Tsz)y`xSlg*k2G z8dVhYEbo4fP1k)C^hToyA)==er&~_DJ!4#{+HI2bl`*=?rqHrzbgSN^!Jr{RX1rII zJ(O5;>@xZla!QxoL?7S1u=Q?nWY)f9s9oWUy84QwhId<2@NSm&T5Gr=A)gu$792n?NkAA39v;Qe>h6Mqs%&b598-EW{Z3}r7#@K z+QqWx(ku-ewn<;R#{-(nI(T0DJj|cgIwn2N&^Q~qda+8+^QBo})ugJ;WVOyW1Sw(q zY$aluyAV;E*B@P!>Je%<1{^etGmG6S8^xeI{S;Rn`0wk>pcy%8^B9L07`x_x=TV_C zgr$#8e}mqIc8HyEU7VSEZlY%RAvv!YbFot znbuOBTq!h$tYyZrwa(lPqVx5jPC;+Z%c8Rts4WMPEWK47?3*d#wD4mj_yd0Mhb}sN zQs=E6?EqfVGx{KUy=MZQ4w@vR*<}?Vc?E&1e~Jl-xVZ!p*_SqQfU!c4gptMHPp(E> zXRSMpY97URLqLd|-c3U1JW?b%rR!f%|PjrMuGX$|tp$sHoC1Vk@$53n49R z@8oGtQ~cNclrC`cAT=H3s%7m0rDr3*J2A6si?x)du_!>d1Va`ZQ^aTu6o$Rkwmo#p zD@iquZgenbS~)Zyv);p=XI`npv5@OMe@Xg?9h}9XTX!p>boDJDn?hjSF5 z;t`U z`&d2}2TT_ZnXe6dx>a!Xd>}&mfe~#j-*yle`p;|QTc*H>^b z**O~}wE20g$rHDhQ1Ab8~Qf% zZRp$3zca&yX zMi;aBCfxx85(@>h*(m-40tN)L*(~=14-*Ih0QdU<0PFPo03s9%v)?fC0}l)d1pxj4 z{s02`{Q&#^|FhsU@&gM1|Nj8-_xu132L!X-IQ9bz3I+lI1_S~C7!C%r-aPgL3j_lL z00;*L00#yGv)@4W0}liN{{Zjv`2Zpl2LR{r`LpCi1_A_-zg2~U?na01MgfQJMgq6) cMgyP16iXxG&0`tHS^xk507*qoM6N<$g8W~tM*si- delta 1906 zcmV-&2aWiflMtbk5RfDRl#wMOe>n<;_kM~#f{;L<<7hOi8`SapQ{?bZX}zefWrkaX zd&)Hc@9`j?{r6wz`4695b9&S~YO6Kz(WWhT9wPnt?Du<1>D*`KEAM0SIZK{jUVJ2l-IJ#<$R52e_f3$Qcv>{O)JebxTZA8QqmEXC0&l}*L}*w zM9n)p_nc=gudyheTb?BqDf$#GDkpnsWtAwo%)CosG=JJ6uXEe$xGBNGOPHC3&4d-N z>-l*2f3Gh$I%nPx3EqFie+s*DzA(s*V!6M}0uVVLJhE4SKd#?D0Lv!ItQ+RQ!Jfw3 z7Q^HRx61PZx-ikW>)T>q?;8*z&NhsZ0s^T@F{zR~XBQ!k0X`keb9pomAP}>>urg~Y z6>uWovsvTvnwu@Z4U<9uVWk!anpQekshZYDT>}nvE2d^v%`L21f3Kx#wOXs!n~U9x ztD9GM4{zS1goZ^8kBAoiX}J}0)mm-dqP5mLhjw=EtnSen7#%mTX5pvHOACAGkf_{XfMm|BT#oq5C(GdoFZeAonM3U!b z={EzUYtLi#I(GB3)yr9P>uGBrX1Ld~XW>Op_wVk$CldLre?3m|wd$~#>+BtMk}1q- z8`H?5m}hzSb8Ncqqo6k$NeB@=l{npU+U*(RO4V+Yps&oPt85Z2i$=HVO&SauB1Fb} zb=gDlHODTaUm+)TIZgEO-3v$W7Ds07ONQDNzNo9ONNQNOH3iRRX|E+0FyhqB`-W5m zuIJny)yw9rf4BqWXtd%?ekmIE=apjjD{=m+8E8rmcf%qbku|Q^Et__5?NodMj6JrW zRj2edPqVR?l#!YR<%Ko7v<-h`p3!E)xl6`WX~BYCu3BYqxUdgpD|nH(@BNl zVAd{{J(p%_V6aW<+HDUgF6&@RAej!K+ z(`PFl%iINz+PwDYB2|x&!!h8XS)5tyX4xnP-KnRT>cD>=UmKbcqc)GxyujEs2Rx4o zjUg;`e{>r3E|f#|83$&N)mTI;P_)CiKF63l>*d=c(QJ#l&?8}Fqs+o>cR^+Lki2H{ zu%0O`)rpltW5`-&99!$m-5@$Y59$=u=DaLAM}gXM5XsV8)xo)$Bu)!EMuI=!2Y;xd z!zX#(>d_A1B|W1Lyw}?k=ycE|7|kxL0Ld!|e^AK|EkM1px%NzF+>jo0b&2#;t6cvc zot?ZnV+83>HrIMqMq0Yf*>yYYEu<@QCkOx>)QU5nx(4rd@`2$rg-^4EHlTnFHH2Cy zSFVdj2*K?Y^{8VYX=pX9A&p2q?QXbgLr}YbSCC(ywoPLqNGP@gUO9A9m`!BoNdu)H ze{~%M01+OY9AqZ8!&;Oi^#;$V5z3rZ79?8V9e-P|Fz3dS?=*A&jcOtJLgG7JkLL4@KPEuWH z&(VO2MTiPZsRZE@1-J*(fNm@|MXoCyB3!Mwj@%*~&(+seZdlMX6SR$-1W4p&%g9F9$ZBqO%Q(=(bn>92YI0ay$-&K3T&tB1H zq*rO@Y$Va<^;nZ0@^vi1D4;OtF4`emVT??Y7rV1G#R?LWS|&&l9&9T3+t~{LXjS47 zlz+$xkle@s`VZ7AU*8E1vQw`g?dZI`4=N~Ku>t{cP`g#+?f%Gb1ON2?z0vnZ-y3~z z^u5vdM&BF#8yoSTG1GBgc{sRNo=JB(+5FZu< zS-C4$l7|M1hd&N@&gY6 z0|EdK3IqV`_WJ-A{syz!H1Y!r6bb|Y3v^008~`v)DZL z0}BTQ1OV{*{QwmW2ea8g_5%+G0{{T;^Z5WD9t;5C?D(_ZL 100 ? 100 : substeps)); physics->step(chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f); camera->position.x = hitbox->position.x; - camera->position.y = hitbox->position.y + 0.5f; + camera->position.y = hitbox->position.y + 0.7f; camera->position.z = hitbox->position.z; if (player->flight && hitbox->grounded) @@ -245,6 +245,12 @@ void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, lighting->onBlockSet(x,y,z, player->choosenBlock); } } + if (Events::jclicked(GLFW_MOUSE_BUTTON_3)){ + int x = (int)iend.x; + int y = (int)iend.y; + int z = (int)iend.z; + player->choosenBlock = chunks->get(x,y,z)->id; + } } } diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index 60938091..9d6d5afc 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -135,7 +135,7 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz){ // id = 10; // } - if ( ((height - (1.5 - 0.2 * pow(height - 55, 4))) < real_y) && (real_y < height)){ + if ( ((height - (1.5 - 0.2 * pow(height - 54, 4))) < real_y) && (real_y < height)){ id = 10; } if (real_y <= 2) From c3b4357852258b8b357f8008fbcd4152d6a72dde Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Tue, 28 Jun 2022 21:21:36 +0300 Subject: [PATCH 21/56] update --- res/block_select.png | Bin 0 -> 264487 bytes src/declarations.h | 2 +- src/voxel_engine.cpp | 5 +++-- src/world_render.h | 28 +++++++++++++++++++++++++--- 4 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 res/block_select.png diff --git a/res/block_select.png b/res/block_select.png new file mode 100644 index 0000000000000000000000000000000000000000..420eb9c110106141de13c1a4a18800e6b9775177 GIT binary patch literal 264487 zcmeI533ycHxyRqxGRY*9WwIv_0s?~UxUkt;6t#3wt5j|6Vry|L?z>h&rB;i2Yj3aH zwO%aVN?W&D6}=XOAA5=rL)#qU*j~ z@%_!eSUvydHCt|Zw&Kd0YS-P{)wb!x<>Sh4IAPUYe}C)9CwCq5v%DSkFMF14`qo)P zpL*r#=~qk${P@>5e)Xaai%*Cgn?3IFrH{wYGC!JET>`GaNe-s`(}`VW8q;61lo@%48+&o4f2#Th@0 z+jh%uZN%|)cl_k53%*i6{GRFGKJS=e8{fZm?N=(so_K@Xeepe0p8H8=wXKS*T$!`v zi3w9~x#*6CHtXNV$6a`Q+_R@&5_syN=~It-_^3;sYCr$IbDn?yzkhn!^6P5PTD0Pg zjSpXQP?sdLodhOWDKQ9)Kg+IfXlufOYA@{5$CzVYbfYhK*)#5ezI z(kl1O_doq&*K_4#J{+0_N&EnH9ezESN>fC9`ORp`fy6A}^Gj1up z`?`$* zof8>$*7);}&iUhocaPoXyI{kKN%0qlmYvYJx%c>n#7lku6Z?Kq=V4ctA0Li=<>~KL zy*jgD%%#PPUwr1ZXa2MzaNaAE|9aw6?#MX*`kR}ImaI*h@rRKYJhL%d z&L3~=4o_U|TQqh?W!kn^)>fSM-nu)EUT|J=@5_yMo%6=2`J+;IUU1p+kuxql;ieN# zS+eAYt20}F^Wn`Yrz~Ffc;l<*-u}01U%$8e%SAVKJ$%k3kG^;0IbV8g_yx(gwf_8( zH;?&c`?n@#|9;I&f4J29A20uT)fF`#Oq=(@@6LT}{F2I=Z_mql>++0iR!sTz?c;mu zZkZA+TlCl&bDyo9TRC^^S(n}ZZ2acUsCuYpOP!*OrsJ zE}gw8p2<5BZwzqs1FW!`X0TUGPD%+5EyvV6$}Z&rABzV}Gs z8NWL%?v~V-j-GsK-XFK#8~5VMxg#c>`{W%*CM>-Ft*cMoe)d`0vfe*y`a93(r!MMv zGI)LcLpQe_U4Q0;zi+#AREKxr<9C1X=f$1P8NH)w#%-K(!f}Nybzcvkea+ERkNMil zeDAV*A6x0U;i8`;_+EJIqzjjS=bLl>dgEJpGj}}nt!-YaX>8u$Qi$|RC?_*{)oi=0D!n5AJ)c=hCUhjiDlhO~%4n1(;;^4Gjt_{pR z_lfVnU36<;@=MJNOUC@*ft8d0!{@4+zU=zd6*WzlPJHyou5Y@px-j_{i;@n1{kT8A z{b=D2$4)JrT{6$AKK#{_7yPvNH-BFIjh~;q;kFH(xBd2SsZWpn*1EK5%N}_CPfu^n zxcM6!rua8*3@5}V=LKJ%^}w1<%d;onHaGa>HKm3>s6C~z4DHQ!#{kvU}5Whc}eH*{9c>)*xZT760bFOz;;ez7%u9(GQ zxUk>D<=CEnPuqFlIn^qv>+mTtE6B^XuI_HDsc$s5%WXZqz2FKdrT-TDl(RzE`=5a+Wn3iBwWo?#_=&{70$08j)78h_^LrssRhT<$7HVe0P zS}4P3F_*{M+q&%K`!4Q(aQkq^6}*MU)t-Cv-OEpzan!H&cFR9Ix8hGX#TuJBE#Qx{ zj!2iKq{dr<&ucxH>#M7F*|7Ye6&9qL0Yj`OivO5J`HgsVmoKfCt&N!+iiSqf|WJ*T4#@0c9P4s)r2iCHNjf4%B`+CY`|yn2?5)( zt==Y%NwNBdcFP+aw71`Bw5*&sE657i%YUo3WN_`mXB>S@y7hE*TVd82*4f!mreeZLVuvx;JL~`rdPkrk&l|-s7-H zPxD(-OPBNgKA+nEA0HFqJ=WOVW!+$yi@7wnM64bAihq;$OYIKoj=Q{y~R z;3@1;jG2Pd)z#$)6W}88tfFg^tP>SCf8x_*_?b{v2M5V;BQBk$F zw!&zHEj}Jf8Sjl8Inp@KjT<*wa&j`(ER70ae}{fh+_&324`3?XFtqA!n6oZy?7W;T z3ncg*zrr8qGe0b2c1D_`dFdtan#Sf9XX7PcVItv9^J3Gc=f+!eQx6=KIP1lAPy^

;19(eczJ=!OTbx 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 literal 0 HcmV?d00001 diff --git a/src/declarations.h b/src/declarations.h index b32ddc8e..01407ffc 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -61,7 +61,7 @@ int initialize_assets(Assets* assets) { LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui"); LOAD_TEXTURE("res/block.png", "block"); - //LOAD_TEXTURE("res/font.png", "font"); + LOAD_TEXTURE("res/block_select.png", "block_select"); LOAD_FONT("res/font.png", "normal"); return 0; diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 3612717d..28e79b7f 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -304,7 +304,7 @@ int main() { bool occlusion = false; bool devdata = false; - glfwSwapInterval(1); + glfwSwapInterval(0); std::cout << "-- initializing finished" << std::endl; @@ -314,6 +314,7 @@ int main() { float currentTime = glfwGetTime(); delta = currentTime - lastTime; lastTime = currentTime; + int fps = 1 / delta; if (Events::jpressed(GLFW_KEY_O)){ occlusion = !occlusion; @@ -332,7 +333,7 @@ int main() { for (int i = 0; i < freeLoaders; i++) chunksController.loadVisible(wfile); - draw_world(camera, assets, chunks, occlusion, devdata); + draw_world(player, camera, assets, chunks, occlusion, devdata, fps); Window::swapBuffers(); Events::pullEvents(); diff --git a/src/world_render.h b/src/world_render.h index b56dfa0d..22d993df 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -5,6 +5,10 @@ #include #include +#ifndef std::string +#include +#endif + #include #include #include @@ -41,6 +45,7 @@ int uiscale = 2; LineBatch *lineBatch; Batch2D *batch; +Batch2D *activeBlockBatch; Camera *uicamera; void init_renderer(){ @@ -48,6 +53,7 @@ void init_renderer(){ lineBatch = new LineBatch(4096); batch = new Batch2D(1024); + activeBlockBatch = new Batch2D(1024); uicamera = new Camera(glm::vec3(), Window::height / uiscale); uicamera->perspective = false; } @@ -57,6 +63,7 @@ void finalize_renderer(){ delete crosshair; delete lineBatch; delete batch; + delete activeBlockBatch; } void draw_chunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ @@ -105,8 +112,8 @@ bool chunks_comparator(size_t i, size_t j) { } -void draw_world(Camera* camera, Assets* assets, Chunks* chunks, - bool occlusion, bool devdata){ +void draw_world(Player* player, Camera* camera, Assets* assets, Chunks* chunks, + bool occlusion, bool devdata, int fps){ glClearColor(0.7f,0.81f,1.0f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); @@ -115,6 +122,7 @@ void draw_world(Camera* camera, Assets* assets, Chunks* chunks, // Draw VAO Texture* texture = assets->getTexture("block"); + Texture* blocks = assets->getTexture("block_select"); Shader* shader = assets->getShader("main"); Shader* crosshairShader = assets->getShader("crosshair"); Shader* linesShader = assets->getShader("lines"); @@ -126,6 +134,7 @@ void draw_world(Camera* camera, Assets* assets, Chunks* chunks, shader->uniform3f("u_fogColor", 0.7f,0.71f,0.73f); shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); texture->bind(); + // blocks->bind(); std::vector indices; @@ -170,14 +179,27 @@ void draw_world(Camera* camera, Assets* assets, Chunks* chunks, uishader->uniformMatrix("u_projview", uicamera->getProjection()); Font* font = assets->getFont("normal"); + // Texture* blocks = assets->getTexture("blocks") batch->begin(); batch->texture(font->texture); // font->draw(batch, "void Font::draw(Batch2D* batch, std::string text, int x, int y) {", 10, 10); if (devdata){ - font->draw(batch, "devdata does not exist", 10, 10); + font->draw(batch, "devdata does not exist", 16, 16); + font->draw(batch, std::to_string((int)player->camera->position.x), 10, 30); + font->draw(batch, std::to_string((int)player->camera->position.y), 50, 30); + font->draw(batch, std::to_string((int)player->camera->position.z), 90, 30); + font->draw(batch, "fps:", 16, 42); + font->draw(batch, std::to_string(fps), 40, 42); } //batch->rect(0, 0, 256, 256); batch->render(); + + activeBlockBatch->begin(); + activeBlockBatch->texture(blocks); + float u = (player->choosenBlock % 16) / 16.0f; + float v = 1.0f - ((player->choosenBlock / 16) / 16.0f) - 1.0f/16.0f; + activeBlockBatch->rect(16, 280, 64, 64, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); + activeBlockBatch->render(); } #endif // WORLD_RENDERER_CPP From 88c16959037da4d12784797193a944591bd73fef Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 14:03:36 +0300 Subject: [PATCH 22/56] Flipped UI, minor changes Flipped UI, removed extra Batch2D, added comments and minor changes --- src/graphics/Batch2D.cpp | 12 +++---- src/graphics/Font.cpp | 36 +++++++++------------ src/graphics/Font.h | 1 + src/voxel_engine.cpp | 3 +- src/window/Camera.cpp | 10 ++++-- src/window/Camera.h | 1 + src/world_render.h | 70 +++++++++++++++++++--------------------- 7 files changed, 67 insertions(+), 66 deletions(-) diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index 9c114576..97c886de 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -74,13 +74,13 @@ void Batch2D::rect(float x, float y, float w, float h){ void Batch2D::rect(float x, float y, float w, float h, float u, float v, float tx, float ty, float r, float g, float b, float a){ - vertex(x, y, u, v, r,g,b,a); - vertex(x+w, y+h, u+tx, v+ty, r,g,b,a); - vertex(x, y+h, u, v+ty, r,g,b,a); + vertex(x, y, u, v+ty, r,g,b,a); + vertex(x+w, y+h, u+tx, v, r,g,b,a); + vertex(x, y+h, u, v, r,g,b,a); - vertex(x, y, u, v, r,g,b,a); - vertex(x+w, y, u+tx, v, r,g,b,a); - vertex(x+w, y+h, u+tx, v+ty, r,g,b,a); + vertex(x, y, u, v+ty, r,g,b,a); + vertex(x+w, y, u+tx, v+ty, r,g,b,a); + vertex(x+w, y+h, u+tx, v, r,g,b,a); } void Batch2D::render() { diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index 0947357b..8a9e764a 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -9,15 +9,8 @@ Font::~Font(){ delete texture; } - -void Font::draw(Batch2D* batch, std::string text, int x, int y) { - for (char c : text){ - float u = (c % 16) / 16.0f; - float v = 1.0f - ((c / 16) / 16.0f) - 1.0f/16.0f; - batch->rect(x, y, 8, 8, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); - - int gw = 7; - switch (c){ +int Font::getGlyphWidth(char c) { + switch (c){ case 'l': case 'i': case 'j': @@ -25,16 +18,19 @@ void Font::draw(Batch2D* batch, std::string text, int x, int y) { case '.': case ',': case ':': - case ';': - gw = 3; - break; - case 't': - gw = 5; - break; - case ' ': - gw = 3; - break; - } - x += gw; + case ';': return 3; + case 't': return 5; + case ' ': return 3; + } + return 7; +} + + +void Font::draw(Batch2D* batch, std::string text, int x, int y) { + for (char c : text){ + float u = (c % 16) / 16.0f; + float v = 1.0f - ((c / 16) / 16.0f) - 1.0f/16.0f; + batch->rect(x, y, 8, 8, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); + x += getGlyphWidth(c); } } diff --git a/src/graphics/Font.h b/src/graphics/Font.h index c771b3e4..77a769a1 100644 --- a/src/graphics/Font.h +++ b/src/graphics/Font.h @@ -12,6 +12,7 @@ public: Font(Texture* texture); ~Font(); + int getGlyphWidth(char c); void draw(Batch2D* batch, std::string text, int x, int y); }; diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 28e79b7f..8dff8152 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -333,7 +333,8 @@ int main() { for (int i = 0; i < freeLoaders; i++) chunksController.loadVisible(wfile); - draw_world(player, camera, assets, chunks, occlusion, devdata, fps); + draw_world(player, camera, assets, chunks, occlusion); + draw_hud(player, assets, devdata, fps); Window::swapBuffers(); Events::pullEvents(); diff --git a/src/window/Camera.cpp b/src/window/Camera.cpp index 4875bd95..1fe9b77c 100644 --- a/src/window/Camera.cpp +++ b/src/window/Camera.cpp @@ -40,9 +40,15 @@ mat4 Camera::getProjection(){ if (perspective) return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f); else - return glm::ortho(0.0f, fov*aspect, 0.0f, fov); + if (flipped) + return glm::ortho(0.0f, fov*aspect, fov, 0.0f); + else + return glm::ortho(0.0f, fov*aspect, 0.0f, fov); } mat4 Camera::getView(){ - return glm::lookAt(position, position+front, up); + if (perspective) + return glm::lookAt(position, position+front, up); + else + return glm::mat4(1.0f); } diff --git a/src/window/Camera.h b/src/window/Camera.h index 4d8a4462..28aabe94 100644 --- a/src/window/Camera.h +++ b/src/window/Camera.h @@ -24,6 +24,7 @@ public: float zoom; mat4 rotation; bool perspective = true; + bool flipped = false; Camera(vec3 position, float fov); void rotate(float x, float y, float z); diff --git a/src/world_render.h b/src/world_render.h index 22d993df..0a029175 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -45,7 +45,6 @@ int uiscale = 2; LineBatch *lineBatch; Batch2D *batch; -Batch2D *activeBlockBatch; Camera *uicamera; void init_renderer(){ @@ -53,9 +52,9 @@ void init_renderer(){ lineBatch = new LineBatch(4096); batch = new Batch2D(1024); - activeBlockBatch = new Batch2D(1024); uicamera = new Camera(glm::vec3(), Window::height / uiscale); uicamera->perspective = false; + uicamera->flipped = true; } @@ -63,7 +62,6 @@ void finalize_renderer(){ delete crosshair; delete lineBatch; delete batch; - delete activeBlockBatch; } void draw_chunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ @@ -112,17 +110,45 @@ bool chunks_comparator(size_t i, size_t j) { } -void draw_world(Player* player, Camera* camera, Assets* assets, Chunks* chunks, - bool occlusion, bool devdata, int fps){ +void draw_hud(Player* player, Assets* assets, bool devdata, int fps){ + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + Shader* uishader = assets->getShader("ui"); + uishader->use(); + uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); + + // draw debug info + Font* font = assets->getFont("normal"); + batch->begin(); + batch->texture(font->texture); + if (devdata){ + font->draw(batch, "devdata does not exist", 16, 16); + font->draw(batch, std::to_string((int)player->camera->position.x), 10, 30); + font->draw(batch, std::to_string((int)player->camera->position.y), 50, 30); + font->draw(batch, std::to_string((int)player->camera->position.z), 90, 30); + font->draw(batch, "fps:", 16, 42); + font->draw(batch, std::to_string(fps), 40, 42); + } + batch->render(); + + // choosen block preview + Texture* blocks = assets->getTexture("block_select"); + batch->texture(blocks); + float u = (player->choosenBlock % 16) / 16.0f; + float v = 1.0f - ((player->choosenBlock / 16) / 16.0f) - 1.0f/16.0f; + batch->rect(16, 280, 64, 64, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); + batch->render(); +} + +void draw_world(Player* player, Camera* camera, Assets* assets, Chunks* chunks, bool occlusion){ glClearColor(0.7f,0.81f,1.0f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); _chunks = chunks; - // Draw VAO Texture* texture = assets->getTexture("block"); - Texture* blocks = assets->getTexture("block_select"); Shader* shader = assets->getShader("main"); Shader* crosshairShader = assets->getShader("crosshair"); Shader* linesShader = assets->getShader("lines"); @@ -134,7 +160,6 @@ void draw_world(Player* player, Camera* camera, Assets* assets, Chunks* chunks, shader->uniform3f("u_fogColor", 0.7f,0.71f,0.73f); shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); texture->bind(); - // blocks->bind(); std::vector indices; @@ -171,35 +196,6 @@ void draw_world(Player* player, Camera* camera, Assets* assets, Chunks* chunks, lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f, camera->position.z+0.01f, 0, 0, 1, 1); lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f+0.01f, camera->position.z, 0, 1, 0, 1); lineBatch->render(); - - - glDisable(GL_DEPTH_TEST); - Shader* uishader = assets->getShader("ui"); - uishader->use(); - uishader->uniformMatrix("u_projview", uicamera->getProjection()); - - Font* font = assets->getFont("normal"); - // Texture* blocks = assets->getTexture("blocks") - batch->begin(); - batch->texture(font->texture); - // font->draw(batch, "void Font::draw(Batch2D* batch, std::string text, int x, int y) {", 10, 10); - if (devdata){ - font->draw(batch, "devdata does not exist", 16, 16); - font->draw(batch, std::to_string((int)player->camera->position.x), 10, 30); - font->draw(batch, std::to_string((int)player->camera->position.y), 50, 30); - font->draw(batch, std::to_string((int)player->camera->position.z), 90, 30); - font->draw(batch, "fps:", 16, 42); - font->draw(batch, std::to_string(fps), 40, 42); - } - //batch->rect(0, 0, 256, 256); - batch->render(); - - activeBlockBatch->begin(); - activeBlockBatch->texture(blocks); - float u = (player->choosenBlock % 16) / 16.0f; - float v = 1.0f - ((player->choosenBlock / 16) / 16.0f) - 1.0f/16.0f; - activeBlockBatch->rect(16, 280, 64, 64, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); - activeBlockBatch->render(); } #endif // WORLD_RENDERER_CPP From 81d246f3d075564972a10e88f0838a175af4e4cf Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 14:55:02 +0300 Subject: [PATCH 23/56] Added text shadow, block indicator outline --- src/graphics/Batch2D.cpp | 7 +++++++ src/graphics/Batch2D.h | 3 +++ src/graphics/Font.cpp | 29 ++++++++++++++++++++++++++--- src/graphics/Font.h | 2 ++ src/world_render.h | 17 ++++++++--------- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index 97c886de..fe2dc250 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -71,6 +71,13 @@ void Batch2D::rect(float x, float y, float w, float h){ vertex(x+w, y+h, 1, 1, r,g,b,a); } +void Batch2D::sprite(float x, float y, 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; + rect(x, y, w, h, u, v, scale, scale, tint.r, tint.g, tint.b, tint.a); +} + void Batch2D::rect(float x, float y, float w, float h, float u, float v, float tx, float ty, float r, float g, float b, float a){ diff --git a/src/graphics/Batch2D.h b/src/graphics/Batch2D.h index 1ea7657a..21fe3b6d 100644 --- a/src/graphics/Batch2D.h +++ b/src/graphics/Batch2D.h @@ -4,6 +4,8 @@ #include #include +using namespace glm; + class Mesh; class Texture; @@ -27,6 +29,7 @@ public: void begin(); void texture(Texture* texture); + void sprite(float x, float y, float w, float h, int atlasRes, int index, vec4 tint); void rect(float x, float y, float w, float h); void rect(float x, float y, float w, float h, float u, float v, float tx, float ty, diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index 8a9e764a..a2b98e80 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -26,11 +26,34 @@ int Font::getGlyphWidth(char c) { } +bool Font::isPrintableChar(char c) { + switch (c){ + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + return false; + default: + return true; + } +} + + void Font::draw(Batch2D* batch, std::string text, int x, int y) { for (char c : text){ - float u = (c % 16) / 16.0f; - float v = 1.0f - ((c / 16) / 16.0f) - 1.0f/16.0f; - batch->rect(x, y, 8, 8, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); + if (isPrintableChar(c)) + batch->sprite(x, y, 8, 8, 16, c, vec4(1.0f)); + x += getGlyphWidth(c); + } +} + +void Font::drawWithShadow(Batch2D* batch, std::string text, int x, int y) { + for (char c : text){ + if (isPrintableChar(c)){ + batch->sprite(x+1, y+1, 8, 8, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x, y, 8, 8, 16, c, vec4(1.0f)); + } x += getGlyphWidth(c); } } diff --git a/src/graphics/Font.h b/src/graphics/Font.h index 77a769a1..f65ba3d7 100644 --- a/src/graphics/Font.h +++ b/src/graphics/Font.h @@ -13,7 +13,9 @@ public: ~Font(); int getGlyphWidth(char c); + bool isPrintableChar(char c); void draw(Batch2D* batch, std::string text, int x, int y); + void drawWithShadow(Batch2D* batch, std::string text, int x, int y); }; #endif /* GRAPHICS_FONT_H_ */ diff --git a/src/world_render.h b/src/world_render.h index 0a029175..887eae32 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -122,21 +122,20 @@ void draw_hud(Player* player, Assets* assets, bool devdata, int fps){ batch->begin(); batch->texture(font->texture); if (devdata){ - font->draw(batch, "devdata does not exist", 16, 16); - font->draw(batch, std::to_string((int)player->camera->position.x), 10, 30); - font->draw(batch, std::to_string((int)player->camera->position.y), 50, 30); - font->draw(batch, std::to_string((int)player->camera->position.z), 90, 30); - font->draw(batch, "fps:", 16, 42); - font->draw(batch, std::to_string(fps), 40, 42); + font->drawWithShadow(batch, "devdata does not exist", 16, 16); + font->drawWithShadow(batch, std::to_string((int)player->camera->position.x), 10, 30); + font->drawWithShadow(batch, std::to_string((int)player->camera->position.y), 50, 30); + font->drawWithShadow(batch, std::to_string((int)player->camera->position.z), 90, 30); + font->drawWithShadow(batch, "fps:", 16, 42); + font->drawWithShadow(batch, std::to_string(fps), 40, 42); } batch->render(); // choosen block preview Texture* blocks = assets->getTexture("block_select"); batch->texture(blocks); - float u = (player->choosenBlock % 16) / 16.0f; - float v = 1.0f - ((player->choosenBlock / 16) / 16.0f) - 1.0f/16.0f; - batch->rect(16, 280, 64, 64, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); + batch->sprite(14, 278, 68, 68, 16, player->choosenBlock, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(16, 280, 64, 64, 16, player->choosenBlock, vec4(1.0f)); batch->render(); } From bb7c63394b7f5207a24df63bb2d394d67f66b8d5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 15:05:21 +0300 Subject: [PATCH 24/56] Fixed block preview texture selection --- src/declarations.h | 1 - src/world_render.h | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/declarations.h b/src/declarations.h index 01407ffc..43bacaeb 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -61,7 +61,6 @@ int initialize_assets(Assets* assets) { LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui"); LOAD_TEXTURE("res/block.png", "block"); - LOAD_TEXTURE("res/block_select.png", "block_select"); LOAD_FONT("res/font.png", "normal"); return 0; diff --git a/src/world_render.h b/src/world_render.h index 887eae32..f94617f0 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -132,10 +132,12 @@ void draw_hud(Player* player, Assets* assets, bool devdata, int fps){ batch->render(); // choosen block preview - Texture* blocks = assets->getTexture("block_select"); + Texture* blocks = assets->getTexture("block"); batch->texture(blocks); - batch->sprite(14, 278, 68, 68, 16, player->choosenBlock, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(16, 280, 64, 64, 16, player->choosenBlock, vec4(1.0f)); + + int texid = Block::blocks[player->choosenBlock]->textureFaces[3]; // face-3 is top face of block + batch->sprite(14, 278, 68, 68, 16, texid, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(16, 280, 64, 64, 16, texid, vec4(1.0f)); batch->render(); } From 265ebc092737ab111e1e4ca77b48ae3b28515684 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 15:05:51 +0300 Subject: [PATCH 25/56] Delete block_select.png --- res/block_select.png | Bin 264487 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 res/block_select.png diff --git a/res/block_select.png b/res/block_select.png deleted file mode 100644 index 420eb9c110106141de13c1a4a18800e6b9775177..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264487 zcmeI533ycHxyRqxGRY*9WwIv_0s?~UxUkt;6t#3wt5j|6Vry|L?z>h&rB;i2Yj3aH zwO%aVN?W&D6}=XOAA5=rL)#qU*j~ z@%_!eSUvydHCt|Zw&Kd0YS-P{)wb!x<>Sh4IAPUYe}C)9CwCq5v%DSkFMF14`qo)P zpL*r#=~qk${P@>5e)Xaai%*Cgn?3IFrH{wYGC!JET>`GaNe-s`(}`VW8q;61lo@%48+&o4f2#Th@0 z+jh%uZN%|)cl_k53%*i6{GRFGKJS=e8{fZm?N=(so_K@Xeepe0p8H8=wXKS*T$!`v zi3w9~x#*6CHtXNV$6a`Q+_R@&5_syN=~It-_^3;sYCr$IbDn?yzkhn!^6P5PTD0Pg zjSpXQP?sdLodhOWDKQ9)Kg+IfXlufOYA@{5$CzVYbfYhK*)#5ezI z(kl1O_doq&*K_4#J{+0_N&EnH9ezESN>fC9`ORp`fy6A}^Gj1up z`?`$* zof8>$*7);}&iUhocaPoXyI{kKN%0qlmYvYJx%c>n#7lku6Z?Kq=V4ctA0Li=<>~KL zy*jgD%%#PPUwr1ZXa2MzaNaAE|9aw6?#MX*`kR}ImaI*h@rRKYJhL%d z&L3~=4o_U|TQqh?W!kn^)>fSM-nu)EUT|J=@5_yMo%6=2`J+;IUU1p+kuxql;ieN# zS+eAYt20}F^Wn`Yrz~Ffc;l<*-u}01U%$8e%SAVKJ$%k3kG^;0IbV8g_yx(gwf_8( zH;?&c`?n@#|9;I&f4J29A20uT)fF`#Oq=(@@6LT}{F2I=Z_mql>++0iR!sTz?c;mu zZkZA+TlCl&bDyo9TRC^^S(n}ZZ2acUsCuYpOP!*OrsJ zE}gw8p2<5BZwzqs1FW!`X0TUGPD%+5EyvV6$}Z&rABzV}Gs z8NWL%?v~V-j-GsK-XFK#8~5VMxg#c>`{W%*CM>-Ft*cMoe)d`0vfe*y`a93(r!MMv zGI)LcLpQe_U4Q0;zi+#AREKxr<9C1X=f$1P8NH)w#%-K(!f}Nybzcvkea+ERkNMil zeDAV*A6x0U;i8`;_+EJIqzjjS=bLl>dgEJpGj}}nt!-YaX>8u$Qi$|RC?_*{)oi=0D!n5AJ)c=hCUhjiDlhO~%4n1(;;^4Gjt_{pR z_lfVnU36<;@=MJNOUC@*ft8d0!{@4+zU=zd6*WzlPJHyou5Y@px-j_{i;@n1{kT8A z{b=D2$4)JrT{6$AKK#{_7yPvNH-BFIjh~;q;kFH(xBd2SsZWpn*1EK5%N}_CPfu^n zxcM6!rua8*3@5}V=LKJ%^}w1<%d;onHaGa>HKm3>s6C~z4DHQ!#{kvU}5Whc}eH*{9c>)*xZT760bFOz;;ez7%u9(GQ zxUk>D<=CEnPuqFlIn^qv>+mTtE6B^XuI_HDsc$s5%WXZqz2FKdrT-TDl(RzE`=5a+Wn3iBwWo?#_=&{70$08j)78h_^LrssRhT<$7HVe0P zS}4P3F_*{M+q&%K`!4Q(aQkq^6}*MU)t-Cv-OEpzan!H&cFR9Ix8hGX#TuJBE#Qx{ zj!2iKq{dr<&ucxH>#M7F*|7Ye6&9qL0Yj`OivO5J`HgsVmoKfCt&N!+iiSqf|WJ*T4#@0c9P4s)r2iCHNjf4%B`+CY`|yn2?5)( zt==Y%NwNBdcFP+aw71`Bw5*&sE657i%YUo3WN_`mXB>S@y7hE*TVd82*4f!mreeZLVuvx;JL~`rdPkrk&l|-s7-H zPxD(-OPBNgKA+nEA0HFqJ=WOVW!+$yi@7wnM64bAihq;$OYIKoj=Q{y~R z;3@1;jG2Pd)z#$)6W}88tfFg^tP>SCf8x_*_?b{v2M5V;BQBk$F zw!&zHEj}Jf8Sjl8Inp@KjT<*wa&j`(ER70ae}{fh+_&324`3?XFtqA!n6oZy?7W;T z3ncg*zrr8qGe0b2c1D_`dFdtan#Sf9XX7PcVItv9^J3Gc=f+!eQx6=KIP1lAPy^

;19(eczJ=!OTbx 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 From 191b88192b6d947c40b5660dd63bfc59c58c8fa1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 15:18:31 +0300 Subject: [PATCH 26/56] Added chunks counter to debug info screen --- src/voxel_engine.cpp | 2 +- src/voxels/Chunks.cpp | 4 ++++ src/voxels/Chunks.h | 1 + src/voxels/ChunksController.cpp | 2 +- src/world_render.h | 6 +++--- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 8dff8152..f4bf8af8 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -334,7 +334,7 @@ int main() { chunksController.loadVisible(wfile); draw_world(player, camera, assets, chunks, occlusion); - draw_hud(player, assets, devdata, fps); + draw_hud(player, assets, chunks, devdata, fps); Window::swapBuffers(); Events::pullEvents(); diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 0591f2f0..ce255800 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -23,6 +23,7 @@ Chunks::Chunks(int w, int h, int d, int ox, int oy, int oz) : w(w), h(h), d(d), chunks[i] = nullptr; meshes[i] = nullptr; } + chunksCount = 0; } Chunks::~Chunks(){ @@ -281,6 +282,7 @@ void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){ worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z); chunk->decref(); delete mesh; + chunksCount--; continue; } meshesSecond[(ny * d + nz) * w + nx] = mesh; @@ -317,6 +319,7 @@ bool Chunks::putChunk(Chunk* chunk) { if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d) return false; chunks[(y * d + z) * w + x] = chunk; + chunksCount++; return true; } @@ -329,4 +332,5 @@ void Chunks::clear(bool freeMemory){ chunks[i] = nullptr; meshes[i] = nullptr; } + chunksCount = 0; } diff --git a/src/voxels/Chunks.h b/src/voxels/Chunks.h index bdd5efbb..c9c70bea 100644 --- a/src/voxels/Chunks.h +++ b/src/voxels/Chunks.h @@ -20,6 +20,7 @@ public: Mesh** meshes; Mesh** meshesSecond; size_t volume; + size_t chunksCount; unsigned int w,h,d; int ox,oy,oz; diff --git a/src/voxels/ChunksController.cpp b/src/voxels/ChunksController.cpp index d64ed858..d2b98eb1 100644 --- a/src/voxels/ChunksController.cpp +++ b/src/voxels/ChunksController.cpp @@ -106,7 +106,7 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){ if (worldFiles->getChunk(chunk->x, chunk->z, (char*)chunk->voxels)) chunk->loaded = true; - chunks->chunks[index] = chunk; + chunks->putChunk(chunk); Chunk* closes[27]; for (int i = 0; i < 27; i++) diff --git a/src/world_render.h b/src/world_render.h index f94617f0..e9f64877 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -110,7 +110,7 @@ bool chunks_comparator(size_t i, size_t j) { } -void draw_hud(Player* player, Assets* assets, bool devdata, int fps){ +void draw_hud(Player* player, Assets* assets, Chunks* chunks, bool devdata, int fps){ glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); Shader* uishader = assets->getShader("ui"); @@ -122,11 +122,11 @@ void draw_hud(Player* player, Assets* assets, bool devdata, int fps){ batch->begin(); batch->texture(font->texture); if (devdata){ - font->drawWithShadow(batch, "devdata does not exist", 16, 16); + font->drawWithShadow(batch, "chunks: "+std::to_string(chunks->chunksCount), 16, 16); font->drawWithShadow(batch, std::to_string((int)player->camera->position.x), 10, 30); font->drawWithShadow(batch, std::to_string((int)player->camera->position.y), 50, 30); font->drawWithShadow(batch, std::to_string((int)player->camera->position.z), 90, 30); - font->drawWithShadow(batch, "fps:", 16, 42); + font->drawWithShadow(batch, "fps: ", 16, 42); font->drawWithShadow(batch, std::to_string(fps), 40, 42); } batch->render(); From f962b73c984f6d442e56e85a52a4871d7a8322bd Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 15:36:45 +0300 Subject: [PATCH 27/56] update_controls & update_interaction moved to separate module --- src/player_control.cpp | 197 +++++++++++++++++++++++++++++++++++++++++ src/player_control.h | 13 +++ src/voxel_engine.cpp | 190 +-------------------------------------- src/world_render.h | 2 +- 4 files changed, 214 insertions(+), 188 deletions(-) create mode 100644 src/player_control.cpp create mode 100644 src/player_control.h diff --git a/src/player_control.cpp b/src/player_control.cpp new file mode 100644 index 00000000..33e71aa0 --- /dev/null +++ b/src/player_control.cpp @@ -0,0 +1,197 @@ +#include "player_control.h" + +#include "graphics/LineBatch.h" +#include "objects/Player.h" +#include "physics/PhysicsSolver.h" +#include "physics/Hitbox.h" +#include "lighting/Lighting.h" +#include "voxels/voxel.h" +#include "voxels/Chunks.h" +#include "window/Camera.h" +#include "window/Events.h" +#include + +#define CROUCH_SPEED_MUL 0.25f +#define CROUCH_SHIFT_Y -0.2f +#define RUN_SPEED_MUL 1.5f +#define CROUCH_ZOOM 0.9f +#define RUN_ZOOM 1.1f +#define C_ZOOM 0.1f +#define ZOOM_SPEED 16.0f +#define DEFAULT_AIR_DAMPING 0.1f +#define PLAYER_NOT_ONGROUND_DAMPING 10.0f +#define CAMERA_SHAKING_OFFSET 0.025f +#define CAMERA_SHAKING_OFFSET_Y 0.031f +#define CAMERA_SHAKING_SPEED 1.6f +#define CAMERA_SHAKING_DELTA_K 10.0f +#define FLIGHT_SPEED_MUL 5.0f +#define JUMP_FORCE 7.0f + +void update_controls(PhysicsSolver* physics, + Chunks* chunks, + Player* player, + float delta){ + + if (Events::jpressed(GLFW_KEY_ESCAPE)){ + Window::setShouldClose(true); + } + if (Events::jpressed(GLFW_KEY_TAB)){ + Events::toogleCursor(); + } + + for (int i = 1; i < 10; i++){ + if (Events::jpressed(GLFW_KEY_0+i)){ + player->choosenBlock = i; + } + } + + // Controls + Camera* camera = player->camera; + Hitbox* hitbox = player->hitbox; + bool sprint = Events::pressed(GLFW_KEY_LEFT_CONTROL); + bool shift = Events::pressed(GLFW_KEY_LEFT_SHIFT) && hitbox->grounded && !sprint; + bool zoom = Events::pressed(GLFW_KEY_C); + + float speed = player->speed; + if (player->flight){ + speed *= FLIGHT_SPEED_MUL; + } + int substeps = (int)(delta * 1000); + substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps)); + physics->step(chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f); + camera->position.x = hitbox->position.x; + camera->position.y = hitbox->position.y + 0.7f; + camera->position.z = hitbox->position.z; + + if (player->flight && hitbox->grounded) + player->flight = false; + // Camera shaking + player->interpVel = player->interpVel * (1.0f - delta * 5) + hitbox->velocity * delta * 0.1f; + if (hitbox->grounded && player->interpVel.y < 0.0f){ + player->interpVel.y *= -30.0f; + } + float factor = hitbox->grounded ? length(vec2(hitbox->velocity.x, hitbox->velocity.z)) : 0.0f; + player->cameraShakingTimer += delta * factor * CAMERA_SHAKING_SPEED; + float shakeTimer = player->cameraShakingTimer; + player->cameraShaking = player->cameraShaking * (1.0f - delta * CAMERA_SHAKING_DELTA_K) + factor * delta * CAMERA_SHAKING_DELTA_K; + camera->position += camera->right * sin(shakeTimer) * CAMERA_SHAKING_OFFSET * player->cameraShaking; + camera->position += camera->up * abs(cos(shakeTimer)) * CAMERA_SHAKING_OFFSET_Y * player->cameraShaking; + camera->position -= min(player->interpVel * 0.05f, 1.0f); + + if (Events::jpressed(GLFW_KEY_F)){ + player->flight = !player->flight; + if (player->flight){ + hitbox->velocity.y += 1; + hitbox->grounded = false; + } + } + + // Field of view manipulations + float dt = min(1.0f, delta * ZOOM_SPEED); + if (dt > 1.0f) + dt = 1.0f; + float zoomValue = 1.0f; + if (shift){ + speed *= CROUCH_SPEED_MUL; + camera->position.y += CROUCH_SHIFT_Y; + zoomValue = CROUCH_ZOOM; + } else if (sprint){ + speed *= RUN_SPEED_MUL; + zoomValue = RUN_ZOOM; + } + if (zoom) + zoomValue *= C_ZOOM; + camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt); + + if (Events::pressed(GLFW_KEY_SPACE) && hitbox->grounded){ + hitbox->velocity.y = JUMP_FORCE; + } + + vec3 dir(0,0,0); + if (Events::pressed(GLFW_KEY_W)){ + dir.x += camera->dir.x; + dir.z += camera->dir.z; + } + if (Events::pressed(GLFW_KEY_S)){ + dir.x -= camera->dir.x; + dir.z -= camera->dir.z; + } + if (Events::pressed(GLFW_KEY_D)){ + dir.x += camera->right.x; + dir.z += camera->right.z; + } + if (Events::pressed(GLFW_KEY_A)){ + dir.x -= camera->right.x; + dir.z -= camera->right.z; + } + + hitbox->linear_damping = DEFAULT_AIR_DAMPING; + if (player->flight){ + hitbox->linear_damping = PLAYER_NOT_ONGROUND_DAMPING; + hitbox->velocity.y *= 1.0f - delta * 9; + if (Events::pressed(GLFW_KEY_SPACE)){ + hitbox->velocity.y += speed * delta * 9; + } + if (Events::pressed(GLFW_KEY_LEFT_SHIFT)){ + hitbox->velocity.y -= speed * delta * 9; + } + } + if (length(dir) > 0.0f){ + dir = normalize(dir); + + if (!hitbox->grounded) + hitbox->linear_damping = PLAYER_NOT_ONGROUND_DAMPING; + + hitbox->velocity.x += dir.x * speed * delta * 9; + hitbox->velocity.z += dir.z * speed * delta * 9; + } + + if (Events::_cursor_locked){ + player->camY += -Events::deltaY / Window::height * 2; + player->camX += -Events::deltaX / Window::height * 2; + + if (player->camY < -radians(89.0f)){ + player->camY = -radians(89.0f); + } + if (player->camY > radians(89.0f)){ + player->camY = radians(89.0f); + } + + camera->rotation = mat4(1.0f); + camera->rotate(player->camY, player->camX, 0); + } +} + +void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, Lighting* lighting, LineBatch* lineBatch){ + Camera* camera = player->camera; + vec3 end; + vec3 norm; + vec3 iend; + voxel* vox = chunks->rayCast(camera->position, camera->front, 10.0f, end, norm, iend); + if (vox != nullptr){ + lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); + + if (Events::jclicked(GLFW_MOUSE_BUTTON_1)){ + int x = (int)iend.x; + int y = (int)iend.y; + int z = (int)iend.z; + chunks->set(x,y,z, 0); + lighting->onBlockSet(x,y,z,0); + } + if (Events::jclicked(GLFW_MOUSE_BUTTON_2)){ + int x = (int)(iend.x)+(int)(norm.x); + int y = (int)(iend.y)+(int)(norm.y); + int z = (int)(iend.z)+(int)(norm.z); + if (!physics->isBlockInside(x,y,z, player->hitbox)){ + chunks->set(x, y, z, player->choosenBlock); + lighting->onBlockSet(x,y,z, player->choosenBlock); + } + } + if (Events::jclicked(GLFW_MOUSE_BUTTON_3)){ + int x = (int)iend.x; + int y = (int)iend.y; + int z = (int)iend.z; + player->choosenBlock = chunks->get(x,y,z)->id; + } + } +} diff --git a/src/player_control.h b/src/player_control.h new file mode 100644 index 00000000..e3a91407 --- /dev/null +++ b/src/player_control.h @@ -0,0 +1,13 @@ +#ifndef PLAYER_CONTROL_H_ +#define PLAYER_CONTROL_H_ + +class PhysicsSolver; +class Chunks; +class Player; +class Lighting; +class LineBatch; + +void update_controls(PhysicsSolver* physics, Chunks* chunks, Player* player, float delta); +void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, Lighting* lighting, LineBatch* lineBatch); + +#endif /* PLAYER_CONTROL_H_ */ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index f4bf8af8..e4ba8473 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -69,194 +69,11 @@ void close_world(WorldFiles* wfile, Chunks* chunks){ delete wfile; } -#define CROUCH_SPEED_MUL 0.25f -#define CROUCH_SHIFT_Y -0.2f -#define RUN_SPEED_MUL 1.5f -#define CROUCH_ZOOM 0.9f -#define RUN_ZOOM 1.1f -#define C_ZOOM 0.1f -#define ZOOM_SPEED 16.0f -#define DEFAULT_AIR_DAMPING 0.1f -#define PLAYER_NOT_ONGROUND_DAMPING 10.0f -#define CAMERA_SHAKING_OFFSET 0.025f -#define CAMERA_SHAKING_OFFSET_Y 0.031f -#define CAMERA_SHAKING_SPEED 1.6f -#define CAMERA_SHAKING_DELTA_K 10.0f -#define FLIGHT_SPEED_MUL 5.0f -#define JUMP_FORCE 7.0f - -void update_controls(PhysicsSolver* physics, - Chunks* chunks, - Player* player, - float delta){ - - if (Events::jpressed(GLFW_KEY_ESCAPE)){ - Window::setShouldClose(true); - } - if (Events::jpressed(GLFW_KEY_TAB)){ - Events::toogleCursor(); - } - - for (int i = 1; i < 10; i++){ - if (Events::jpressed(GLFW_KEY_0+i)){ - player->choosenBlock = i; - } - } - - // Controls - Camera* camera = player->camera; - Hitbox* hitbox = player->hitbox; - bool sprint = Events::pressed(GLFW_KEY_LEFT_CONTROL); - bool shift = Events::pressed(GLFW_KEY_LEFT_SHIFT) && hitbox->grounded && !sprint; - bool zoom = Events::pressed(GLFW_KEY_C); - - float speed = player->speed; - if (player->flight){ - speed *= FLIGHT_SPEED_MUL; - } - int substeps = (int)(delta * 1000); - substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps)); - physics->step(chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f); - camera->position.x = hitbox->position.x; - camera->position.y = hitbox->position.y + 0.7f; - camera->position.z = hitbox->position.z; - - if (player->flight && hitbox->grounded) - player->flight = false; - // Camera shaking - player->interpVel = player->interpVel * (1.0f - delta * 5) + hitbox->velocity * delta * 0.1f; - if (hitbox->grounded && player->interpVel.y < 0.0f){ - player->interpVel.y *= -30.0f; - } - float factor = hitbox->grounded ? length(vec2(hitbox->velocity.x, hitbox->velocity.z)) : 0.0f; - player->cameraShakingTimer += delta * factor * CAMERA_SHAKING_SPEED; - float shakeTimer = player->cameraShakingTimer; - player->cameraShaking = player->cameraShaking * (1.0f - delta * CAMERA_SHAKING_DELTA_K) + factor * delta * CAMERA_SHAKING_DELTA_K; - camera->position += camera->right * sin(shakeTimer) * CAMERA_SHAKING_OFFSET * player->cameraShaking; - camera->position += camera->up * abs(cos(shakeTimer)) * CAMERA_SHAKING_OFFSET_Y * player->cameraShaking; - camera->position -= min(player->interpVel * 0.05f, 1.0f); - - if (Events::jpressed(GLFW_KEY_F)){ - player->flight = !player->flight; - if (player->flight){ - hitbox->velocity.y += 1; - hitbox->grounded = false; - } - } - - // Field of view manipulations - float dt = min(1.0f, delta * ZOOM_SPEED); - if (dt > 1.0f) - dt = 1.0f; - float zoomValue = 1.0f; - if (shift){ - speed *= CROUCH_SPEED_MUL; - camera->position.y += CROUCH_SHIFT_Y; - zoomValue = CROUCH_ZOOM; - } else if (sprint){ - speed *= RUN_SPEED_MUL; - zoomValue = RUN_ZOOM; - } - if (zoom) - zoomValue *= C_ZOOM; - camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt); - - if (Events::pressed(GLFW_KEY_SPACE) && hitbox->grounded){ - hitbox->velocity.y = JUMP_FORCE; - } - - vec3 dir(0,0,0); - if (Events::pressed(GLFW_KEY_W)){ - dir.x += camera->dir.x; - dir.z += camera->dir.z; - } - if (Events::pressed(GLFW_KEY_S)){ - dir.x -= camera->dir.x; - dir.z -= camera->dir.z; - } - if (Events::pressed(GLFW_KEY_D)){ - dir.x += camera->right.x; - dir.z += camera->right.z; - } - if (Events::pressed(GLFW_KEY_A)){ - dir.x -= camera->right.x; - dir.z -= camera->right.z; - } - - hitbox->linear_damping = DEFAULT_AIR_DAMPING; - if (player->flight){ - hitbox->linear_damping = PLAYER_NOT_ONGROUND_DAMPING; - hitbox->velocity.y *= 1.0f - delta * 9; - if (Events::pressed(GLFW_KEY_SPACE)){ - hitbox->velocity.y += speed * delta * 9; - } - if (Events::pressed(GLFW_KEY_LEFT_SHIFT)){ - hitbox->velocity.y -= speed * delta * 9; - } - } - if (length(dir) > 0.0f){ - dir = normalize(dir); - - if (!hitbox->grounded) - hitbox->linear_damping = PLAYER_NOT_ONGROUND_DAMPING; - - hitbox->velocity.x += dir.x * speed * delta * 9; - hitbox->velocity.z += dir.z * speed * delta * 9; - } - - if (Events::_cursor_locked){ - player->camY += -Events::deltaY / Window::height * 2; - player->camX += -Events::deltaX / Window::height * 2; - - if (player->camY < -radians(89.0f)){ - player->camY = -radians(89.0f); - } - if (player->camY > radians(89.0f)){ - player->camY = radians(89.0f); - } - - camera->rotation = mat4(1.0f); - camera->rotate(player->camY, player->camX, 0); - } -} - -void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, Lighting* lighting){ - Camera* camera = player->camera; - vec3 end; - vec3 norm; - vec3 iend; - voxel* vox = chunks->rayCast(camera->position, camera->front, 10.0f, end, norm, iend); - if (vox != nullptr){ - lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); - - if (Events::jclicked(GLFW_MOUSE_BUTTON_1)){ - int x = (int)iend.x; - int y = (int)iend.y; - int z = (int)iend.z; - chunks->set(x,y,z, 0); - lighting->onBlockSet(x,y,z,0); - } - if (Events::jclicked(GLFW_MOUSE_BUTTON_2)){ - int x = (int)(iend.x)+(int)(norm.x); - int y = (int)(iend.y)+(int)(norm.y); - int z = (int)(iend.z)+(int)(norm.z); - if (!physics->isBlockInside(x,y,z, player->hitbox)){ - chunks->set(x, y, z, player->choosenBlock); - lighting->onBlockSet(x,y,z, player->choosenBlock); - } - } - if (Events::jclicked(GLFW_MOUSE_BUTTON_3)){ - int x = (int)iend.x; - int y = (int)iend.y; - int z = (int)iend.z; - player->choosenBlock = chunks->get(x,y,z)->id; - } - } -} - int WIDTH = 1280; int HEIGHT = 720; +#include "player_control.h" + int main() { setup_definitions(); @@ -308,7 +125,6 @@ int main() { std::cout << "-- initializing finished" << std::endl; - while (!Window::isShouldClose()){ frame++; float currentTime = glfwGetTime(); @@ -324,7 +140,7 @@ int main() { } update_controls(&physics, chunks, player, delta); - update_interaction(chunks, &physics, player, &lighting); + update_interaction(chunks, &physics, player, &lighting, lineBatch); chunks->setCenter(wfile, camera->position.x,0,camera->position.z); chunksController._buildMeshes(&renderer, frame); diff --git a/src/world_render.h b/src/world_render.h index e9f64877..eea5acb7 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -126,7 +126,7 @@ void draw_hud(Player* player, Assets* assets, Chunks* chunks, bool devdata, int font->drawWithShadow(batch, std::to_string((int)player->camera->position.x), 10, 30); font->drawWithShadow(batch, std::to_string((int)player->camera->position.y), 50, 30); font->drawWithShadow(batch, std::to_string((int)player->camera->position.z), 90, 30); - font->drawWithShadow(batch, "fps: ", 16, 42); + font->drawWithShadow(batch, "fps:", 16, 42); font->drawWithShadow(batch, std::to_string(fps), 40, 42); } batch->render(); From b2382cc1827131b8fd1ae110c32615545e629057 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 15:41:24 +0300 Subject: [PATCH 28/56] Update linux makefiles --- Debug/objects.mk | 2 +- Debug/src/subdir.mk | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Debug/objects.mk b/Debug/objects.mk index f076e108..b7d25c5b 100644 --- a/Debug/objects.mk +++ b/Debug/objects.mk @@ -4,5 +4,5 @@ USER_OBJS := -LIBS := -lglfw -lpng -lopenal -lGL -lGLEW -lstdc++fs +LIBS := -lglfw -lpng -lGL -lGLEW -lstdc++fs -lopenal diff --git a/Debug/src/subdir.mk b/Debug/src/subdir.mk index 5919ac83..25556588 100644 --- a/Debug/src/subdir.mk +++ b/Debug/src/subdir.mk @@ -5,14 +5,17 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ ../src/Assets.cpp \ +../src/player_control.cpp \ ../src/voxel_engine.cpp OBJS += \ ./src/Assets.o \ +./src/player_control.o \ ./src/voxel_engine.o CPP_DEPS += \ ./src/Assets.d \ +./src/player_control.d \ ./src/voxel_engine.d From 123f3ae6ffefa9be3d12972d5f4d21855236a666 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 15:43:28 +0300 Subject: [PATCH 29/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 608b3fa8..c42ff866 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ `$ sudo apt install libglfw3-dev libglfw3 libglew-dev libglm-dev libpng-dev libopenal-dev` #### RHEL-based distro: -`$ sudo dnf install glfw-devel glfw glew-devel glm-devel libpng-devel` +`$ sudo dnf install glfw-devel glfw glew-devel glm-devel libpng-devel openal-devel` # Note for MinGW compiling: From 4ceba017c73f039cc91115ccc277606d0fc71473 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 16:07:55 +0300 Subject: [PATCH 30/56] Some refactor --- Debug/makefile | 1 + Debug/sources.mk | 1 + Debug/src/world/subdir.mk | 24 +++++++++++++++++++++ src/files/WorldFiles.cpp | 2 +- src/files/WorldFiles.h | 2 +- src/objects/Player.cpp | 3 +++ src/objects/Player.h | 2 ++ src/voxel_engine.cpp | 44 +++++++++++++++++++-------------------- src/world/World.cpp | 13 ++++++++++++ src/world/World.h | 19 +++++++++++++++++ src/world_render.h | 8 +++++-- 11 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 Debug/src/world/subdir.mk create mode 100644 src/world/World.cpp create mode 100644 src/world/World.h diff --git a/Debug/makefile b/Debug/makefile index 9c5b3843..0247a747 100644 --- a/Debug/makefile +++ b/Debug/makefile @@ -8,6 +8,7 @@ RM := rm -rf # All of the sources participating in the build are defined here -include sources.mk +-include src/world/subdir.mk -include src/window/subdir.mk -include src/voxels/subdir.mk -include src/physics/subdir.mk diff --git a/Debug/sources.mk b/Debug/sources.mk index b2849f80..39d73484 100644 --- a/Debug/sources.mk +++ b/Debug/sources.mk @@ -33,4 +33,5 @@ src/objects \ src/physics \ src/voxels \ src/window \ +src/world \ diff --git a/Debug/src/world/subdir.mk b/Debug/src/world/subdir.mk new file mode 100644 index 00000000..bf85112f --- /dev/null +++ b/Debug/src/world/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +CPP_SRCS += \ +../src/world/World.cpp + +OBJS += \ +./src/world/World.o + +CPP_DEPS += \ +./src/world/World.d + + +# Each subdirectory must supply rules for building sources it contributes +src/world/%.o: ../src/world/%.cpp src/world/subdir.mk + @echo 'Building file: $<' + @echo 'Invoking: Cross G++ Compiler' + g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 17fee0f0..850d045a 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -50,7 +50,7 @@ float bytes2Float(char* srcs, unsigned int offset){ return *(float*)(&value); } -WorldFiles::WorldFiles(const char* directory, size_t mainBufferCapacity) : directory(directory){ +WorldFiles::WorldFiles(std::string directory, size_t mainBufferCapacity) : directory(directory){ mainBufferIn = new char[CHUNK_VOL*2]; mainBufferOut = new char[mainBufferCapacity]; } diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index 9495f58b..9ee11778 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -25,7 +25,7 @@ public: char* mainBufferIn; char* mainBufferOut; - WorldFiles(const char* directory, size_t mainBufferCapacity); + WorldFiles(std::string directory, size_t mainBufferCapacity); ~WorldFiles(); void put(const char* chunkData, int x, int y); diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index b8e2b37a..997caf06 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -1,5 +1,8 @@ #include "Player.h" #include "../physics/Hitbox.h" +#include "../physics/PhysicsSolver.h" +#include "../voxels/Chunks.h" +#include "../window/Events.h" #include diff --git a/src/objects/Player.h b/src/objects/Player.h index d3e4e081..2147458f 100644 --- a/src/objects/Player.h +++ b/src/objects/Player.h @@ -5,6 +5,8 @@ class Camera; class Hitbox; +class PhysicsSolver; +class Chunks; class Player { public: diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index e4ba8473..290f70c2 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -41,6 +41,7 @@ using namespace glm; #include "lighting/Lighting.h" #include "physics/Hitbox.h" #include "physics/PhysicsSolver.h" +#include "world/World.h" #include "audio/Audio.h" #include "audio/audioutil.h" @@ -49,10 +50,18 @@ using namespace glm; #include "declarations.h" #include "world_render.h" +#include "player_control.h" + + +int WIDTH = 1280; +int HEIGHT = 720; // Save all world data to files -void write_world(WorldFiles* wfile, Chunks* chunks){ +void write_world(World* world){ + WorldFiles* wfile = world->wfile; + Chunks* chunks = world->chunks; + for (unsigned int i = 0; i < chunks->volume; i++){ Chunk* chunk = chunks->chunks[i]; if (chunk == nullptr) @@ -63,17 +72,6 @@ void write_world(WorldFiles* wfile, Chunks* chunks){ wfile->write(); } -// Deleting world data from memory -void close_world(WorldFiles* wfile, Chunks* chunks){ - delete chunks; - delete wfile; -} - -int WIDTH = 1280; -int HEIGHT = 720; - -#include "player_control.h" - int main() { setup_definitions(); @@ -93,13 +91,13 @@ int main() { } std::cout << "-- loading world" << std::endl; - Camera *camera = new Camera(vec3(-320,255,32), radians(90.0f)); - WorldFiles *wfile = new WorldFiles("world/", REGION_VOL * (CHUNK_VOL * 2 + 8)); - Chunks *chunks = new Chunks(34,1,34, 0,0,0); + Camera* camera = new Camera(vec3(-320,255,32), radians(90.0f)); + World* world = new World("world-1", "world/", new Chunks(34,1,34, 0,0,0)); + Chunks* chunks = world->chunks; Player* player = new Player(vec3(camera->position), 4.0f, camera); - wfile->readPlayer(player); + world->wfile->readPlayer(player); camera->rotation = mat4(1.0f); camera->rotate(player->camY, player->camX, 0); @@ -142,24 +140,24 @@ int main() { update_controls(&physics, chunks, player, delta); update_interaction(chunks, &physics, player, &lighting, lineBatch); - chunks->setCenter(wfile, camera->position.x,0,camera->position.z); + chunks->setCenter(world->wfile, camera->position.x,0,camera->position.z); chunksController._buildMeshes(&renderer, frame); int freeLoaders = chunksController.countFreeLoaders(); for (int i = 0; i < freeLoaders; i++) - chunksController.loadVisible(wfile); + chunksController.loadVisible(world->wfile); - draw_world(player, camera, assets, chunks, occlusion); - draw_hud(player, assets, chunks, devdata, fps); + draw_world(player, camera, assets, world, occlusion); + draw_hud(player, assets, world, devdata, fps); Window::swapBuffers(); Events::pullEvents(); } std::cout << "-- saving world" << std::endl; - wfile->writePlayer(player); - write_world(wfile, chunks); - close_world(wfile, chunks); + world->wfile->writePlayer(player); + write_world(world); + delete world; std::cout << "-- shutting down" << std::endl; diff --git a/src/world/World.cpp b/src/world/World.cpp new file mode 100644 index 00000000..31cdbf1c --- /dev/null +++ b/src/world/World.cpp @@ -0,0 +1,13 @@ +#include "World.h" + +#include "../files/WorldFiles.h" +#include "../voxels/Chunk.h" +#include "../voxels/Chunks.h" + +World::World(std::string name, std::string directory, Chunks* chunks) : name(name), chunks(chunks) { + wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_VOL * 2 + 8)); +} + +World::~World(){ + delete wfile; +} diff --git a/src/world/World.h b/src/world/World.h new file mode 100644 index 00000000..20343abc --- /dev/null +++ b/src/world/World.h @@ -0,0 +1,19 @@ +#ifndef WORLD_WORLD_H_ +#define WORLD_WORLD_H_ + +#include + +class WorldFiles; +class Chunks; + +class World { +public: + std::string name; + WorldFiles* wfile; + Chunks* chunks; + + World(std::string name, std::string directory, Chunks* chunks); + ~World(); +}; + +#endif /* WORLD_WORLD_H_ */ diff --git a/src/world_render.h b/src/world_render.h index eea5acb7..b2fe3075 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -110,7 +110,9 @@ bool chunks_comparator(size_t i, size_t j) { } -void draw_hud(Player* player, Assets* assets, Chunks* chunks, bool devdata, int fps){ +void draw_hud(Player* player, Assets* assets, World* world, bool devdata, int fps){ + Chunks* chunks = world->chunks; + glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); Shader* uishader = assets->getShader("ui"); @@ -141,7 +143,9 @@ void draw_hud(Player* player, Assets* assets, Chunks* chunks, bool devdata, int batch->render(); } -void draw_world(Player* player, Camera* camera, Assets* assets, Chunks* chunks, bool occlusion){ +void draw_world(Player* player, Camera* camera, Assets* assets, World* world, bool occlusion){ + Chunks* chunks = world->chunks; + glClearColor(0.7f,0.81f,1.0f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); From e8ca11894d5930edd31ac610a65b9155aba67ba6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 17:12:58 +0300 Subject: [PATCH 31/56] Added class Level for runtime world stuff --- Debug/src/world/subdir.mk | 3 +++ src/player_control.cpp | 8 +++++-- src/player_control.h | 4 ++-- src/voxel_engine.cpp | 47 +++++++++++++++++++-------------------- src/world/Level.cpp | 19 ++++++++++++++++ src/world/Level.h | 21 +++++++++++++++++ src/world/World.cpp | 2 +- src/world/World.h | 3 +-- src/world_render.h | 9 ++++---- 9 files changed, 81 insertions(+), 35 deletions(-) create mode 100644 src/world/Level.cpp create mode 100644 src/world/Level.h diff --git a/Debug/src/world/subdir.mk b/Debug/src/world/subdir.mk index bf85112f..0d5d11aa 100644 --- a/Debug/src/world/subdir.mk +++ b/Debug/src/world/subdir.mk @@ -4,12 +4,15 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ +../src/world/Level.cpp \ ../src/world/World.cpp OBJS += \ +./src/world/Level.o \ ./src/world/World.o CPP_DEPS += \ +./src/world/Level.d \ ./src/world/World.d diff --git a/src/player_control.cpp b/src/player_control.cpp index 33e71aa0..26223c43 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -5,6 +5,7 @@ #include "physics/PhysicsSolver.h" #include "physics/Hitbox.h" #include "lighting/Lighting.h" +#include "world/Level.h" #include "voxels/voxel.h" #include "voxels/Chunks.h" #include "window/Camera.h" @@ -162,8 +163,11 @@ void update_controls(PhysicsSolver* physics, } } -void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, Lighting* lighting, LineBatch* lineBatch){ +void update_interaction(Level* level, LineBatch* lineBatch){ + Chunks* chunks = level->chunks; + Player* player = level->player; Camera* camera = player->camera; + Lighting* lighting = level->lighting; vec3 end; vec3 norm; vec3 iend; @@ -182,7 +186,7 @@ void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, int x = (int)(iend.x)+(int)(norm.x); int y = (int)(iend.y)+(int)(norm.y); int z = (int)(iend.z)+(int)(norm.z); - if (!physics->isBlockInside(x,y,z, player->hitbox)){ + if (!level->physics->isBlockInside(x,y,z, player->hitbox)){ chunks->set(x, y, z, player->choosenBlock); lighting->onBlockSet(x,y,z, player->choosenBlock); } diff --git a/src/player_control.h b/src/player_control.h index e3a91407..d486b9b8 100644 --- a/src/player_control.h +++ b/src/player_control.h @@ -4,10 +4,10 @@ class PhysicsSolver; class Chunks; class Player; -class Lighting; class LineBatch; +class Level; void update_controls(PhysicsSolver* physics, Chunks* chunks, Player* player, float delta); -void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, Lighting* lighting, LineBatch* lineBatch); +void update_interaction(Level* level, LineBatch* lineBatch); #endif /* PLAYER_CONTROL_H_ */ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 290f70c2..e40a4d5c 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -42,6 +42,7 @@ using namespace glm; #include "physics/Hitbox.h" #include "physics/PhysicsSolver.h" #include "world/World.h" +#include "world/Level.h" #include "audio/Audio.h" #include "audio/audioutil.h" @@ -58,9 +59,9 @@ int HEIGHT = 720; // Save all world data to files -void write_world(World* world){ +void write_world(World* world, Level* level){ WorldFiles* wfile = world->wfile; - Chunks* chunks = world->chunks; + Chunks* chunks = level->chunks; for (unsigned int i = 0; i < chunks->volume; i++){ Chunk* chunk = chunks->chunks[i]; @@ -72,6 +73,18 @@ void write_world(World* world){ wfile->write(); } +void update_level(World* world, Level* level, VoxelRenderer* renderer, vec3 position, float delta, long frame){ + update_controls(level->physics, level->chunks, level->player, delta); + update_interaction(level, lineBatch); + + level->chunks->setCenter(world->wfile, position.x,0,position.z); + level->chunksController->_buildMeshes(renderer, frame); + + int freeLoaders = level->chunksController->countFreeLoaders(); + for (int i = 0; i < freeLoaders; i++) + level->chunksController->loadVisible(world->wfile); +} + int main() { setup_definitions(); @@ -91,12 +104,11 @@ int main() { } std::cout << "-- loading world" << std::endl; - Camera* camera = new Camera(vec3(-320,255,32), radians(90.0f)); - World* world = new World("world-1", "world/", new Chunks(34,1,34, 0,0,0)); - Chunks* chunks = world->chunks; - - + Camera* camera = new Camera(vec3(-320,200,32), radians(90.0f)); + World* world = new World("world-1", "world/"); Player* player = new Player(vec3(camera->position), 4.0f, camera); + Level* level = new Level(player, new Chunks(34,1,34, 0,0,0), new PhysicsSolver(vec3(0, -9.8f*2.0f, 0))); + world->wfile->readPlayer(player); camera->rotation = mat4(1.0f); camera->rotate(player->camY, player->camX, 0); @@ -104,13 +116,9 @@ int main() { std::cout << "-- preparing systems" << std::endl; VoxelRenderer renderer(1024*1024); - PhysicsSolver physics(vec3(0,-9.8f*2.0f,0)); - Lighting lighting(chunks); init_renderer(); - ChunksController chunksController(chunks, &lighting); - float lastTime = glfwGetTime(); float delta = 0.0f; @@ -137,18 +145,9 @@ int main() { devdata = !devdata; } - update_controls(&physics, chunks, player, delta); - update_interaction(chunks, &physics, player, &lighting, lineBatch); - - chunks->setCenter(world->wfile, camera->position.x,0,camera->position.z); - chunksController._buildMeshes(&renderer, frame); - - int freeLoaders = chunksController.countFreeLoaders(); - for (int i = 0; i < freeLoaders; i++) - chunksController.loadVisible(world->wfile); - - draw_world(player, camera, assets, world, occlusion); - draw_hud(player, assets, world, devdata, fps); + update_level(world, level, &renderer, camera->position, delta, frame); + draw_world(world, level, camera, assets, occlusion); + draw_hud(world, level, assets, devdata, fps); Window::swapBuffers(); Events::pullEvents(); @@ -156,7 +155,7 @@ int main() { std::cout << "-- saving world" << std::endl; world->wfile->writePlayer(player); - write_world(world); + write_world(world, level); delete world; std::cout << "-- shutting down" << std::endl; diff --git a/src/world/Level.cpp b/src/world/Level.cpp new file mode 100644 index 00000000..3faa316f --- /dev/null +++ b/src/world/Level.cpp @@ -0,0 +1,19 @@ +#include "Level.h" +#include "../lighting/Lighting.h" +#include "../voxels/ChunksController.h" + +Level::Level(Player* player, Chunks* chunks, PhysicsSolver* physics) : + player(player), + chunks(chunks), + physics(physics) { + lighting = new Lighting(chunks); + chunksController = new ChunksController(chunks, lighting); +} + +Level::~Level(){ + delete chunks; + delete physics; + delete player; + delete lighting; + delete chunksController; +} diff --git a/src/world/Level.h b/src/world/Level.h new file mode 100644 index 00000000..8284cbb0 --- /dev/null +++ b/src/world/Level.h @@ -0,0 +1,21 @@ +#ifndef WORLD_LEVEL_H_ +#define WORLD_LEVEL_H_ + +class Player; +class Chunks; +class Lighting; +class PhysicsSolver; +class ChunksController; + +class Level { +public: + Player* player; + Chunks* chunks; + PhysicsSolver* physics; + Lighting* lighting; + ChunksController* chunksController; + Level(Player* player, Chunks* chunks, PhysicsSolver* physics); + ~Level(); +}; + +#endif /* WORLD_LEVEL_H_ */ diff --git a/src/world/World.cpp b/src/world/World.cpp index 31cdbf1c..92e7c0e2 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -4,7 +4,7 @@ #include "../voxels/Chunk.h" #include "../voxels/Chunks.h" -World::World(std::string name, std::string directory, Chunks* chunks) : name(name), chunks(chunks) { +World::World(std::string name, std::string directory) : name(name) { wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_VOL * 2 + 8)); } diff --git a/src/world/World.h b/src/world/World.h index 20343abc..019601bd 100644 --- a/src/world/World.h +++ b/src/world/World.h @@ -10,9 +10,8 @@ class World { public: std::string name; WorldFiles* wfile; - Chunks* chunks; - World(std::string name, std::string directory, Chunks* chunks); + World(std::string name, std::string directory); ~World(); }; diff --git a/src/world_render.h b/src/world_render.h index b2fe3075..60a7c1a7 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -110,8 +110,9 @@ bool chunks_comparator(size_t i, size_t j) { } -void draw_hud(Player* player, Assets* assets, World* world, bool devdata, int fps){ - Chunks* chunks = world->chunks; +void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps){ + Chunks* chunks = level->chunks; + Player* player = level->player; glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); @@ -143,8 +144,8 @@ void draw_hud(Player* player, Assets* assets, World* world, bool devdata, int fp batch->render(); } -void draw_world(Player* player, Camera* camera, Assets* assets, World* world, bool occlusion){ - Chunks* chunks = world->chunks; +void draw_world(World* world, Level* level, Camera* camera, Assets* assets, bool occlusion){ + Chunks* chunks = level->chunks; glClearColor(0.7f,0.81f,1.0f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); From ffc39fccaf93a6d734e00f88f6a10dc0a390116e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 17:47:40 +0300 Subject: [PATCH 32/56] Some refactor again --- src/voxel_engine.cpp | 55 ++++++++++++++++++++++++++------------------ src/world_render.h | 4 ++++ 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index e40a4d5c..415627f3 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -54,6 +54,8 @@ using namespace glm; #include "player_control.h" +float gravity = 19.6f; + int WIDTH = 1280; int HEIGHT = 720; @@ -71,9 +73,11 @@ void write_world(World* world, Level* level){ } wfile->write(); + + world->wfile->writePlayer(level->player); } -void update_level(World* world, Level* level, VoxelRenderer* renderer, vec3 position, float delta, long frame){ +void update_level(World* world, Level* level, vec3 position, float delta, long frame){ update_controls(level->physics, level->chunks, level->player, delta); update_interaction(level, lineBatch); @@ -85,52 +89,60 @@ void update_level(World* world, Level* level, VoxelRenderer* renderer, vec3 posi level->chunksController->loadVisible(world->wfile); } +Level* load_level(World* world, Player* player) { + Level* level = new Level(player, new Chunks(34,1,34, 0,0,0), new PhysicsSolver(vec3(0, -gravity, 0))); + world->wfile->readPlayer(player); -int main() { - setup_definitions(); + Camera* camera = player->camera; + camera->rotation = mat4(1.0f); + camera->rotate(player->camY, player->camX, 0); + return level; +} + +int initialize(Assets*& assets){ Audio::initialize(); - Window::initialize(WIDTH, HEIGHT, "Window 2.0"); Events::initialize(); + assets = new Assets(); std::cout << "-- loading assets" << std::endl; - Assets* assets = new Assets(); int result = initialize_assets(assets); if (result){ delete assets; Window::terminate(); return result; } + return 0; +} + + +int main() { + setup_definitions(); + + Assets* assets; + int status = initialize(assets); + if (status) return status; + std::cout << "-- loading world" << std::endl; - - Camera* camera = new Camera(vec3(-320,200,32), radians(90.0f)); + vec3 playerPosition = vec3(-320,200,32); + Camera* camera = new Camera(playerPosition, radians(90.0f)); World* world = new World("world-1", "world/"); - Player* player = new Player(vec3(camera->position), 4.0f, camera); - Level* level = new Level(player, new Chunks(34,1,34, 0,0,0), new PhysicsSolver(vec3(0, -9.8f*2.0f, 0))); - - world->wfile->readPlayer(player); - camera->rotation = mat4(1.0f); - camera->rotate(player->camY, player->camX, 0); + Player* player = new Player(playerPosition, 4.0f, camera); + Level* level = load_level(world, player); std::cout << "-- preparing systems" << std::endl; - - VoxelRenderer renderer(1024*1024); - init_renderer(); float lastTime = glfwGetTime(); float delta = 0.0f; - long frame = 0; - bool occlusion = false; bool devdata = false; glfwSwapInterval(0); std::cout << "-- initializing finished" << std::endl; - while (!Window::isShouldClose()){ frame++; float currentTime = glfwGetTime(); @@ -145,7 +157,7 @@ int main() { devdata = !devdata; } - update_level(world, level, &renderer, camera->position, delta, frame); + update_level(world, level, camera->position, delta, frame); draw_world(world, level, camera, assets, occlusion); draw_hud(world, level, assets, devdata, fps); @@ -153,13 +165,10 @@ int main() { Events::pullEvents(); } std::cout << "-- saving world" << std::endl; - - world->wfile->writePlayer(player); write_world(world, level); delete world; std::cout << "-- shutting down" << std::endl; - delete assets; finalize_renderer(); Audio::finalize(); diff --git a/src/world_render.h b/src/world_render.h index 60a7c1a7..0531eb79 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -46,6 +46,7 @@ int uiscale = 2; LineBatch *lineBatch; Batch2D *batch; Camera *uicamera; +VoxelRenderer *renderer; void init_renderer(){ crosshair = new Mesh(vertices, 4, attrs); @@ -55,6 +56,8 @@ void init_renderer(){ uicamera = new Camera(glm::vec3(), Window::height / uiscale); uicamera->perspective = false; uicamera->flipped = true; + + renderer = new VoxelRenderer(1024*1024); } @@ -62,6 +65,7 @@ void finalize_renderer(){ delete crosshair; delete lineBatch; delete batch; + delete renderer; } void draw_chunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ From 15bed4169ec2928ee592785ea036bf50c50d0537 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 17:52:35 +0300 Subject: [PATCH 33/56] Update .gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 492224c2..f1bcd4b5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,8 @@ Debug/src/**/*.o Debug/voxel_engine -.vscode \ No newline at end of file +.vscode + +.settings +.cproject +.project From f569378b88ae20e39486c5365468b3f11942241b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 19:30:23 +0300 Subject: [PATCH 34/56] Chunks render moved to ChunksLoader --- src/graphics/VoxelRenderer.cpp | 36 +++++++++++++------------- src/graphics/VoxelRenderer.h | 10 +++++--- src/player_control.cpp | 2 +- src/voxel_engine.cpp | 10 +++++--- src/voxels/Chunk.cpp | 1 + src/voxels/Chunk.h | 9 +++++++ src/voxels/ChunksController.cpp | 45 +++++++++++++++++++++++++++++---- src/voxels/ChunksLoader.cpp | 35 ++++++++++++++++++++----- src/voxels/ChunksLoader.h | 15 ++++++++--- src/window/Window.cpp | 4 +++ src/window/Window.h | 1 + src/world_render.h | 2 +- 12 files changed, 127 insertions(+), 43 deletions(-) diff --git a/src/graphics/VoxelRenderer.cpp b/src/graphics/VoxelRenderer.cpp index fde67308..5b5a7537 100644 --- a/src/graphics/VoxelRenderer.cpp +++ b/src/graphics/VoxelRenderer.cpp @@ -1,12 +1,12 @@ #include "VoxelRenderer.h" + +#include #include "Mesh.h" #include "../voxels/Chunk.h" #include "../voxels/voxel.h" #include "../voxels/Block.h" #include "../lighting/Lightmap.h" -#define VERTEX_SIZE (3 + 2 + 4) - #define CDIV(X,A) (((X) < 0) ? ((X) / (A) - 1) : ((X) / (A))) #define LOCAL_NEG(X, SIZE) (((X) < 0) ? ((SIZE)+(X)) : (X)) #define LOCAL(X, SIZE) ((X) >= (SIZE) ? ((X) - (SIZE)) : LOCAL_NEG(X, SIZE)) @@ -17,16 +17,16 @@ #define VOXEL(X,Y,Z) (GET_CHUNK(X,Y,Z)->voxels[(LOCAL(Y, CHUNK_H) * CHUNK_D + LOCAL(Z, CHUNK_D)) * CHUNK_W + LOCAL(X, CHUNK_W)]) #define IS_BLOCKED(X,Y,Z,GROUP) ((!IS_CHUNK(X, Y, Z)) || Block::blocks[VOXEL(X, Y, Z).id]->drawGroup == (GROUP)) -#define VERTEX(INDEX, X,Y,Z, U,V, R,G,B,S) buffer[INDEX+0] = (X);\ - buffer[INDEX+1] = (Y);\ - buffer[INDEX+2] = (Z);\ - buffer[INDEX+3] = (U);\ - buffer[INDEX+4] = (V);\ - buffer[INDEX+5] = (R);\ - buffer[INDEX+6] = (G);\ - buffer[INDEX+7] = (B);\ - buffer[INDEX+8] = (S);\ - INDEX += VERTEX_SIZE; +#define VERTEX(INDEX, X,Y,Z, U,V, R,G,B,S) buffer.push_back(X);\ + buffer.push_back(Y);\ + buffer.push_back(Z);\ + buffer.push_back(U);\ + buffer.push_back(V);\ + buffer.push_back(R);\ + buffer.push_back(G);\ + buffer.push_back(B);\ + buffer.push_back(S);\ + INDEX += CHUNK_VERTEX_SIZE; #define SETUP_UV(INDEX) float u1 = ((INDEX) % 16) * uvsize;\ @@ -36,15 +36,13 @@ int chunk_attrs[] = {3,2,4, 0}; -VoxelRenderer::VoxelRenderer(size_t capacity) : capacity(capacity) { - buffer = new float[capacity * VERTEX_SIZE * 6]; +VoxelRenderer::VoxelRenderer() { } VoxelRenderer::~VoxelRenderer(){ - delete[] buffer; } -inline void _renderBlock(float* buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){ +inline void _renderBlock(std::vector& buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){ unsigned int id = vox.id; if (!id){ @@ -289,7 +287,8 @@ inline void _renderBlock(float* buffer, int x, int y, int z, const Chunk** chunk } } -Mesh* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks){ +const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& size){ + buffer.clear(); size_t index = 0; for (int y = 0; y < CHUNK_H; y++){ for (int z = 0; z < CHUNK_D; z++){ @@ -323,5 +322,6 @@ Mesh* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks){ } } } - return new Mesh(buffer, index / VERTEX_SIZE, chunk_attrs); + size = buffer.size(); + return &buffer[0]; } diff --git a/src/graphics/VoxelRenderer.h b/src/graphics/VoxelRenderer.h index 4b3a6255..84e38238 100644 --- a/src/graphics/VoxelRenderer.h +++ b/src/graphics/VoxelRenderer.h @@ -2,18 +2,20 @@ #define GRAPHICS_VOXELRENDERER_H_ #include +#include class Mesh; class Chunk; +#define CHUNK_VERTEX_SIZE (3 + 2 + 4) + class VoxelRenderer { - float* buffer; - size_t capacity; public: - VoxelRenderer(size_t capacity); + std::vector buffer; + VoxelRenderer(); ~VoxelRenderer(); - Mesh* render(Chunk* chunk, const Chunk** chunks); + const float* render(Chunk* chunk, const Chunk** chunks, size_t& size); }; #endif /* GRAPHICS_VOXELRENDERER_H_ */ diff --git a/src/player_control.cpp b/src/player_control.cpp index 26223c43..6b814fba 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -25,7 +25,7 @@ #define CAMERA_SHAKING_OFFSET_Y 0.031f #define CAMERA_SHAKING_SPEED 1.6f #define CAMERA_SHAKING_DELTA_K 10.0f -#define FLIGHT_SPEED_MUL 5.0f +#define FLIGHT_SPEED_MUL 8.0f #define JUMP_FORCE 7.0f void update_controls(PhysicsSolver* physics, diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 415627f3..9c1a0bed 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -81,10 +81,12 @@ void update_level(World* world, Level* level, vec3 position, float delta, long f update_controls(level->physics, level->chunks, level->player, delta); update_interaction(level, lineBatch); - level->chunks->setCenter(world->wfile, position.x,0,position.z); - level->chunksController->_buildMeshes(renderer, frame); - + level->chunks->setCenter(world->wfile, position.x, 0, position.z); int freeLoaders = level->chunksController->countFreeLoaders(); + for (int i = 0; i < freeLoaders; i++) + level->chunksController->_buildMeshes(renderer, frame); + + freeLoaders = level->chunksController->countFreeLoaders(); for (int i = 0; i < freeLoaders; i++) level->chunksController->loadVisible(world->wfile); } @@ -140,7 +142,7 @@ int main() { bool occlusion = false; bool devdata = false; - glfwSwapInterval(0); + Window::swapInterval(0); std::cout << "-- initializing finished" << std::endl; while (!Window::isShouldClose()){ diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index a4e645b0..5bf9006e 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -8,6 +8,7 @@ Chunk::Chunk(int xpos, int ypos, int zpos) : x(xpos), y(ypos), z(zpos){ for (unsigned int i = 0; i < CHUNK_VOL; i++) voxels[i].id = 1; lightmap = new Lightmap(); + renderData.vertices = nullptr; } Chunk::~Chunk(){ diff --git a/src/voxels/Chunk.h b/src/voxels/Chunk.h index 14d1689c..2c37fed9 100644 --- a/src/voxels/Chunk.h +++ b/src/voxels/Chunk.h @@ -1,6 +1,8 @@ #ifndef VOXELS_CHUNK_H_ #define VOXELS_CHUNK_H_ +#include + #define CHUNK_W 16 #define CHUNK_H 256 #define CHUNK_D 16 @@ -9,6 +11,11 @@ class voxel; class Lightmap; +struct RenderData { + float* vertices; + size_t size; +}; + class Chunk { public: int x,y,z; @@ -19,6 +26,8 @@ public: bool loaded = false; int surrounding = 0; int references = 1; + RenderData renderData; + Chunk(int x, int y, int z); ~Chunk(); diff --git a/src/voxels/ChunksController.cpp b/src/voxels/ChunksController.cpp index d2b98eb1..9d8d3489 100644 --- a/src/voxels/ChunksController.cpp +++ b/src/voxels/ChunksController.cpp @@ -20,7 +20,7 @@ ChunksController::ChunksController(Chunks* chunks, Lighting* lighting) : chunks(chunks), lighting(lighting){ - loadersCount = std::thread::hardware_concurrency() - 1; + loadersCount = std::thread::hardware_concurrency() * 2 - 1; if (loadersCount <= 0) loadersCount = 1; loaders = new ChunksLoader*[loadersCount]; @@ -130,7 +130,7 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){ oz += 1; closes[(oy * 3 + oz) * 3 + ox] = other; } - freeLoader->perform(chunk, (Chunk**)closes); + freeLoader->load(chunk, (Chunk**)closes); return true; } @@ -139,6 +139,35 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { const int h = chunks->h; const int d = chunks->d; + for (int y = 0; y < h; y++){ + for (int z = 1; z < d-1; z++){ + for (int x = 1; x < w-1; x++){ + int index = (y * d + z) * w + x; + Chunk* chunk = chunks->chunks[index]; + if (chunk == nullptr) + continue; + if (chunk->renderData.vertices > (void*)1){ + const int chunk_attrs[] = {3,2,4, 0}; + Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs); + chunks->meshes[index] = mesh; + delete[] chunk->renderData.vertices; + chunk->renderData.vertices = nullptr; + } + } + } + } + ChunksLoader* freeLoader = nullptr; + for (int i = 0; i < loadersCount; i++){ + ChunksLoader* loader = loaders[i]; + if (loader->isBusy()){ + continue; + } + freeLoader = loader; + break; + } + if (freeLoader == nullptr) + return false; + int nearX = 0; int nearY = 0; int nearZ = 0; @@ -208,9 +237,15 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { oz += 1; closes[(oy * 3 + oz) * 3 + ox] = other; } - mesh = renderer->render(chunk, (const Chunk**)closes); - chunks->meshes[index] = mesh; - return true; + if (chunk->renderData.vertices == nullptr){ + chunk->renderData.vertices = (float*)1; + freeLoader->render(chunk, (Chunk**)closes); + + return true; + } + //mesh = renderer->render(chunk, (const Chunk**)closes); + //chunks->meshes[index] = mesh; + } return false; } diff --git a/src/voxels/ChunksLoader.cpp b/src/voxels/ChunksLoader.cpp index 89963760..be82d168 100644 --- a/src/voxels/ChunksLoader.cpp +++ b/src/voxels/ChunksLoader.cpp @@ -5,6 +5,7 @@ #include "Chunks.h" #include "WorldGenerator.h" #include "../lighting/Lighting.h" +#include "../graphics/VoxelRenderer.h" #include @@ -13,7 +14,8 @@ void ChunksLoader::_thread(){ Chunks chunks(3,3,3, -1,-1,-1); Lighting lighting(&chunks); - while (working){ + VoxelRenderer renderer; + while (state != OFF){ if (current == nullptr){ std::this_thread::sleep_for(std::chrono::milliseconds(1)); continue; @@ -27,12 +29,24 @@ void ChunksLoader::_thread(){ } } - if (!chunk->loaded){ - WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z); + if (state == LOAD){ + chunks.putChunk(chunk); + if (!chunk->loaded){ + WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z); + } + + lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true); + } + else if (state == RENDER){ + size_t size; + renderer.render(chunk, (const Chunk**)(closes.load()), size); + float* vertices = new float[size]; + for (size_t i = 0; i < size; i++) + vertices[i] = renderer.buffer[i]; + chunk->renderData.vertices = vertices; + chunk->renderData.size = size; } - chunks.putChunk(chunk); - lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true); chunks.clear(false); for (int i = 0; i < CLOSES_C; i++){ Chunk* other = closes[i]; @@ -45,7 +59,7 @@ void ChunksLoader::_thread(){ } } -void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed){ +void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode){ if (isBusy()){ std::cerr << "performing while busy" << std::endl; return; @@ -64,4 +78,13 @@ void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed){ } } current = chunk; + state = mode; +} + +void ChunksLoader::load(Chunk* chunk, Chunk** closes_passed){ + perform(chunk, closes_passed, LOAD); +} + +void ChunksLoader::render(Chunk* chunk, Chunk** closes_passed){ + perform(chunk, closes_passed, RENDER); } diff --git a/src/voxels/ChunksLoader.h b/src/voxels/ChunksLoader.h index aff93ec7..98433b7c 100644 --- a/src/voxels/ChunksLoader.h +++ b/src/voxels/ChunksLoader.h @@ -12,19 +12,25 @@ class Chunk; +enum LoaderMode { + OFF, IDLE, LOAD, RENDER, +}; + class ChunksLoader final { private: std::thread loaderThread; void _thread(); std::atomic current {nullptr}; std::atomic closes {nullptr}; - std::atomic working {true}; + std::atomic state {IDLE}; + + void perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode); public: ChunksLoader() : loaderThread{} { loaderThread = std::thread{&ChunksLoader::_thread, this}; } ~ChunksLoader(){ - working = false; + state = OFF; loaderThread.join(); } @@ -32,10 +38,11 @@ public: return current != nullptr; } - void perform(Chunk* chunk, Chunk** closes_passed); + void load(Chunk* chunk, Chunk** closes_passed); + void render(Chunk* chunk, Chunk** closes_passed); void stop(){ - working = false; + state = OFF; } }; diff --git a/src/window/Window.cpp b/src/window/Window.cpp index ef6d48d8..a761631e 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -57,6 +57,10 @@ void Window::setShouldClose(bool flag){ glfwSetWindowShouldClose(window, flag); } +void Window::swapInterval(int interval){ + glfwSwapInterval(interval); +} + void Window::swapBuffers(){ glfwSwapBuffers(window); } diff --git a/src/window/Window.h b/src/window/Window.h index a0575af9..b54e1a58 100644 --- a/src/window/Window.h +++ b/src/window/Window.h @@ -15,6 +15,7 @@ public: static bool isShouldClose(); static void setShouldClose(bool flag); static void swapBuffers(); + static void swapInterval(int interval); }; #endif /* WINDOW_WINDOW_H_ */ diff --git a/src/world_render.h b/src/world_render.h index 0531eb79..d50c68f6 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -57,7 +57,7 @@ void init_renderer(){ uicamera->perspective = false; uicamera->flipped = true; - renderer = new VoxelRenderer(1024*1024); + renderer = new VoxelRenderer(); } From 37dd882fdbce149537d905269d178298c79bba10 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jun 2022 20:13:49 +0300 Subject: [PATCH 35/56] Small chunks render fix --- src/voxels/ChunksController.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/voxels/ChunksController.cpp b/src/voxels/ChunksController.cpp index 9d8d3489..05b1ab28 100644 --- a/src/voxels/ChunksController.cpp +++ b/src/voxels/ChunksController.cpp @@ -149,6 +149,8 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { if (chunk->renderData.vertices > (void*)1){ const int chunk_attrs[] = {3,2,4, 0}; Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs); + if (chunks->meshes[index]) + delete chunks->meshes[index]; chunks->meshes[index] = mesh; delete[] chunk->renderData.vertices; chunk->renderData.vertices = nullptr; @@ -209,8 +211,6 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { Mesh* mesh = chunks->meshes[index]; if (mesh == nullptr || chunk->modified){ Chunk* closes[27]; - if (mesh != nullptr) - delete mesh; if (chunk->isEmpty()){ chunks->meshes[index] = nullptr; return false; From 1038a79b785fa7b721be7ed0b2902c0123d48e63 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 1 Jul 2022 02:31:30 +0300 Subject: [PATCH 36/56] Added generation seed support --- src/voxel_engine.cpp | 6 +++--- src/voxels/ChunksController.cpp | 7 ++++--- src/voxels/ChunksController.h | 3 ++- src/voxels/ChunksLoader.cpp | 3 ++- src/voxels/ChunksLoader.h | 4 +++- src/voxels/WorldGenerator.cpp | 5 +++-- src/voxels/WorldGenerator.h | 2 +- src/world/Level.cpp | 4 ++-- src/world/Level.h | 3 ++- src/world/World.cpp | 2 +- src/world/World.h | 3 ++- 11 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 9c1a0bed..9fc3e307 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -92,7 +92,7 @@ void update_level(World* world, Level* level, vec3 position, float delta, long f } Level* load_level(World* world, Player* player) { - Level* level = new Level(player, new Chunks(34,1,34, 0,0,0), new PhysicsSolver(vec3(0, -gravity, 0))); + Level* level = new Level(world, player, new Chunks(32,1,32, 0,0,0), new PhysicsSolver(vec3(0, -gravity, 0))); world->wfile->readPlayer(player); Camera* camera = player->camera; @@ -129,7 +129,7 @@ int main() { std::cout << "-- loading world" << std::endl; vec3 playerPosition = vec3(-320,200,32); Camera* camera = new Camera(playerPosition, radians(90.0f)); - World* world = new World("world-1", "world/"); + World* world = new World("world-1", "world/", 42); Player* player = new Player(playerPosition, 4.0f, camera); Level* level = load_level(world, player); @@ -142,7 +142,7 @@ int main() { bool occlusion = false; bool devdata = false; - Window::swapInterval(0); + Window::swapInterval(1); std::cout << "-- initializing finished" << std::endl; while (!Window::isShouldClose()){ diff --git a/src/voxels/ChunksController.cpp b/src/voxels/ChunksController.cpp index 05b1ab28..96b2cac4 100644 --- a/src/voxels/ChunksController.cpp +++ b/src/voxels/ChunksController.cpp @@ -8,6 +8,7 @@ #include "../files/WorldFiles.h" #include "ChunksLoader.h" #include +#include #ifdef _WIN32 #define _WIN32_WINNT 0x0501 @@ -19,13 +20,13 @@ #define MIN_SURROUNDING 9 -ChunksController::ChunksController(Chunks* chunks, Lighting* lighting) : chunks(chunks), lighting(lighting){ +ChunksController::ChunksController(World* world, Chunks* chunks, Lighting* lighting) : chunks(chunks), lighting(lighting){ loadersCount = std::thread::hardware_concurrency() * 2 - 1; if (loadersCount <= 0) loadersCount = 1; loaders = new ChunksLoader*[loadersCount]; for (int i = 0; i < loadersCount; i++){ - loaders[i] = new ChunksLoader(); + loaders[i] = new ChunksLoader(world); } std::cout << "created " << loadersCount << " loaders" << std::endl; } @@ -173,7 +174,7 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { int nearX = 0; int nearY = 0; int nearZ = 0; - int minDistance = 1000000000; + int minDistance = INT_MAX; for (int y = 0; y < h; y++){ for (int z = 1; z < d-1; z++){ for (int x = 1; x < w-1; x++){ diff --git a/src/voxels/ChunksController.h b/src/voxels/ChunksController.h index d31d925f..9212e207 100644 --- a/src/voxels/ChunksController.h +++ b/src/voxels/ChunksController.h @@ -1,6 +1,7 @@ #ifndef VOXELS_CHUNKSCONTROLLER_H_ #define VOXELS_CHUNKSCONTROLLER_H_ +class World; class Chunks; class Lighting; class WorldFiles; @@ -14,7 +15,7 @@ private: ChunksLoader** loaders; int loadersCount; public: - ChunksController(Chunks* chunks, Lighting* lighting); + ChunksController(World* world, Chunks* chunks, Lighting* lighting); ~ChunksController(); int countFreeLoaders(); diff --git a/src/voxels/ChunksLoader.cpp b/src/voxels/ChunksLoader.cpp index be82d168..f71b5363 100644 --- a/src/voxels/ChunksLoader.cpp +++ b/src/voxels/ChunksLoader.cpp @@ -3,6 +3,7 @@ #include "Chunk.h" #include "Chunks.h" +#include "../world/World.h" #include "WorldGenerator.h" #include "../lighting/Lighting.h" #include "../graphics/VoxelRenderer.h" @@ -32,7 +33,7 @@ void ChunksLoader::_thread(){ if (state == LOAD){ chunks.putChunk(chunk); if (!chunk->loaded){ - WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z); + WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world.load()->seed); } lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true); diff --git a/src/voxels/ChunksLoader.h b/src/voxels/ChunksLoader.h index 98433b7c..5e5a5b22 100644 --- a/src/voxels/ChunksLoader.h +++ b/src/voxels/ChunksLoader.h @@ -11,6 +11,7 @@ #include class Chunk; +class World; enum LoaderMode { OFF, IDLE, LOAD, RENDER, @@ -22,11 +23,12 @@ private: void _thread(); std::atomic current {nullptr}; std::atomic closes {nullptr}; + std::atomic world {nullptr}; std::atomic state {IDLE}; void perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode); public: - ChunksLoader() : loaderThread{} { + ChunksLoader(World* world) : loaderThread{}, world(world) { loaderThread = std::thread{&ChunksLoader::_thread, this}; } ~ChunksLoader(){ diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index 9d6d5afc..a1495004 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -85,9 +85,10 @@ int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights, return 0; } -void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz){ +void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ fnl_state noise = fnlCreateState(); noise.noise_type = FNL_NOISE_OPENSIMPLEX2; + noise.seed = seed * 60617077 % 25896307; PseudoRandom random; @@ -144,4 +145,4 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz){ } } } -} \ No newline at end of file +} diff --git a/src/voxels/WorldGenerator.h b/src/voxels/WorldGenerator.h index c04dbd31..ae164319 100644 --- a/src/voxels/WorldGenerator.h +++ b/src/voxels/WorldGenerator.h @@ -5,7 +5,7 @@ class voxel; class WorldGenerator { public: - static void generate(voxel* voxels, int x, int y, int z); + static void generate(voxel* voxels, int x, int y, int z, int seed); }; #endif /* VOXELS_WORLDGENERATOR_H_ */ diff --git a/src/world/Level.cpp b/src/world/Level.cpp index 3faa316f..7770d124 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -2,12 +2,12 @@ #include "../lighting/Lighting.h" #include "../voxels/ChunksController.h" -Level::Level(Player* player, Chunks* chunks, PhysicsSolver* physics) : +Level::Level(World* world, Player* player, Chunks* chunks, PhysicsSolver* physics) : player(player), chunks(chunks), physics(physics) { lighting = new Lighting(chunks); - chunksController = new ChunksController(chunks, lighting); + chunksController = new ChunksController(world, chunks, lighting); } Level::~Level(){ diff --git a/src/world/Level.h b/src/world/Level.h index 8284cbb0..de4bf554 100644 --- a/src/world/Level.h +++ b/src/world/Level.h @@ -1,6 +1,7 @@ #ifndef WORLD_LEVEL_H_ #define WORLD_LEVEL_H_ +class World; class Player; class Chunks; class Lighting; @@ -14,7 +15,7 @@ public: PhysicsSolver* physics; Lighting* lighting; ChunksController* chunksController; - Level(Player* player, Chunks* chunks, PhysicsSolver* physics); + Level(World* world, Player* player, Chunks* chunks, PhysicsSolver* physics); ~Level(); }; diff --git a/src/world/World.cpp b/src/world/World.cpp index 92e7c0e2..2e336dce 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -4,7 +4,7 @@ #include "../voxels/Chunk.h" #include "../voxels/Chunks.h" -World::World(std::string name, std::string directory) : name(name) { +World::World(std::string name, std::string directory, int seed) : name(name), seed(seed) { wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_VOL * 2 + 8)); } diff --git a/src/world/World.h b/src/world/World.h index 019601bd..7b51192b 100644 --- a/src/world/World.h +++ b/src/world/World.h @@ -10,8 +10,9 @@ class World { public: std::string name; WorldFiles* wfile; + int seed; - World(std::string name, std::string directory); + World(std::string name, std::string directory, int seed); ~World(); }; From b2872650d68edd6b5ca570cca5db260a1a308507 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 1 Jul 2022 02:34:34 +0300 Subject: [PATCH 37/56] mini-fix --- src/voxel_engine.cpp | 2 +- src/voxels/ChunksLoader.cpp | 2 +- src/voxels/ChunksLoader.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 9fc3e307..4eafd412 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -92,7 +92,7 @@ void update_level(World* world, Level* level, vec3 position, float delta, long f } Level* load_level(World* world, Player* player) { - Level* level = new Level(world, player, new Chunks(32,1,32, 0,0,0), new PhysicsSolver(vec3(0, -gravity, 0))); + Level* level = new Level(world, player, new Chunks(34,1,34, 0,0,0), new PhysicsSolver(vec3(0, -gravity, 0))); world->wfile->readPlayer(player); Camera* camera = player->camera; diff --git a/src/voxels/ChunksLoader.cpp b/src/voxels/ChunksLoader.cpp index f71b5363..4c4796ad 100644 --- a/src/voxels/ChunksLoader.cpp +++ b/src/voxels/ChunksLoader.cpp @@ -33,7 +33,7 @@ void ChunksLoader::_thread(){ if (state == LOAD){ chunks.putChunk(chunk); if (!chunk->loaded){ - WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world.load()->seed); + WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world->seed); } lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true); diff --git a/src/voxels/ChunksLoader.h b/src/voxels/ChunksLoader.h index 5e5a5b22..37c623fd 100644 --- a/src/voxels/ChunksLoader.h +++ b/src/voxels/ChunksLoader.h @@ -23,8 +23,8 @@ private: void _thread(); std::atomic current {nullptr}; std::atomic closes {nullptr}; - std::atomic world {nullptr}; std::atomic state {IDLE}; + World* world; void perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode); public: From bdd3fbf7d4f9b73cbe5fa2ba9108cafb673a967d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 14 Jul 2022 19:23:31 +0300 Subject: [PATCH 38/56] Added 3 unicode pages for font, fixed UI, added Block.breakable Added 1, 2, 3 and 4 unicode pages from Minecraft. Font now uses std::wstring instead of std::string Added Block.breakable field (the only unbreakable block is bedrock) Bedrock is now selectable --- res/font_0.png | Bin 0 -> 6483 bytes res/font_1.png | Bin 0 -> 27588 bytes res/font_2.png | Bin 0 -> 5711 bytes res/font_3.png | Bin 0 -> 5457 bytes res/font_4.png | Bin 0 -> 6201 bytes src/declarations.h | 22 ++++++++++------- src/files/WorldFiles.cpp | 2 +- src/graphics/Batch2D.cpp | 11 +++++++-- src/graphics/Font.cpp | 44 ++++++++++++++++++++++------------ src/graphics/Font.h | 11 +++++---- src/lighting/Lighting.cpp | 2 ++ src/player_control.cpp | 3 ++- src/voxel_engine.cpp | 4 ++-- src/voxels/Block.h | 1 + src/voxels/ChunksLoader.cpp | 8 +++++++ src/voxels/WorldGenerator.cpp | 14 ++++++++--- src/world_render.h | 19 +++++++-------- 17 files changed, 94 insertions(+), 47 deletions(-) create mode 100644 res/font_0.png create mode 100644 res/font_1.png create mode 100644 res/font_2.png create mode 100644 res/font_3.png create mode 100644 res/font_4.png diff --git a/res/font_0.png b/res/font_0.png new file mode 100644 index 0000000000000000000000000000000000000000..0f15661240f2589c102c344392a0257d44f42148 GIT binary patch literal 6483 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ⅆdRCQmc zjtUS&UA>{2uTU0D-Emp~F EFWeP*!vFvP literal 0 HcmV?d00001 diff --git a/res/font_1.png b/res/font_1.png new file mode 100644 index 0000000000000000000000000000000000000000..92d7b2b35e7ef000e22ac6d8f524db05a5a72c1a GIT binary patch literal 27588 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 literal 0 HcmV?d00001 diff --git a/res/font_2.png b/res/font_2.png new file mode 100644 index 0000000000000000000000000000000000000000..984affe852d81090adb746fb10274ebc247f20e5 GIT binary patch literal 5711 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 Y)~YI=)?_wa5=94SYdlu3R7HmU5C4;iQ~&?~ literal 0 HcmV?d00001 diff --git a/res/font_3.png b/res/font_3.png new file mode 100644 index 0000000000000000000000000000000000000000..49b44eec77081ac5195d61ea73b89661af03c6c5 GIT binary patch literal 5457 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 RMAkr-~DT4GWNE2yN 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 pages; + for (size_t i = 0; i <= 4; i++){ + Texture* texture = load_texture(filename+"_"+std::to_string(i)+".png"); + if (texture == nullptr){ + std::cerr << "failed to load bitmap font '" << name << "' (missing page " << std::to_string(i) << ")" << std::endl; + return false; + } + pages.push_back(texture); } - Font* font = new Font(texture); + Font* font = new Font(pages); assets->store(font, name); return true; } @@ -62,13 +66,15 @@ int initialize_assets(Assets* assets) { LOAD_TEXTURE("res/block.png", "block"); - LOAD_FONT("res/font.png", "normal"); + LOAD_FONT("res/font", "normal"); return 0; } // All in-game definitions (blocks, items, etc..) void setup_definitions() { + for (size_t i = 0; i < 256; i++) + Block::blocks[i] = nullptr; // AIR 0 Block* block = new Block(0,0); block->drawGroup = 1; @@ -128,13 +134,13 @@ void setup_definitions() { block->selectable = false; Block::blocks[block->id] = block; - // SEND 10 + // SAND 10 block = new Block(10,12); Block::blocks[block->id] = block; // BEDROCK 11 block = new Block(11,13); - block->selectable = false; + block->breakable = false; Block::blocks[block->id] = block; } #endif // DECLARATIONS_H diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 850d045a..f9ae26ba 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -210,7 +210,7 @@ bool WorldFiles::readPlayer(Player* player) { size_t length = 0; char* data = read_binary_file(getPlayerFile(), length); if (data == nullptr){ - std::cerr << "could not to read player.bin" << std::endl; + std::cerr << "could not to read player.bin (ignored)" << std::endl; return false; } glm::vec3 position = player->hitbox->position; diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index fe2dc250..45a00579 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -4,6 +4,8 @@ #include +#define VERTEX_SIZE 8 + Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){ @@ -11,7 +13,7 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), 2, 2, 4, 0 //null terminator }; - buffer = new float[capacity * 8]; + buffer = new float[capacity * VERTEX_SIZE]; mesh = new Mesh(buffer, 0, attrs); index = 0; @@ -49,6 +51,7 @@ void Batch2D::vertex(float x, float y, void Batch2D::texture(Texture* new_texture){ if (_texture == new_texture) return; + render(); _texture = new_texture; if (new_texture == nullptr) blank->bind(); @@ -61,6 +64,8 @@ void Batch2D::rect(float x, float y, float w, float h){ const float g = color.g; const float b = color.b; const float a = color.a; + if (index + 6*VERTEX_SIZE >= capacity) + render(); vertex(x, y, 0, 0, r,g,b,a); vertex(x+w, y+h, 1, 1, r,g,b,a); @@ -81,6 +86,8 @@ void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index void Batch2D::rect(float x, float y, float w, float h, float u, float v, float tx, float ty, float r, float g, float b, float a){ + if (index + 6*VERTEX_SIZE >= capacity) + render(); vertex(x, y, u, v+ty, r,g,b,a); vertex(x+w, y+h, u+tx, v, r,g,b,a); vertex(x, y+h, u, v, r,g,b,a); @@ -91,7 +98,7 @@ void Batch2D::rect(float x, float y, float w, float h, } void Batch2D::render() { - mesh->reload(buffer, index / 8); + mesh->reload(buffer, index / VERTEX_SIZE); mesh->draw(GL_TRIANGLES); index = 0; } diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index a2b98e80..b35257bd 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -2,11 +2,12 @@ #include "Texture.h" #include "Batch2D.h" -Font::Font(Texture* texture) : texture(texture) { +Font::Font(std::vector pages) : pages(pages) { } Font::~Font(){ - delete texture; + for (Texture* texture : pages) + delete texture; } int Font::getGlyphWidth(char c) { @@ -26,7 +27,7 @@ int Font::getGlyphWidth(char c) { } -bool Font::isPrintableChar(char c) { +bool Font::isPrintableChar(int c) { switch (c){ case ' ': case '\t': @@ -39,20 +40,33 @@ bool Font::isPrintableChar(char c) { } } +#define RES 16 -void Font::draw(Batch2D* batch, std::string text, int x, int y) { - for (char c : text){ - if (isPrintableChar(c)) - batch->sprite(x, y, 8, 8, 16, c, vec4(1.0f)); - x += getGlyphWidth(c); - } -} - -void Font::drawWithShadow(Batch2D* batch, std::string text, int x, int y) { - for (char c : text){ +void Font::draw(Batch2D* batch, std::wstring text, int x, int y) { + for (unsigned c : text){ if (isPrintableChar(c)){ - batch->sprite(x+1, y+1, 8, 8, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x, y, 8, 8, 16, c, vec4(1.0f)); + batch->texture(pages[c >> 8]); + batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); + } + x += getGlyphWidth(c); + } +} + +void Font::drawWithShadow(Batch2D* batch, std::wstring text, int x, int y) { + for (unsigned c : text){ + if (isPrintableChar(c)){ + batch->texture(pages[c >> 8]); + batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x-1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + batch->sprite(x-1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x-1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); } x += getGlyphWidth(c); } diff --git a/src/graphics/Font.h b/src/graphics/Font.h index f65ba3d7..61976903 100644 --- a/src/graphics/Font.h +++ b/src/graphics/Font.h @@ -2,20 +2,21 @@ #define GRAPHICS_FONT_H_ #include +#include class Texture; class Batch2D; class Font { public: - Texture* texture; - Font(Texture* texture); + std::vector pages; + Font(std::vector pages); ~Font(); int getGlyphWidth(char c); - bool isPrintableChar(char c); - void draw(Batch2D* batch, std::string text, int x, int y); - void drawWithShadow(Batch2D* batch, std::string text, int x, int y); + bool isPrintableChar(int c); + void draw(Batch2D* batch, std::wstring text, int x, int y); + void drawWithShadow(Batch2D* batch, std::wstring text, int x, int y); }; #endif /* GRAPHICS_FONT_H_ */ diff --git a/src/lighting/Lighting.cpp b/src/lighting/Lighting.cpp index 12bca112..b1fe4f80 100644 --- a/src/lighting/Lighting.cpp +++ b/src/lighting/Lighting.cpp @@ -6,6 +6,8 @@ #include "../voxels/voxel.h" #include "../voxels/Block.h" +#include + Lighting::Lighting(Chunks* chunks){ this->chunks = chunks; solverR = new LightSolver(chunks, 0); diff --git a/src/player_control.cpp b/src/player_control.cpp index 6b814fba..b8e5f407 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -6,6 +6,7 @@ #include "physics/Hitbox.h" #include "lighting/Lighting.h" #include "world/Level.h" +#include "voxels/Block.h" #include "voxels/voxel.h" #include "voxels/Chunks.h" #include "window/Camera.h" @@ -175,7 +176,7 @@ void update_interaction(Level* level, LineBatch* lineBatch){ if (vox != nullptr){ lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); - if (Events::jclicked(GLFW_MOUSE_BUTTON_1)){ + if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && Block::blocks[vox->id]->breakable){ int x = (int)iend.x; int y = (int)iend.y; int z = (int)iend.z; diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 4eafd412..d4a986d6 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -104,7 +104,7 @@ Level* load_level(World* world, Player* player) { int initialize(Assets*& assets){ Audio::initialize(); - Window::initialize(WIDTH, HEIGHT, "Window 2.0"); + Window::initialize(WIDTH, HEIGHT, "VoxelEngine-Cpp v.12"); Events::initialize(); assets = new Assets(); @@ -127,7 +127,7 @@ int main() { if (status) return status; std::cout << "-- loading world" << std::endl; - vec3 playerPosition = vec3(-320,200,32); + vec3 playerPosition = vec3(0,150,-10); Camera* camera = new Camera(playerPosition, radians(90.0f)); World* world = new World("world-1", "world/", 42); Player* player = new Player(playerPosition, 4.0f, camera); diff --git a/src/voxels/Block.h b/src/voxels/Block.h index 58010e70..cd66322b 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -14,6 +14,7 @@ public: bool skyLightPassing = false; bool obstacle = true; bool selectable = true; + bool breakable = true; Block(unsigned int id, int texture); }; diff --git a/src/voxels/ChunksLoader.cpp b/src/voxels/ChunksLoader.cpp index 4c4796ad..0b41241d 100644 --- a/src/voxels/ChunksLoader.cpp +++ b/src/voxels/ChunksLoader.cpp @@ -3,6 +3,8 @@ #include "Chunk.h" #include "Chunks.h" +#include "Block.h" +#include "voxel.h" #include "../world/World.h" #include "WorldGenerator.h" #include "../lighting/Lighting.h" @@ -36,6 +38,12 @@ void ChunksLoader::_thread(){ WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world->seed); } + for (size_t i = 0; i < CHUNK_VOL; i++){ + if (Block::blocks[chunk->voxels[i].id] == nullptr){ + std::cout << "corruped block detected at " << i << " of chunk " << chunk->x << "x" << chunk->z << std::endl; + chunk->voxels[i].id = 11; + } + } lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true); } else if (state == RENDER){ diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index a1495004..d7be2a78 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -28,12 +28,16 @@ public: }; float calc_height(fnl_state *noise, int real_x, int real_z){ - const float s = 0.2f; + const float s = 0.18f; float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f); height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f; height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f; height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f; height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f; + height += fnlGetNoise3D(noise, + real_x*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*50, + real_z*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32+4363,real_z*0.1f*s*32, 0.0f)*50, + 0.0f)*0.1f; height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.0625f; // height += fnlGetNoise3D(noise, real_x*s*32,real_z*s*32, 0.0f)*0.03f; height = height * 0.5f + 0.5f; @@ -44,13 +48,17 @@ float calc_height(fnl_state *noise, int real_x, int real_z){ } float calc_height_faster(fnl_state *noise, int real_x, int real_z){ - const float s = 0.2f; + const float s = 0.18f; float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f); height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f; height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f; height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f; height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f; - //height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F; + height += fnlGetNoise3D(noise, + real_x*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*50, + real_z*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32+4363,real_z*0.1f*s*32, 0.0f)*50, + 0.0f)*0.1f; + // height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F; height = height * 0.5f + 0.5f; height *= height; height *= (140.0f)*0.12f/s; diff --git a/src/world_render.h b/src/world_render.h index d50c68f6..fb876138 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -41,7 +41,7 @@ int attrs[] = { 2, 0 //null terminator }; -int uiscale = 2; +int uiscale = 1; LineBatch *lineBatch; Batch2D *batch; @@ -127,14 +127,13 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) // draw debug info Font* font = assets->getFont("normal"); batch->begin(); - batch->texture(font->texture); if (devdata){ - font->drawWithShadow(batch, "chunks: "+std::to_string(chunks->chunksCount), 16, 16); - font->drawWithShadow(batch, std::to_string((int)player->camera->position.x), 10, 30); - font->drawWithShadow(batch, std::to_string((int)player->camera->position.y), 50, 30); - font->drawWithShadow(batch, std::to_string((int)player->camera->position.z), 90, 30); - font->drawWithShadow(batch, "fps:", 16, 42); - font->drawWithShadow(batch, std::to_string(fps), 40, 42); + font->drawWithShadow(batch, L"рандом chunks: "+std::to_wstring(chunks->chunksCount), 16, 16); + font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.x), 10, 30); + font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.y), 50, 30); + font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.z), 90, 30); + font->drawWithShadow(batch, L"fps:", 16, 42); + font->drawWithShadow(batch, std::to_wstring(fps), 40, 42); } batch->render(); @@ -143,8 +142,8 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) batch->texture(blocks); int texid = Block::blocks[player->choosenBlock]->textureFaces[3]; // face-3 is top face of block - batch->sprite(14, 278, 68, 68, 16, texid, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(16, 280, 64, 64, 16, texid, vec4(1.0f)); + batch->sprite(14, Window::height-82, 68, 68, 16, texid, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(16, Window::height-80, 64, 64, 16, texid, vec4(1.0f)); batch->render(); } From 889b2a62b563520c928dbf85e1d214fdc8e67a24 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 15 Jul 2022 16:40:12 +0300 Subject: [PATCH 39/56] 0 font page used instead of missing one --- src/graphics/Font.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index b35257bd..1e627538 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -55,7 +55,11 @@ void Font::draw(Batch2D* batch, std::wstring text, int x, int y) { void Font::drawWithShadow(Batch2D* batch, std::wstring text, int x, int y) { for (unsigned c : text){ if (isPrintableChar(c)){ - batch->texture(pages[c >> 8]); + Texture* texture = pages[c >> 8]; + if (texture == nullptr){ + texture = pages[0]; + } + batch->texture(texture); batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); batch->sprite(x-1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); From fa4538c124208ec8869e2efa33507abda599d798 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 15 Jul 2022 16:54:35 +0300 Subject: [PATCH 40/56] font draw improvements --- src/graphics/Font.cpp | 82 ++++++++++++++++++++++++++++++------------- src/graphics/Font.h | 2 +- src/world_render.h | 12 +++---- 3 files changed, 64 insertions(+), 32 deletions(-) diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index 1e627538..b501c206 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -43,35 +43,67 @@ bool Font::isPrintableChar(int c) { #define RES 16 void Font::draw(Batch2D* batch, std::wstring text, int x, int y) { - for (unsigned c : text){ - if (isPrintableChar(c)){ - batch->texture(pages[c >> 8]); - batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); + int page = 0; + int next = 10000; + int init_x = x; + do { + for (unsigned c : text){ + if (isPrintableChar(c)){ + int charpage = c >> 8; + if (charpage == page){ + Texture* texture = pages[charpage]; + if (texture == nullptr){ + texture = pages[0]; + } + batch->texture(pages[charpage]); + batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); + } + else if (charpage > page && charpage < next){ + next = charpage; + } + } + x += getGlyphWidth(c); } - x += getGlyphWidth(c); - } + page = next; + next = 10000; + x = init_x; + } while (page < 10000); } -void Font::drawWithShadow(Batch2D* batch, std::wstring text, int x, int y) { - for (unsigned c : text){ - if (isPrintableChar(c)){ - Texture* texture = pages[c >> 8]; - if (texture == nullptr){ - texture = pages[0]; - } - batch->texture(texture); - batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x-1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); +void Font::drawWithOutline(Batch2D* batch, std::wstring text, int x, int y) { + int page = 0; + int next = 10000; + int init_x = x; + do { + for (unsigned c : text){ + if (isPrintableChar(c)){ + int charpage = c >> 8; + if (charpage == page){ + Texture* texture = pages[charpage]; + if (texture == nullptr){ + texture = pages[0]; + } + batch->texture(pages[charpage]); + batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x-1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x-1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x-1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x-1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x-1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); + batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); + } + else if (charpage > page && charpage < next){ + next = charpage; + } + } + x += getGlyphWidth(c); } - x += getGlyphWidth(c); - } + page = next; + next = 10000; + x = init_x; + } while (page < 10000); } diff --git a/src/graphics/Font.h b/src/graphics/Font.h index 61976903..c2f15b87 100644 --- a/src/graphics/Font.h +++ b/src/graphics/Font.h @@ -16,7 +16,7 @@ public: int getGlyphWidth(char c); bool isPrintableChar(int c); void draw(Batch2D* batch, std::wstring text, int x, int y); - void drawWithShadow(Batch2D* batch, std::wstring text, int x, int y); + void drawWithOutline(Batch2D* batch, std::wstring text, int x, int y); }; #endif /* GRAPHICS_FONT_H_ */ diff --git a/src/world_render.h b/src/world_render.h index fb876138..bf304540 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -128,12 +128,12 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) Font* font = assets->getFont("normal"); batch->begin(); if (devdata){ - font->drawWithShadow(batch, L"рандом chunks: "+std::to_wstring(chunks->chunksCount), 16, 16); - font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.x), 10, 30); - font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.y), 50, 30); - font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.z), 90, 30); - font->drawWithShadow(batch, L"fps:", 16, 42); - font->drawWithShadow(batch, std::to_wstring(fps), 40, 42); + font->drawWithOutline(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16); + font->drawWithOutline(batch, std::to_wstring((int)player->camera->position.x), 10, 30); + font->drawWithOutline(batch, std::to_wstring((int)player->camera->position.y), 50, 30); + font->drawWithOutline(batch, std::to_wstring((int)player->camera->position.z), 90, 30); + font->drawWithOutline(batch, L"fps:", 16, 42); + font->drawWithOutline(batch, std::to_wstring(fps), 40, 42); } batch->render(); From c0f5e5f4fc19b966d4106a7e2b73715e58b4a654 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Jul 2022 00:31:04 +0300 Subject: [PATCH 41/56] Added 'style' font render argument --- src/graphics/Font.cpp | 49 +++++++++++++------------------------------ src/graphics/Font.h | 6 +++++- src/world_render.h | 12 +++++------ 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index b501c206..96d9c30e 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -43,34 +43,10 @@ bool Font::isPrintableChar(int c) { #define RES 16 void Font::draw(Batch2D* batch, std::wstring text, int x, int y) { - int page = 0; - int next = 10000; - int init_x = x; - do { - for (unsigned c : text){ - if (isPrintableChar(c)){ - int charpage = c >> 8; - if (charpage == page){ - Texture* texture = pages[charpage]; - if (texture == nullptr){ - texture = pages[0]; - } - batch->texture(pages[charpage]); - batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); - } - else if (charpage > page && charpage < next){ - next = charpage; - } - } - x += getGlyphWidth(c); - } - page = next; - next = 10000; - x = init_x; - } while (page < 10000); + draw(batch, text, x, y, STYLE_NONE); } -void Font::drawWithOutline(Batch2D* batch, std::wstring text, int x, int y) { +void Font::draw(Batch2D* batch, std::wstring text, int x, int y, int style) { int page = 0; int next = 10000; int init_x = x; @@ -84,15 +60,20 @@ void Font::drawWithOutline(Batch2D* batch, std::wstring text, int x, int y) { texture = pages[0]; } batch->texture(pages[charpage]); - batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x-1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x-1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x-1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + switch (style){ + case STYLE_SHADOW: + batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + break; + case STYLE_OUTLINE: + for (int oy = -1; oy <= 1; oy++){ + for (int ox = -1; ox <= 1; ox++){ + if (ox || oy) + batch->sprite(x+ox, y+oy, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + } + } + break; + } batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); } diff --git a/src/graphics/Font.h b/src/graphics/Font.h index c2f15b87..db1fdcda 100644 --- a/src/graphics/Font.h +++ b/src/graphics/Font.h @@ -7,6 +7,10 @@ class Texture; class Batch2D; +#define STYLE_NONE 0 +#define STYLE_SHADOW 1 +#define STYLE_OUTLINE 2 + class Font { public: std::vector pages; @@ -16,7 +20,7 @@ public: int getGlyphWidth(char c); bool isPrintableChar(int c); void draw(Batch2D* batch, std::wstring text, int x, int y); - void drawWithOutline(Batch2D* batch, std::wstring text, int x, int y); + void draw(Batch2D* batch, std::wstring text, int x, int y, int style); }; #endif /* GRAPHICS_FONT_H_ */ diff --git a/src/world_render.h b/src/world_render.h index bf304540..c3c50a45 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -128,12 +128,12 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) Font* font = assets->getFont("normal"); batch->begin(); if (devdata){ - font->drawWithOutline(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16); - font->drawWithOutline(batch, std::to_wstring((int)player->camera->position.x), 10, 30); - font->drawWithOutline(batch, std::to_wstring((int)player->camera->position.y), 50, 30); - font->drawWithOutline(batch, std::to_wstring((int)player->camera->position.z), 90, 30); - font->drawWithOutline(batch, L"fps:", 16, 42); - font->drawWithOutline(batch, std::to_wstring(fps), 40, 42); + font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.y), 50, 30, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.z), 90, 30, STYLE_OUTLINE); + font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE); + font->draw(batch, std::to_wstring(fps), 40, 42, STYLE_OUTLINE); } batch->render(); From 9a92d7a20cd14b0a33ebcb79a9985c385d87a196 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 18 Jul 2022 02:47:50 +0300 Subject: [PATCH 42/56] Erreur stupide --- src/graphics/Batch2D.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index 45a00579..a96aa4fd 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -6,9 +6,7 @@ #define VERTEX_SIZE 8 -Batch2D::Batch2D(size_t capacity) : capacity(capacity), - offset(0), - color(1.0f, 1.0f, 1.0f, 1.0f){ +Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){ const int attrs[] = { 2, 2, 4, 0 //null terminator }; @@ -26,7 +24,7 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), Batch2D::~Batch2D(){ delete blank; - delete buffer; + delete[] buffer; delete mesh; } From 539c5f90bd82d498cd40f3520868ca839a76c747 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Wed, 10 Aug 2022 20:18:04 +0300 Subject: [PATCH 43/56] add many feature, but have many draw bugs --- res/block.png | Bin 264603 -> 262913 bytes res/sprite.png | Bin 0 -> 262913 bytes src/declarations.h | 20 +- src/graphics/VoxelRenderer.cpp | 357 ++++++++++++++++++++++++--------- src/player_control.cpp | 12 +- src/voxels/Block.h | 1 + src/voxels/WorldGenerator.cpp | 102 ++++++---- src/world_render.h | 9 +- 8 files changed, 355 insertions(+), 146 deletions(-) create mode 100644 res/sprite.png diff --git a/res/block.png b/res/block.png index b89677861bda446d15759012688719499c6ded2b..eb0535cd0539b6a7d1aa8207c77e3cac692737ce 100644 GIT binary patch delta 1840 zcmb7EU1%It6#i!J{AD)Toy}%#vq?$w)21PmqN%2(wWhX#6l$pmA`0S*6a_$+i8Supy5qv4Mv<57;h>r>iTCo(`P@0sso3?4PKaZ)F`|wqkqm1&*rzxm3Mw74stYm!ZnWr!0WhJY1sHPx6Sj@SZn^HhnH>v({iF#qrgcxyh8B*9P>tX6xAv-*>ots)XC+XTG z7#*45vTy!ZpfEXh^W#F|U1Ot^HJNNSZr|upF~TXBg|y-1`+d+IHoQ-W_ z8+xbf8e+n=3s<@#225e$8j($1Jbu)sd_>N(y^QB>b0@Fap(;%O~ir+v_TE$8b zK`0GWs76KpfV8c{QNO&C1k1T&~&VLRT3d!k^TDL9<&zVnRXLiMWJF8YG8?$4o8sXz#UAP8VkH#JRz@B7GRvshkUmbOG9L4ms53DY!DEEe5wyK?TTJv=ou z;9z+rfUc?V{5o1J>IPL`s?^ZCtqqI!J!xxC8CWAxD(z;1s$Y7vhI$xbXlO|0VSdl^ zVAIaCj#8&zE-p%2I!&FmEU2mq)>9}H=;VZZH;-q0){Dgme6`|{uQfj$Y-2Fl z>DV?O#REs^!tj~q;P?$-P>Rkce|&#aDP{A`sxEmj5;{FJ&uLeJ^r6e!XGBt&b53PU zS2ede^S=&7tCbX-)*=S>-%#e1Q~wCMTAdw#T-_(rNA)Ez;`htFQS8lja~#L8C%yfw zjBl|Na1^2bVvcMVd--#^KLNy6n#@p7Ojz1O0$po@n1-(kR!;+AL5>_qz$QpFJGVZq zlflfgq4$!|hIaQnp3M)saYZY1JJOC7BRrvvzun2Y<~e1rXmJc$JQN)#KIneJ_=%$zUVdl#U&vBqasU7T delta 2617 zcmbtTc{tQ-8-8cUG%<55S;tborYMEPpvg($OhS<@Dd7~^EBho-I4OqY$da;@N*YU9 zQYXvFmL!!z))Coej4?B2=KJyWeb@Q_d*AE5-s}Fo@AKUEb3gAdE>R|jE^|YRhE9z< z;vD91;(~fmNTAPYe{c1$h#+ru@9@(;0EG9?WLc*hkk%(~W0OtbaLJ@my+1iP{xSz| zymHue`-8~rS^42Sq=fa{_oV10nm9DC@mWY_c(3W1GQ;50?{AW~r^UJpgr6NuxW{;Z z3vNYsr8BdL=7X07WeXjQd7VI7e7+#luXLrdAl7`mEVyE*rJcEpr*M7bwcUj1bp4$2 zr$a|qmTxmgWZ0p;ejjaOr=skLcj^ak?Y5#u=$3u$Y7OUp9C)V1F(AIH?4ia-+0b=1 zsoJ~rjQ<^LRzh{}t!J=1A|_Z$DI?FvT^!O154|f4d79aS_2 z&LQ~MU(R;X(|#B}@V2$Rv7yl*tgD_xC=~xK7dsw(;zmw$NMkliJ;XfxR5_CNwedJe z!F%@|43+UbG}_su$9wgNRey0C)gX^w{pn*J%%N#8QQv{0?nu&hOlSVk9NY1-WHe&i z^$8gAoe#dOw!I_6npnEyhv=^ z=ggBgU5mHqj20aWy6N6Tv8y>nW+e?skBMH++?f@V0(ib-dDsCl;yKfTiwdEQETPU! zPYLSJ-IA$xOEkKF-!7J>PpMrpbt?BV+T+%6+ps3Ddg(-Blx~!K?BsXRzyNojW`0#G z>4lT3d}waNUE3`Q#%D*B9A()$bFrxhKgP%|?!POcQCLDKakH&6^K!r6e>QzFb4P7k zare{T!^#Hly(-YK@TotVWtQO_`eP?wF2p8lU>|X);Rz=o_*CDEQ?$}!!zs1=!1 z+z!tN++1=EfoUBYs1LNV9Et3jv2XD2ve`{Z-M{tKSXSXM&4YBlk-#j^iz{9XGBWMK zyNo6eJUxA-+jf)o%THbcmvc79*#^o{){6ICx;>m3zkQiMFrj!>`w}@JQLhSS*)QtG zmT>5wh2GdXTDaW}WN)$4WE%n?|yhj!ldx4_y8TN)N3LEMsE;8-!?6_QX-8OzO;r!LyU{AE;wFAO?g{mza3+lSPW zeB62y^a-}R`gOjZS2*G${l-sQdOEw$A=jN`koeHMrJ}0qE3S~uDX`re*wtRhkSo>2 zr0Fy`s{Y6!ja1HiZKN$DV&|`HGl_O!K2nOfjN*^eJXD0={atYhWLAOuhHy%_w=C!`(T;k@Y zIKf$qqPm_RZU3seRa)A!^W@g2fmjV)|GBZ#wue_f3Ny9^vD6J!#~*mlz>9pf8p%5t zekoNM#TA<=HOOD(m1&2Ye#glsHhicy3v1hIZI~JmrswNwY(QiTzRvUYxc|E1#aqJhjVIn5;hOp9b3~3ec`yYG+r_Jbmdi-Rs@&U5R_UU-h zn{4N}i>9RmYOICmO|it~lDC1s4kf<8#VGT4EuNkH(%op(Bu?|KVg|<9w0UDfyNw3f#rFkOhFYxQ=Pb4Mi-;9w)3v51MFYv+S zVwe~#%q{_pBm#W>!U9N`$R7YC9L#a}kO)W! zbnu~v1HKI{0^Xtka2A&V3I&6F6$1So1fZm(wAKp*B$~(Lt@({aA_14n1#)t7t3?4c zk+fx=5TGDl4tE8Jpq{N3&w}_gRB>xLBqb1l zAdLoi84Q3!Ij~Ui+~pO(<_G|ZL|V-S=|TYxhqI<(m6OF{0ZmQKwRkD$o#63!Kp+qx z-of-3<9FlfPR d0tyhcld`{QjdXe`wz#f_TU*-hdu-u(>E9}Dsl@;Q diff --git a/res/sprite.png b/res/sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..f9e20e0dfd52089d846fa19d75b1a4185845f57f GIT binary patch literal 262913 zcmeI*!D|#(7y$5ZOO%)*5_+iVY3Rj2ppfFBhm{eXi(1)(MGu9dy-G`=^x%&6g2Cl51`;o8o2YCfU{9owxHFNH#Nh@6Gr9K6s}uFAuL> zxpaErlZA*lU0lwuN3`~TY{mS^{f}GUJ-f62aq8~nufC7?@T2}$D}MR)Y(y4C-tPR^ zimdE)TPrIod;0@Ny4Kg%V|8`4|5_IT0tpJtZEbDE?(Xi;q0i6H4?V{O0tD(MFxL-f zXJ@DXalilVxYyFsQunxHjUzyyo&q1#Gb~XNATS958^9!#y@Nna1#AE{EsU@TOhUj0 zFbQSvAW%~Q8$eA9BP;@A5%}iX$sgYK0#sgLGpK;LCD0@R8$gq)Emr~+0UJOC#4Uj) z3D^LdRBgEus0i2qDj;qNG)ce)(4=b1l|V({;O_$Z&z6^$hwk&=-rlY(=avA0lmreo zfW^hd*x1+@I_~~F7XbnZ2;4sR$8Q6A0TPH_hy(}_AV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!8A1;EOXauj&P;s<-rS)Ajdu0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBly@V*7c)(eo8z3%%C)_Md85FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7e?kplOgeEwxb7De9f968tk0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK%n*lV>=h1_L&Qi009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF%%*@|fZ438tOyVwK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZpt%Cm z?FGonUbngSGABTQ009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RrO?`03%d=OeNx z@^)t&>sylm0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&Un5@8b&jpxluHHs~ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjY?AfOkZ300OO0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&&Ng#nr4rL>5Kf?!41NCKDh)fB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009EE5J=!$fLb^Sf&c*m1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2&5vQ7a)~NiIV^U0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PB~YU{-nova;7b zUdBcdAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;&*%tU`^K}uCMUl5Vvz@8z z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+Kr;kpOm&+@N`EQ-9{NhfNN5+Fc;009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0Rn>roC`2W#&ZG$2oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5Fn7IfL?$!>n3Uf1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 u2oNAJNZ`L-fYxXJN5CMV|9jqw*xP&b^T%tKZa#kAA5dJplE1j{^@BGJbCYEN literal 0 HcmV?d00001 diff --git a/src/declarations.h b/src/declarations.h index 8890b849..086e2b91 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -65,6 +65,7 @@ int initialize_assets(Assets* assets) { LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui"); LOAD_TEXTURE("res/block.png", "block"); + LOAD_TEXTURE("res/sprite.png", "sprite"); LOAD_FONT("res/font", "normal"); return 0; @@ -82,13 +83,14 @@ void setup_definitions() { block->skyLightPassing = true; block->obstacle = false; block->selectable = false; + block->type = 0; Block::blocks[block->id] = block; // DIRT 1 block = new Block(1,2); Block::blocks[block->id] = block; - // GRASS 2 + // GRASS BLOCK2 block = new Block(2,4); block->textureFaces[2] = 2; block->textureFaces[3] = 1; @@ -142,6 +144,22 @@ void setup_definitions() { block = new Block(11,13); block->breakable = false; Block::blocks[block->id] = block; + + // GRASS 12 + block = new Block(12,14); + block->drawGroup = 5; + block->lightPassing = true; + block->obstacle = false; + block->type = 2; + Block::blocks[block->id] = block; + + // FLOWER 13 + block = new Block(13,16); + block->drawGroup = 5; + block->lightPassing = true; + block->obstacle = false; + block->type = 2; + Block::blocks[block->id] = block; } #endif // DECLARATIONS_H diff --git a/src/graphics/VoxelRenderer.cpp b/src/graphics/VoxelRenderer.cpp index 5b5a7537..ce44e1f4 100644 --- a/src/graphics/VoxelRenderer.cpp +++ b/src/graphics/VoxelRenderer.cpp @@ -1,6 +1,7 @@ #include "VoxelRenderer.h" #include +#include #include "Mesh.h" #include "../voxels/Chunk.h" #include "../voxels/voxel.h" @@ -65,25 +66,25 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const float lb = LIGHT(x,y+1,z, 2) / 15.0f; float ls = LIGHT(x,y+1,z, 3) / 15.0f; - float lr0 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 5.0f / 15.0f; - float lr1 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 5.0f / 15.0f; - float lr2 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 5.0f / 15.0f; - float lr3 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 5.0f / 15.0f; + float lr0 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 75.0f; + float lr1 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 75.0f; + float lr2 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 75.0f; + float lr3 = (LIGHT(x+1,y+1,z,0) + lr*30 + LIGHT(x+1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 75.0f; - float lg0 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 5.0f / 15.0f; - float lg1 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 5.0f / 15.0f; - float lg2 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 5.0f / 15.0f; - float lg3 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 5.0f / 15.0f; + float lg0 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 75.0f; + float lg1 = (LIGHT(x-1,y+1,z,1) + lg*30 + LIGHT(x-1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 75.0f; + float lg2 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z+1,1) + LIGHT(x,y+1,z+1,1)) / 75.0f; + float lg3 = (LIGHT(x+1,y+1,z,1) + lg*30 + LIGHT(x+1,y+1,z-1,1) + LIGHT(x,y+1,z-1,1)) / 75.0f; - float lb0 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 5.0f / 15.0f; - float lb1 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 5.0f / 15.0f; - float lb2 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 5.0f / 15.0f; - float lb3 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 5.0f / 15.0f; + float lb0 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 75.0f; + float lb1 = (LIGHT(x-1,y+1,z,2) + lb*30 + LIGHT(x-1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 75.0f; + float lb2 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z+1,2) + LIGHT(x,y+1,z+1,2)) / 75.0f; + float lb3 = (LIGHT(x+1,y+1,z,2) + lb*30 + LIGHT(x+1,y+1,z-1,2) + LIGHT(x,y+1,z-1,2)) / 75.0f; - float ls0 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 5.0f / 15.0f; - float ls1 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 5.0f / 15.0f; - float ls2 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 5.0f / 15.0f; - float ls3 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 5.0f / 15.0f; + float ls0 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 75.0f; + float ls1 = (LIGHT(x-1,y+1,z,3) + ls*30 + LIGHT(x-1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 75.0f; + float ls2 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z+1,3) + LIGHT(x,y+1,z+1,3)) / 75.0f; + float ls3 = (LIGHT(x+1,y+1,z,3) + ls*30 + LIGHT(x+1,y+1,z-1,3) + LIGHT(x,y+1,z-1,3)) / 75.0f; VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, lr0, lg0, lb0, ls0); VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1, lg1, lb1, ls1); @@ -103,25 +104,25 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const float lb = LIGHT(x,y-1,z, 2) / 15.0f; float ls = LIGHT(x,y-1,z, 3) / 15.0f; - float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 5.0f / 15.0f; - float lr1 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 5.0f / 15.0f; - float lr2 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 5.0f / 15.0f; - float lr3 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 5.0f / 15.0f; + float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 75.0f; + float lr1 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 75.0f; + float lr2 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 75.0f; + float lr3 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 75.0f; - float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 5.0f / 15.0f; - float lg1 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 5.0f / 15.0f; - float lg2 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 5.0f / 15.0f; - float lg3 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 5.0f / 15.0f; + float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 75.0f; + float lg1 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 75.0f; + float lg2 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y-1,z,1) + LIGHT(x,y-1,z+1,1)) / 75.0f; + float lg3 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y-1,z,1) + LIGHT(x,y-1,z-1,1)) / 75.0f; - float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 5.0f / 15.0f; - float lb1 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 5.0f / 15.0f; - float lb2 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 5.0f / 15.0f; - float lb3 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 5.0f / 15.0f; + float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 75.0f; + float lb1 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 75.0f; + float lb2 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y-1,z,2) + LIGHT(x,y-1,z+1,2)) / 75.0f; + float lb3 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y-1,z,2) + LIGHT(x,y-1,z-1,2)) / 75.0f; - float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 5.0f / 15.0f; - float ls1 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 5.0f / 15.0f; - float ls2 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 5.0f / 15.0f; - float ls3 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 5.0f / 15.0f; + float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 75.0f; + float ls1 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 75.0f; + float ls2 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y-1,z,3) + LIGHT(x,y-1,z+1,3)) / 75.0f; + float ls3 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y-1,z,3) + LIGHT(x,y-1,z-1,3)) / 75.0f; VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0); VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1); @@ -142,25 +143,25 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const float lb = LIGHT(x+1,y,z, 2) / 15.0f; float ls = LIGHT(x+1,y,z, 3) / 15.0f; - float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 5.0f / 15.0f; - float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 5.0f / 15.0f; - float lr2 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 5.0f / 15.0f; - float lr3 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 5.0f / 15.0f; + float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + float lr2 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + float lr3 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - float lg0 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y-1,z,1)) / 5.0f / 15.0f; - float lg1 = (LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y+1,z,1)) / 5.0f / 15.0f; - float lg2 = (LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y+1,z,1)) / 5.0f / 15.0f; - float lg3 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y-1,z,1)) / 5.0f / 15.0f; + float lg0 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y-1,z,1)) / 75.0f; + float lg1 = (LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y+1,z,1)) / 75.0f; + float lg2 = (LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y+1,z,1)) / 75.0f; + float lg3 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y-1,z,1)) / 75.0f; - float lb0 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y-1,z,2)) / 5.0f / 15.0f; - float lb1 = (LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y+1,z,2)) / 5.0f / 15.0f; - float lb2 = (LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y+1,z,2)) / 5.0f / 15.0f; - float lb3 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y-1,z,2)) / 5.0f / 15.0f; + float lb0 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y-1,z,2)) / 75.0f; + float lb1 = (LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y+1,z,2)) / 75.0f; + float lb2 = (LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y+1,z,2)) / 75.0f; + float lb3 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y-1,z,2)) / 75.0f; - float ls0 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y-1,z,3)) / 5.0f / 15.0f; - float ls1 = (LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y+1,z,3)) / 5.0f / 15.0f; - float ls2 = (LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y+1,z,3)) / 5.0f / 15.0f; - float ls3 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y-1,z,3)) / 5.0f / 15.0f; + float ls0 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y-1,z,3)) / 75.0f; + float ls1 = (LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y+1,z,3)) / 75.0f; + float ls2 = (LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y+1,z,3)) / 75.0f; + float ls3 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y-1,z,3)) / 75.0f; VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0); VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u2,v2, lr1,lg1,lb1,ls1); @@ -180,25 +181,25 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const float lb = LIGHT(x-1,y,z, 2) / 15.0f; float ls = LIGHT(x-1,y,z, 3) / 15.0f; - float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y-1,z,0)) / 5.0f / 15.0f; - float lr1 = (LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y+1,z,0)) / 5.0f / 15.0f; - float lr2 = (LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y+1,z,0)) / 5.0f / 15.0f; - float lr3 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y-1,z,0)) / 5.0f / 15.0f; + float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y-1,z,0)) / 75.0f; + float lr1 = (LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y+1,z,0)) / 75.0f; + float lr2 = (LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y+1,z,0)) / 75.0f; + float lr3 = (LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y-1,z,0)) / 75.0f; - float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y-1,z,1)) / 5.0f / 15.0f; - float lg1 = (LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y+1,z,1)) / 5.0f / 15.0f; - float lg2 = (LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y+1,z,1)) / 5.0f / 15.0f; - float lg3 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y-1,z,1)) / 5.0f / 15.0f; + float lg0 = (LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y-1,z,1)) / 75.0f; + float lg1 = (LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y+1,z,1)) / 75.0f; + float lg2 = (LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x-1,y,z-1,1) + LIGHT(x-1,y+1,z,1)) / 75.0f; + float lg3 = (LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x-1,y,z+1,1) + LIGHT(x-1,y-1,z,1)) / 75.0f; - float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y-1,z,2)) / 5.0f / 15.0f; - float lb1 = (LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y+1,z,2)) / 5.0f / 15.0f; - float lb2 = (LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y+1,z,2)) / 5.0f / 15.0f; - float lb3 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y-1,z,2)) / 5.0f / 15.0f; + float lb0 = (LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y-1,z,2)) / 75.0f; + float lb1 = (LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y+1,z,2)) / 75.0f; + float lb2 = (LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x-1,y,z-1,2) + LIGHT(x-1,y+1,z,2)) / 75.0f; + float lb3 = (LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x-1,y,z+1,2) + LIGHT(x-1,y-1,z,2)) / 75.0f; - float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y-1,z,3)) / 5.0f / 15.0f; - float ls1 = (LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y+1,z,3)) / 5.0f / 15.0f; - float ls2 = (LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y+1,z,3)) / 5.0f / 15.0f; - float ls3 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y-1,z,3)) / 5.0f / 15.0f; + float ls0 = (LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y-1,z,3)) / 75.0f; + float ls1 = (LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y+1,z,3)) / 75.0f; + float ls2 = (LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x-1,y,z-1,3) + LIGHT(x-1,y+1,z,3)) / 75.0f; + float ls3 = (LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x-1,y,z+1,3) + LIGHT(x-1,y-1,z,3)) / 75.0f; VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, lr0,lg0,lb0,ls0); VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1); @@ -219,25 +220,25 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const float lb = LIGHT(x,y,z+1, 2) / 15.0f; float ls = LIGHT(x,y,z+1, 3) / 15.0f; - float lr0 = l*(LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 5.0f / 15.0f; - float lr1 = l*(LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 5.0f / 15.0f; - float lr2 = l*(LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 5.0f / 15.0f; - float lr3 = l*(LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 5.0f / 15.0f; + float lr0 = l*(LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 75.0f; + float lr1 = l*(LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 75.0f; + float lr2 = l*(LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 75.0f; + float lr3 = l*(LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 75.0f; - float lg0 = l*(LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 5.0f / 15.0f; - float lg1 = l*(LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 5.0f / 15.0f; - float lg2 = l*(LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 5.0f / 15.0f; - float lg3 = l*(LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 5.0f / 15.0f; + float lg0 = l*(LIGHT(x-1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 75.0f; + float lg1 = l*(LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 75.0f; + float lg2 = l*(LIGHT(x-1,y+1,z+1,1) + lg*30 + LIGHT(x,y+1,z+1,1) + LIGHT(x-1,y,z+1,1)) / 75.0f; + float lg3 = l*(LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x,y-1,z+1,1) + LIGHT(x+1,y,z+1,1)) / 75.0f; - float lb0 = l*(LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 5.0f / 15.0f; - float lb1 = l*(LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 5.0f / 15.0f; - float lb2 = l*(LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 5.0f / 15.0f; - float lb3 = l*(LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 5.0f / 15.0f; + float lb0 = l*(LIGHT(x-1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 75.0f; + float lb1 = l*(LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 75.0f; + float lb2 = l*(LIGHT(x-1,y+1,z+1,2) + lb*30 + LIGHT(x,y+1,z+1,2) + LIGHT(x-1,y,z+1,2)) / 75.0f; + float lb3 = l*(LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x,y-1,z+1,2) + LIGHT(x+1,y,z+1,2)) / 75.0f; - float ls0 = l*(LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 5.0f / 15.0f; - float ls1 = l*(LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 5.0f / 15.0f; - float ls2 = l*(LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 5.0f / 15.0f; - float ls3 = l*(LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 5.0f / 15.0f; + float ls0 = l*(LIGHT(x-1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 75.0f; + float ls1 = l*(LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 75.0f; + float ls2 = l*(LIGHT(x-1,y+1,z+1,3) + ls*30 + LIGHT(x,y+1,z+1,3) + LIGHT(x-1,y,z+1,3)) / 75.0f; + float ls3 = l*(LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x,y-1,z+1,3) + LIGHT(x+1,y,z+1,3)) / 75.0f; VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, lr0,lg0,lb0,ls0); VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, lr1,lg1,lb1,ls1); @@ -257,25 +258,25 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const float lb = LIGHT(x,y,z-1, 2) / 15.0f; float ls = LIGHT(x,y,z-1, 3) / 15.0f; - float lr0 = l*(LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 5.0f / 15.0f; - float lr1 = l*(LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 5.0f / 15.0f; - float lr2 = l*(LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 5.0f / 15.0f; - float lr3 = l*(LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 5.0f / 15.0f; + float lr0 = l*(LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 75.0f; + float lr1 = l*(LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 75.0f; + float lr2 = l*(LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 75.0f; + float lr3 = l*(LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x+1,y,z-1,0)) / 75.0f; - float lg0 = l*(LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 5.0f / 15.0f; - float lg1 = l*(LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 5.0f / 15.0f; - float lg2 = l*(LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 5.0f / 15.0f; - float lg3 = l*(LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 5.0f / 15.0f; + float lg0 = l*(LIGHT(x-1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 75.0f; + float lg1 = l*(LIGHT(x-1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x-1,y,z-1,1)) / 75.0f; + float lg2 = l*(LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x,y+1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 75.0f; + float lg3 = l*(LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x,y-1,z-1,1) + LIGHT(x+1,y,z-1,1)) / 75.0f; - float lb0 = l*(LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 5.0f / 15.0f; - float lb1 = l*(LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 5.0f / 15.0f; - float lb2 = l*(LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 5.0f / 15.0f; - float lb3 = l*(LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 5.0f / 15.0f; + float lb0 = l*(LIGHT(x-1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 75.0f; + float lb1 = l*(LIGHT(x-1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x-1,y,z-1,2)) / 75.0f; + float lb2 = l*(LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x,y+1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 75.0f; + float lb3 = l*(LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x,y-1,z-1,2) + LIGHT(x+1,y,z-1,2)) / 75.0f; - float ls0 = l*(LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 5.0f / 15.0f; - float ls1 = l*(LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 5.0f / 15.0f; - float ls2 = l*(LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 5.0f / 15.0f; - float ls3 = l*(LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 5.0f / 15.0f; + float ls0 = l*(LIGHT(x-1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 75.0f; + float ls1 = l*(LIGHT(x-1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x-1,y,z-1,3)) / 75.0f; + float ls2 = l*(LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x,y+1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 75.0f; + float ls3 = l*(LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x,y-1,z-1,3) + LIGHT(x+1,y,z-1,3)) / 75.0f; VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, lr0,lg0,lb0,ls0); VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v2, lr1,lg1,lb1,ls1); @@ -287,6 +288,119 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const } } + + + + +inline void _renderXBlock(std::vector& buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){ + Block* block = Block::blocks[vox.id]; + + int rand = ((x * z + y) xor (z * y - x)) * (z + y); + + float xs = (float)(char)rand / 512; + float zs = (float)(char)(rand >> 8) / 512; + + if (block->type != 2){ + return; + } + + float l; + float uvsize = 1.0f/16.0f; + + float lr = LIGHT(x,y,z, 0) / 15.0f; + float lg = LIGHT(x,y,z, 1) / 15.0f; + float lb = LIGHT(x,y,z, 2) / 15.0f; + float ls = LIGHT(x,y,z, 3) / 15.0f; + + float lr0 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + float lr1 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr2 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr3 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + float lr4 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + float lr5 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr6 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr7 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + + float lg0 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + float lg1 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg2 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg3 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + float lg4 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + float lg5 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg6 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg7 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + + float lb0 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + float lb1 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb2 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb3 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + float lb4 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + float lb5 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb6 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb7 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + + float ls0 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + float ls1 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls2 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls3 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + float ls4 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + float ls5 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls6 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls7 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + + + l = 0.95f; + + {SETUP_UV(block->textureFaces[1]); + + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr1,lg1,lb1,ls1); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); + + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); + VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr3,lg3,lb3,ls3);} + + + l = 0.85f; + + {SETUP_UV(block->textureFaces[0]); + + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1); + VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); + + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr3,lg3,lb3,ls3); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);} + + + l = 0.9f; + + {SETUP_UV(block->textureFaces[5]); + + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5); + VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); + + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr7,lg7,lb7,ls7); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);} + + + l = 0.8f; + + {SETUP_UV(block->textureFaces[4]); + + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr5,lg5,lb5,ls5); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); + + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); + VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr7,lg7,lb7,ls7);} +} + const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& size){ buffer.clear(); size_t index = 0; @@ -294,7 +408,7 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; - if (vox.id == 9 || vox.id == 4) + if (vox.id == 9 || vox.id == 4 || vox.id == 12 || vox.id == 13) continue; _renderBlock(buffer, x, y, z, chunks, vox, index); } @@ -312,6 +426,17 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s } } + for (int y = 0; y < CHUNK_H; y++){ + for (int z = 0; z < CHUNK_D; z++){ + for (int x = 0; x < CHUNK_W; x++){ + voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; + if (vox.id != 12 && vox.id != 13) + continue; + _renderXBlock(buffer, x, y, z, chunks, vox, index); + } + } + } + for (int y = 0; y < CHUNK_H; y++){ for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ @@ -325,3 +450,41 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s size = buffer.size(); return &buffer[0]; } + + + + // float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + // float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lr2 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lr3 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + // float lr4 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + // float lr5 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lr6 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lr7 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + + // float lg0 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y-1,z,1)) / 75.0f; + // float lg1 = (LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y+1,z,1)) / 75.0f; + // float lg2 = (LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y+1,z,1)) / 75.0f; + // float lg3 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y-1,z,1)) / 75.0f; + // float lg4 = (LIGHT(x+1,y-1,z-1,0) + lg*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + // float lg5 = (LIGHT(x+1,y+1,z-1,0) + lg*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lg6 = (LIGHT(x+1,y+1,z+1,0) + lg*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lg7 = (LIGHT(x+1,y-1,z+1,0) + lg*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + + // float lb0 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y-1,z,2)) / 75.0f; + // float lb1 = (LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y+1,z,2)) / 75.0f; + // float lb2 = (LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y+1,z,2)) / 75.0f; + // float lb3 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y-1,z,2)) / 75.0f; + // float lb4 = (LIGHT(x+1,y-1,z-1,0) + lb*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + // float lb5 = (LIGHT(x+1,y+1,z-1,0) + lb*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lb6 = (LIGHT(x+1,y+1,z+1,0) + lb*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float lb7 = (LIGHT(x+1,y-1,z+1,0) + lb*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + + // float ls0 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y-1,z,3)) / 75.0f; + // float ls1 = (LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y+1,z,3)) / 75.0f; + // float ls2 = (LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y+1,z,3)) / 75.0f; + // float ls3 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y-1,z,3)) / 75.0f; + // float ls4 = (LIGHT(x+1,y-1,z-1,0) + ls*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; + // float ls5 = (LIGHT(x+1,y+1,z-1,0) + ls*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float ls6 = (LIGHT(x+1,y+1,z+1,0) + ls*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; + // float ls7 = (LIGHT(x+1,y-1,z+1,0) + ls*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; \ No newline at end of file diff --git a/src/player_control.cpp b/src/player_control.cpp index b8e5f407..33d87a7a 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -27,6 +27,7 @@ #define CAMERA_SHAKING_SPEED 1.6f #define CAMERA_SHAKING_DELTA_K 10.0f #define FLIGHT_SPEED_MUL 8.0f +#define CHEAT_SPEED_MUL 5.0f #define JUMP_FORCE 7.0f void update_controls(PhysicsSolver* physics, @@ -53,11 +54,15 @@ void update_controls(PhysicsSolver* physics, bool sprint = Events::pressed(GLFW_KEY_LEFT_CONTROL); bool shift = Events::pressed(GLFW_KEY_LEFT_SHIFT) && hitbox->grounded && !sprint; bool zoom = Events::pressed(GLFW_KEY_C); + bool cheat = Events::pressed(GLFW_KEY_R); float speed = player->speed; if (player->flight){ speed *= FLIGHT_SPEED_MUL; } + if (cheat){ + speed *= CHEAT_SPEED_MUL; + } int substeps = (int)(delta * 1000); substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps)); physics->step(chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f); @@ -174,7 +179,12 @@ void update_interaction(Level* level, LineBatch* lineBatch){ vec3 iend; voxel* vox = chunks->rayCast(camera->position, camera->front, 10.0f, end, norm, iend); if (vox != nullptr){ - lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); + if (Block::blocks[vox->id]->type == 1){ + lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); + } else if (Block::blocks[vox->id]->type == 2){ + lineBatch->box(iend.x+0.4f, iend.y+0.3f, iend.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f); + } + if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && Block::blocks[vox->id]->breakable){ int x = (int)iend.x; diff --git a/src/voxels/Block.h b/src/voxels/Block.h index cd66322b..5310ca2f 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -15,6 +15,7 @@ public: bool obstacle = true; bool selectable = true; bool breakable = true; + unsigned char type = 1; Block(unsigned int id, int texture); }; diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index d7be2a78..c9f694b7 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -10,59 +10,72 @@ #include class PseudoRandom { - unsigned seed; + unsigned short seed; public: PseudoRandom(){ - seed = (unsigned)time(0); + seed = (unsigned short)time(0); } int rand(){ - seed = (8253729 * seed + 2396403); - return seed % 32768; + // seed = ((unsigned short)8253729 xor seed + (unsigned short)2396403 xor (unsigned short)time(0)) * (seed xor (unsigned short)2124678); + // unsigned short a = seed xor 0xf1ad; + // unsigned short b = seed * 0x7fb7; + // unsigned short c = a * 0xa77c; + // unsigned short d = b xor c; + // unsigned short e = d * seed % 0x6a; + // unsigned short f = c < seed % 0x10; + + // seed = (f % e) - a; + // seed = ((a + d) * b - c) * e + f; + + seed = (seed + 0x7ed5 + (seed << 6)); + seed = (seed ^ 0xc23c ^ (seed >> 9)); + seed = (seed + 0x1656 + (seed << 3)); + seed = ((seed + 0xa264) ^ (seed << 4)); + seed = (seed + 0xfd70 - (seed << 3)); + seed = (seed ^ 0xba49 ^ (seed >> 8)); + + return (int)seed; } void setSeed(int number){ - seed = (unsigned)number+8253729; + seed = (unsigned short)number+23729 xor (unsigned short)number+16786; rand(); } }; float calc_height(fnl_state *noise, int real_x, int real_z){ - const float s = 0.18f; - float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f); - height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f; - height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f; - height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f; - height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f; + // const float s = 0.18f; + float height = fnlGetNoise3D(noise, real_x*0.0125f*8,real_z*0.0125f*8, 0.0f); + height += fnlGetNoise3D(noise, real_x*0.025f*8,real_z*0.025f*8, 0.0f)*0.5f; + height += fnlGetNoise3D(noise, real_x*0.05f*8,real_z*0.05f*8, 0.0f)*0.25f; height += fnlGetNoise3D(noise, - real_x*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*50, - real_z*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32+4363,real_z*0.1f*s*32, 0.0f)*50, + real_x*0.2f*8 + fnlGetNoise3D(noise, real_x*0.1f*8,real_z*0.1f*8, 0.0f)*50, + real_z*0.2f*8 + fnlGetNoise3D(noise, real_x*0.1f*8+4363,real_z*0.1f*8, 0.0f)*50, 0.0f)*0.1f; - height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.0625f; - // height += fnlGetNoise3D(noise, real_x*s*32,real_z*s*32, 0.0f)*0.03f; - height = height * 0.5f + 0.5f; - height *= height; - height *= (140.0f)*0.12f/s; - height += (42)*0.12f/s; + height += fnlGetNoise3D(noise, real_x*0.1f*8,real_z*0.1f*8, 0.0f)*0.125f; + height += fnlGetNoise3D(noise, real_x*0.4f*8,real_z*0.4f*8, 0.0f)*0.0625f; + height += fnlGetNoise3D(noise, real_x*8,real_z*8, 0.0f)*0.03f*(fnlGetNoise3D(noise, -real_x*0.0125f*8-1000,real_z*0.0125f*8+2000, 0.0f)/2+0.5f); + height *= fnlGetNoise3D(noise, real_x*0.0125f*8+1000,real_z*0.0125f*8+1000, 0.0f)/2+0.5f; + height += 1.0f; + height *= 64.0f; return height; } float calc_height_faster(fnl_state *noise, int real_x, int real_z){ - const float s = 0.18f; - float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f); - height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f; - height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f; - height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f; - height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f; + // const float s = 0.18f; + float height = fnlGetNoise3D(noise, real_x*0.0125f*8,real_z*0.0125f*8, 0.0f); + height += fnlGetNoise3D(noise, real_x*0.025f*8,real_z*0.025f*8, 0.0f)*0.5f; + height += fnlGetNoise3D(noise, real_x*0.05f*8,real_z*0.05f*8, 0.0f)*0.25f; height += fnlGetNoise3D(noise, - real_x*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*50, - real_z*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32+4363,real_z*0.1f*s*32, 0.0f)*50, + real_x*0.2f*8 + fnlGetNoise3D(noise, real_x*0.1f*8,real_z*0.1f*8, 0.0f)*50, + real_z*0.2f*8 + fnlGetNoise3D(noise, real_x*0.1f*8+4363,real_z*0.1f*8, 0.0f)*50, 0.0f)*0.1f; - // height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F; - height = height * 0.5f + 0.5f; - height *= height; - height *= (140.0f)*0.12f/s; - height += (42)*0.12f/s; + height += fnlGetNoise3D(noise, real_x*0.1f*8,real_z*0.1f*8, 0.0f)*0.125f; + // height += fnlGetNoise3D(noise, real_x*0.4f*8,real_z*0.4f*8, 0.0f)*0.125f*0.5F; + height *= fnlGetNoise3D(noise, real_x*0.0125f*8+1000,real_z*0.0125f*8+1000, 0.0f)/2+0.5f; + height += 1.0f; + height *= 64.0f; return height; } #include @@ -98,10 +111,13 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ noise.noise_type = FNL_NOISE_OPENSIMPLEX2; noise.seed = seed * 60617077 % 25896307; - PseudoRandom random; + PseudoRandom randomtree; + // PseudoRandom random; float heights[CHUNK_VOL]; + std::cout << calc_height(&noise, cx, cy) << "\n"; + for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ int real_x = x + cx * CHUNK_W; @@ -127,28 +143,26 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ } else if (real_y < height){ id = 1; } else { - int tree = generate_tree(&noise, &random, heights, real_x, real_y, real_z, 16); + int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 16); if (tree) id = tree; - else if ((tree = generate_tree(&noise, &random, heights, real_x, real_y, real_z, 19))){ + else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 19))){ id = tree; - }else if ((tree = generate_tree(&noise, &random, heights, real_x, real_y, real_z, 23))){ + }else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 23))){ id = tree; } } - // if ((real_y < height) && (57 > height) && (height > 51) && ((int)height == real_y)){ - // id = 10; - // } - - // if ( ((height - (1 - 0.1 * pow(height - 55, 4))) < real_y) && (real_y < height)){ - // id = 10; - // } - if ( ((height - (1.5 - 0.2 * pow(height - 54, 4))) < real_y) && (real_y < height)){ id = 10; } if (real_y <= 2) id = 11; + if ((real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 56000)){ + id = 12; + } + if ((real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 64000)){ + id = 13; + } voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id; } } diff --git a/src/world_render.h b/src/world_render.h index c3c50a45..a022a531 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -139,11 +139,14 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) // choosen block preview Texture* blocks = assets->getTexture("block"); - batch->texture(blocks); + Texture* sprite = assets->getTexture("sprite"); + + batch->texture(sprite); + batch->sprite(16, 640, 64, 64, 16, 0, vec4(1.0f)); + batch->texture(blocks); int texid = Block::blocks[player->choosenBlock]->textureFaces[3]; // face-3 is top face of block - batch->sprite(14, Window::height-82, 68, 68, 16, texid, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(16, Window::height-80, 64, 64, 16, texid, vec4(1.0f)); + batch->sprite(24, 648, 48, 48, 16, texid, vec4(1.0f)); batch->render(); } From 18266845a6c525323735ebb23f512a75157c7cea Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Wed, 10 Aug 2022 20:24:13 +0300 Subject: [PATCH 44/56] delete comment --- src/graphics/VoxelRenderer.cpp | 38 ---------------------------------- src/voxels/WorldGenerator.cpp | 14 ------------- 2 files changed, 52 deletions(-) diff --git a/src/graphics/VoxelRenderer.cpp b/src/graphics/VoxelRenderer.cpp index ce44e1f4..76f984c1 100644 --- a/src/graphics/VoxelRenderer.cpp +++ b/src/graphics/VoxelRenderer.cpp @@ -450,41 +450,3 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s size = buffer.size(); return &buffer[0]; } - - - - // float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - // float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lr2 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lr3 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - // float lr4 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - // float lr5 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lr6 = (LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lr7 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - - // float lg0 = (LIGHT(x+1,y-1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y-1,z,1)) / 75.0f; - // float lg1 = (LIGHT(x+1,y+1,z-1,1) + lg*30 + LIGHT(x+1,y,z-1,1) + LIGHT(x+1,y+1,z,1)) / 75.0f; - // float lg2 = (LIGHT(x+1,y+1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y+1,z,1)) / 75.0f; - // float lg3 = (LIGHT(x+1,y-1,z+1,1) + lg*30 + LIGHT(x+1,y,z+1,1) + LIGHT(x+1,y-1,z,1)) / 75.0f; - // float lg4 = (LIGHT(x+1,y-1,z-1,0) + lg*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - // float lg5 = (LIGHT(x+1,y+1,z-1,0) + lg*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lg6 = (LIGHT(x+1,y+1,z+1,0) + lg*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lg7 = (LIGHT(x+1,y-1,z+1,0) + lg*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - - // float lb0 = (LIGHT(x+1,y-1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y-1,z,2)) / 75.0f; - // float lb1 = (LIGHT(x+1,y+1,z-1,2) + lb*30 + LIGHT(x+1,y,z-1,2) + LIGHT(x+1,y+1,z,2)) / 75.0f; - // float lb2 = (LIGHT(x+1,y+1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y+1,z,2)) / 75.0f; - // float lb3 = (LIGHT(x+1,y-1,z+1,2) + lb*30 + LIGHT(x+1,y,z+1,2) + LIGHT(x+1,y-1,z,2)) / 75.0f; - // float lb4 = (LIGHT(x+1,y-1,z-1,0) + lb*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - // float lb5 = (LIGHT(x+1,y+1,z-1,0) + lb*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lb6 = (LIGHT(x+1,y+1,z+1,0) + lb*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float lb7 = (LIGHT(x+1,y-1,z+1,0) + lb*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - - // float ls0 = (LIGHT(x+1,y-1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y-1,z,3)) / 75.0f; - // float ls1 = (LIGHT(x+1,y+1,z-1,3) + ls*30 + LIGHT(x+1,y,z-1,3) + LIGHT(x+1,y+1,z,3)) / 75.0f; - // float ls2 = (LIGHT(x+1,y+1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y+1,z,3)) / 75.0f; - // float ls3 = (LIGHT(x+1,y-1,z+1,3) + ls*30 + LIGHT(x+1,y,z+1,3) + LIGHT(x+1,y-1,z,3)) / 75.0f; - // float ls4 = (LIGHT(x+1,y-1,z-1,0) + ls*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; - // float ls5 = (LIGHT(x+1,y+1,z-1,0) + ls*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float ls6 = (LIGHT(x+1,y+1,z+1,0) + ls*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; - // float ls7 = (LIGHT(x+1,y-1,z+1,0) + ls*30 + LIGHT(x+1,y,z+1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; \ No newline at end of file diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index c9f694b7..46d6e3dc 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -17,17 +17,6 @@ public: } int rand(){ - // seed = ((unsigned short)8253729 xor seed + (unsigned short)2396403 xor (unsigned short)time(0)) * (seed xor (unsigned short)2124678); - // unsigned short a = seed xor 0xf1ad; - // unsigned short b = seed * 0x7fb7; - // unsigned short c = a * 0xa77c; - // unsigned short d = b xor c; - // unsigned short e = d * seed % 0x6a; - // unsigned short f = c < seed % 0x10; - - // seed = (f % e) - a; - // seed = ((a + d) * b - c) * e + f; - seed = (seed + 0x7ed5 + (seed << 6)); seed = (seed ^ 0xc23c ^ (seed >> 9)); seed = (seed + 0x1656 + (seed << 3)); @@ -45,7 +34,6 @@ public: }; float calc_height(fnl_state *noise, int real_x, int real_z){ - // const float s = 0.18f; float height = fnlGetNoise3D(noise, real_x*0.0125f*8,real_z*0.0125f*8, 0.0f); height += fnlGetNoise3D(noise, real_x*0.025f*8,real_z*0.025f*8, 0.0f)*0.5f; height += fnlGetNoise3D(noise, real_x*0.05f*8,real_z*0.05f*8, 0.0f)*0.25f; @@ -63,7 +51,6 @@ float calc_height(fnl_state *noise, int real_x, int real_z){ } float calc_height_faster(fnl_state *noise, int real_x, int real_z){ - // const float s = 0.18f; float height = fnlGetNoise3D(noise, real_x*0.0125f*8,real_z*0.0125f*8, 0.0f); height += fnlGetNoise3D(noise, real_x*0.025f*8,real_z*0.025f*8, 0.0f)*0.5f; height += fnlGetNoise3D(noise, real_x*0.05f*8,real_z*0.05f*8, 0.0f)*0.25f; @@ -72,7 +59,6 @@ float calc_height_faster(fnl_state *noise, int real_x, int real_z){ real_z*0.2f*8 + fnlGetNoise3D(noise, real_x*0.1f*8+4363,real_z*0.1f*8, 0.0f)*50, 0.0f)*0.1f; height += fnlGetNoise3D(noise, real_x*0.1f*8,real_z*0.1f*8, 0.0f)*0.125f; - // height += fnlGetNoise3D(noise, real_x*0.4f*8,real_z*0.4f*8, 0.0f)*0.125f*0.5F; height *= fnlGetNoise3D(noise, real_x*0.0125f*8+1000,real_z*0.0125f*8+1000, 0.0f)/2+0.5f; height += 1.0f; height *= 64.0f; From 420ae4e9937204eb4c7a376fc485a30c163aec46 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Wed, 10 Aug 2022 20:26:35 +0300 Subject: [PATCH 45/56] include fix --- src/files/files.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/files/files.h b/src/files/files.h index 7b53cb16..27cc9c54 100644 --- a/src/files/files.h +++ b/src/files/files.h @@ -1,7 +1,9 @@ #ifndef FILES_FILES_H_ #define FILES_FILES_H_ +#ifndef std::string #include +#endif extern bool write_binary_file(std::string filename, const char* data, size_t size); extern unsigned int append_binary_file(std::string filename, const char* data, size_t size); From 0711cb07f037417505a4e7338f315694b21cd492 Mon Sep 17 00:00:00 2001 From: lllzebralll Date: Thu, 11 Aug 2022 20:22:20 +0300 Subject: [PATCH 46/56] add blockSprite --- res/sprite.png | Bin 262913 -> 262913 bytes src/graphics/Batch2D.cpp | 65 ++++++++++++++++++++++++++++++++++ src/graphics/Batch2D.h | 7 +++- src/voxels/WorldGenerator.cpp | 4 +-- src/world_render.h | 11 ++++-- 5 files changed, 82 insertions(+), 5 deletions(-) diff --git a/res/sprite.png b/res/sprite.png index f9e20e0dfd52089d846fa19d75b1a4185845f57f..65c5d3adbfdf6dd479164e96dad5df01f2f06793 100644 GIT binary patch delta 147 zcmZo{6KHG`*bulB#}kN3)+pyPpFi5HoG}b6}o-NTjz}e4Bgp^ff@s89ZJ6 KT-G@yGywoSPAoG3 diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index a96aa4fd..4cde0087 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -45,6 +45,18 @@ void Batch2D::vertex(float x, float y, buffer[index++] = b; buffer[index++] = a; } +void Batch2D::vertex(vec2 point, + vec2 uvpoint, + float r, float g, float b, float a) { + buffer[index++] = point.x; + buffer[index++] = point.y; + buffer[index++] = uvpoint.x; + buffer[index++] = uvpoint.y; + buffer[index++] = r; + buffer[index++] = g; + buffer[index++] = b; + buffer[index++] = a; +} void Batch2D::texture(Texture* new_texture){ if (_texture == new_texture) @@ -81,6 +93,59 @@ void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index rect(x, y, w, h, u, v, scale, scale, tint.r, tint.g, tint.b, tint.a); } +void Batch2D::blockSprite(float x, float y, float w, float h, int atlasRes, int index[6], vec4 tint){ + float scale = 1.0f / (float)atlasRes; + float uu = (index[3] % atlasRes) * scale; + float vu = 1.0f - ((index[3] / atlasRes) * scale) - scale; + float uf = (index[0] % atlasRes) * scale; + float vf = 1.0f - ((index[0] / atlasRes) * scale) - scale; + if (index[0] + 6*VERTEX_SIZE >= capacity) + render(); + + vec2 points[7] = {vec2(x+(w*0.5f), y+(h*0.5f)), + vec2(x, y+(h*0.25f)), + vec2(x+(w*0.5f), y), + vec2(x+w, y+(h*0.25f)), + vec2(x+w, y+(h*0.75f)), + vec2(x+(w*0.5f), y+h), + vec2(x, y+(h*0.75f))}; + + vec2 uvpoints[8] = {vec2(uu, vu), + vec2(uu+scale, vu), + vec2(uu+scale, vu+scale), + vec2(uu, vu+scale), + vec2(uf, vf), + vec2(uf+scale, vf), + vec2(uf+scale, vf+scale), + vec2(uf, vf+scale)}; + + vertex(points[0], uvpoints[3], tint.r, tint.g, tint.b, tint.a); + vertex(points[1], uvpoints[0], tint.r, tint.g, tint.b, tint.a); + vertex(points[2], uvpoints[1], tint.r, tint.g, tint.b, tint.a); + + vertex(points[0], uvpoints[3], tint.r, tint.g, tint.b, tint.a); + vertex(points[2], uvpoints[1], tint.r, tint.g, tint.b, tint.a); + vertex(points[3], uvpoints[2], tint.r, tint.g, tint.b, tint.a); + + + vertex(points[0], uvpoints[7], tint.r, tint.g, tint.b, tint.a); + vertex(points[3], uvpoints[6], tint.r, tint.g, tint.b, tint.a); + vertex(points[4], uvpoints[5], tint.r, tint.g, tint.b, tint.a); + + vertex(points[0], uvpoints[7], tint.r, tint.g, tint.b, tint.a); + vertex(points[4], uvpoints[5], tint.r, tint.g, tint.b, tint.a); + vertex(points[5], uvpoints[4], tint.r, tint.g, tint.b, tint.a); + + + vertex(points[0], uvpoints[6], tint.r, tint.g, tint.b, tint.a); + vertex(points[5], uvpoints[5], tint.r, tint.g, tint.b, tint.a); + vertex(points[6], uvpoints[4], tint.r, tint.g, tint.b, tint.a); + + vertex(points[0], uvpoints[6], tint.r, tint.g, tint.b, tint.a); + vertex(points[6], uvpoints[4], tint.r, tint.g, tint.b, tint.a); + vertex(points[1], uvpoints[7], tint.r, tint.g, tint.b, tint.a); +} + void Batch2D::rect(float x, float y, float w, float h, float u, float v, float tx, float ty, float r, float g, float b, float a){ diff --git a/src/graphics/Batch2D.h b/src/graphics/Batch2D.h index 21fe3b6d..814305f9 100644 --- a/src/graphics/Batch2D.h +++ b/src/graphics/Batch2D.h @@ -18,11 +18,15 @@ class Batch2D { size_t index; Texture* blank; - Texture* _texture; + Texture* _texture; void vertex(float x, float y, float u, float v, float r, float g, float b, float a); + void vertex(vec2 point, + vec2 uvpoint, + float r, float g, float b, float a); + public: Batch2D(size_t capacity); ~Batch2D(); @@ -30,6 +34,7 @@ public: void begin(); void texture(Texture* texture); void sprite(float x, float y, float w, float h, int atlasRes, int index, vec4 tint); + void blockSprite(float x, float y, float w, float h, int atlasRes, int index[6], vec4 tint); void rect(float x, float y, float w, float h); void rect(float x, float y, float w, float h, float u, float v, float tx, float ty, diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index 46d6e3dc..54e80f83 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -143,10 +143,10 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ } if (real_y <= 2) id = 11; - if ((real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 56000)){ + if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 56000)){ id = 12; } - if ((real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 64000)){ + if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 64000)){ id = 13; } voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id; diff --git a/src/world_render.h b/src/world_render.h index a022a531..b5c7e380 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -145,8 +145,15 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) batch->sprite(16, 640, 64, 64, 16, 0, vec4(1.0f)); batch->texture(blocks); - int texid = Block::blocks[player->choosenBlock]->textureFaces[3]; // face-3 is top face of block - batch->sprite(24, 648, 48, 48, 16, texid, vec4(1.0f)); + 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){ + batch->sprite(24, 648, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f)); + } + batch->render(); } From d60f5c3679749a74bc36d9a15e2499cbf72500c8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 29 Aug 2022 15:56:29 +0300 Subject: [PATCH 47/56] Added Batch3D --- src/graphics/Batch3D.cpp | 165 +++++++++++++++++++++++++++++++++++++++ src/graphics/Batch3D.h | 40 ++++++++++ src/world_render.h | 10 ++- 3 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 src/graphics/Batch3D.cpp create mode 100644 src/graphics/Batch3D.h 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)); From dc3bc312a2efd3bc4c42b13d888b25b82f2af5f7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 29 Aug 2022 15:57:56 +0300 Subject: [PATCH 48/56] Update makefiles --- Debug/src/graphics/subdir.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Debug/src/graphics/subdir.mk b/Debug/src/graphics/subdir.mk index 0797e63c..73d9da31 100644 --- a/Debug/src/graphics/subdir.mk +++ b/Debug/src/graphics/subdir.mk @@ -5,6 +5,7 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ ../src/graphics/Batch2D.cpp \ +../src/graphics/Batch3D.cpp \ ../src/graphics/Font.cpp \ ../src/graphics/LineBatch.cpp \ ../src/graphics/Mesh.cpp \ @@ -14,6 +15,7 @@ CPP_SRCS += \ OBJS += \ ./src/graphics/Batch2D.o \ +./src/graphics/Batch3D.o \ ./src/graphics/Font.o \ ./src/graphics/LineBatch.o \ ./src/graphics/Mesh.o \ @@ -23,6 +25,7 @@ OBJS += \ CPP_DEPS += \ ./src/graphics/Batch2D.d \ +./src/graphics/Batch3D.d \ ./src/graphics/Font.d \ ./src/graphics/LineBatch.d \ ./src/graphics/Mesh.d \ From ce5400e5d7f4e597c7bb1d79a3800b65af7b388d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 29 Aug 2022 16:03:08 +0300 Subject: [PATCH 49/56] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index f1bcd4b5..da925adf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ Debug/src/**/*.o Debug/voxel_engine +world + .vscode .settings From 5955c742083bf990f2c19ce8dcae885f1900a051 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 29 Aug 2022 16:23:23 +0300 Subject: [PATCH 50/56] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index da925adf..da91e919 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ world .settings .cproject .project +.git From d3f29f8ace2284f53e00ce10c65c910439369b37 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 1 Oct 2022 15:59:57 +0300 Subject: [PATCH 51/56] WorldRenderer and HudRenderer classes --- .gitignore | 1 + Debug/src/subdir.mk | 6 + src/declarations.h | 6 +- src/graphics/VoxelRenderer.cpp | 2 +- src/player_control.cpp | 4 +- src/voxel_engine.cpp | 13 +- src/voxels/Block.h | 5 +- src/world_render.h | 222 +++------------------------------ 8 files changed, 43 insertions(+), 216 deletions(-) diff --git a/.gitignore b/.gitignore index da91e919..6650ac54 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ world .cproject .project .git +/Default/ diff --git a/Debug/src/subdir.mk b/Debug/src/subdir.mk index 25556588..ff529556 100644 --- a/Debug/src/subdir.mk +++ b/Debug/src/subdir.mk @@ -6,16 +6,22 @@ CPP_SRCS += \ ../src/Assets.cpp \ ../src/player_control.cpp \ +../src/hud_render.cpp \ +../src/world_render.cpp \ ../src/voxel_engine.cpp OBJS += \ ./src/Assets.o \ ./src/player_control.o \ +../src/hud_render.o \ +../src/world_render.o \ ./src/voxel_engine.o CPP_DEPS += \ ./src/Assets.d \ ./src/player_control.d \ +../src/hud_render.d \ +../src/world_render.d \ ./src/voxel_engine.d diff --git a/src/declarations.h b/src/declarations.h index 086e2b91..03491fd7 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -83,7 +83,7 @@ void setup_definitions() { block->skyLightPassing = true; block->obstacle = false; block->selectable = false; - block->type = 0; + block->model = 0; Block::blocks[block->id] = block; // DIRT 1 @@ -150,7 +150,7 @@ void setup_definitions() { block->drawGroup = 5; block->lightPassing = true; block->obstacle = false; - block->type = 2; + block->model = 2; Block::blocks[block->id] = block; // FLOWER 13 @@ -158,7 +158,7 @@ void setup_definitions() { block->drawGroup = 5; block->lightPassing = true; block->obstacle = false; - block->type = 2; + block->model = 2; Block::blocks[block->id] = block; } #endif // DECLARATIONS_H diff --git a/src/graphics/VoxelRenderer.cpp b/src/graphics/VoxelRenderer.cpp index 76f984c1..7e17d676 100644 --- a/src/graphics/VoxelRenderer.cpp +++ b/src/graphics/VoxelRenderer.cpp @@ -300,7 +300,7 @@ inline void _renderXBlock(std::vector& buffer, int x, int y, int z, const float xs = (float)(char)rand / 512; float zs = (float)(char)(rand >> 8) / 512; - if (block->type != 2){ + if (block->model != 2){ return; } diff --git a/src/player_control.cpp b/src/player_control.cpp index 33d87a7a..48d1900c 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -179,9 +179,9 @@ void update_interaction(Level* level, LineBatch* lineBatch){ vec3 iend; voxel* vox = chunks->rayCast(camera->position, camera->front, 10.0f, end, norm, iend); if (vox != nullptr){ - if (Block::blocks[vox->id]->type == 1){ + if (Block::blocks[vox->id]->model == 1){ lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); - } else if (Block::blocks[vox->id]->type == 2){ + } else if (Block::blocks[vox->id]->model == 2){ lineBatch->box(iend.x+0.4f, iend.y+0.3f, iend.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f); } diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index d4a986d6..31ee3cb1 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -51,6 +51,7 @@ using namespace glm; #include "declarations.h" #include "world_render.h" +#include "hud_render.h" #include "player_control.h" @@ -77,7 +78,7 @@ void write_world(World* world, Level* level){ world->wfile->writePlayer(level->player); } -void update_level(World* world, Level* level, vec3 position, float delta, long frame){ +void update_level(World* world, Level* level, vec3 position, float delta, long frame, VoxelRenderer* renderer, LineBatch* lineBatch){ update_controls(level->physics, level->chunks, level->player, delta); update_interaction(level, lineBatch); @@ -134,7 +135,8 @@ int main() { Level* level = load_level(world, player); std::cout << "-- preparing systems" << std::endl; - init_renderer(); + HudRenderer hud; + WorldRenderer worldRenderer(level); float lastTime = glfwGetTime(); float delta = 0.0f; @@ -159,9 +161,9 @@ int main() { devdata = !devdata; } - update_level(world, level, camera->position, delta, frame); - draw_world(world, level, camera, assets, occlusion); - draw_hud(world, level, assets, devdata, fps); + update_level(world, level, camera->position, delta, frame, worldRenderer.renderer, worldRenderer.lineBatch); + worldRenderer.draw(world, camera, assets, occlusion); + hud.draw(world, level, assets, devdata, fps); Window::swapBuffers(); Events::pullEvents(); @@ -172,7 +174,6 @@ int main() { std::cout << "-- shutting down" << std::endl; delete assets; - finalize_renderer(); Audio::finalize(); Events::finalize(); Window::terminate(); diff --git a/src/voxels/Block.h b/src/voxels/Block.h index 5310ca2f..c57bec3d 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -1,6 +1,9 @@ #ifndef VOXELS_BLOCK_H_ #define VOXELS_BLOCK_H_ +#define BLOCK_MODEL_CUBE 1 +#define BLOCK_MODEL_GRASS 2 + class Block { public: static Block* blocks[256]; @@ -15,7 +18,7 @@ public: bool obstacle = true; bool selectable = true; bool breakable = true; - unsigned char type = 1; + unsigned char model = 1; Block(unsigned int id, int texture); }; diff --git a/src/world_render.h b/src/world_render.h index eb2e363b..124caf8b 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -13,214 +13,30 @@ #include #include -#include "window/Window.h" -#include "window/Camera.h" -#include "graphics/Mesh.h" -#include "graphics/Shader.h" -#include "graphics/Texture.h" -#include "graphics/LineBatch.h" -#include "graphics/Batch3D.h" -#include "voxels/Chunks.h" -#include "voxels/Chunk.h" +class World; +class Level; +class Camera; +class Assets; +class LineBatch; +class Batch3D; +class VoxelRenderer; +class Shader; -float _camera_cx; -float _camera_cz; -Chunks* _chunks; -Mesh *crosshair; +class WorldRenderer { + Batch3D *batch3d; + Level* level; -float vertices[] = { - // x y - -0.01f,-0.01f, - 0.01f, 0.01f, + void drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion); +public: + VoxelRenderer *renderer; + LineBatch *lineBatch; - -0.01f, 0.01f, - 0.01f,-0.01f, + WorldRenderer(Level* level); + ~WorldRenderer(); + + void draw(World* world, Camera* camera, Assets* assets, bool occlusion); }; -int attrs[] = { - 2, 0 //null terminator -}; - -int uiscale = 1; - -LineBatch *lineBatch; -Batch2D *batch; -Batch3D *batch3d; -Camera *uicamera; -VoxelRenderer *renderer; - -void init_renderer(){ - crosshair = new Mesh(vertices, 4, attrs); - 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; - - renderer = new VoxelRenderer(); -} - - -void finalize_renderer(){ - delete crosshair; - delete lineBatch; - delete batch; - delete renderer; -} - -void draw_chunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ - Chunk* chunk = _chunks->chunks[index]; - Mesh* mesh = _chunks->meshes[index]; - if (mesh == nullptr) - return; - - // Simple frustum culling (culling chunks behind the camera in 2D - XZ) - if (occlusion){ - const float cameraX = camera->position.x; - const float cameraZ = camera->position.z; - const float camDirX = camera->dir.x; - const float camDirZ = camera->dir.z; - - bool unoccluded = false; - do { - if ((chunk->x*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; - } - if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; - } - if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; - } - if ((chunk->x*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; - } - } while (false); - if (!unoccluded) - return; - } - - mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, chunk->y*CHUNK_H+0.5f, chunk->z*CHUNK_D+0.5f)); - shader->uniformMatrix("u_model", model); - mesh->draw(GL_TRIANGLES); -} - -bool chunks_comparator(size_t i, size_t j) { - Chunk* a = _chunks->chunks[i]; - Chunk* b = _chunks->chunks[j]; - return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz) - > - (b->x + 0.5f - _camera_cx)*(b->x + 0.5f - _camera_cx) + (b->z + 0.5f - _camera_cz)*(b->z + 0.5f - _camera_cz)); -} - - -void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps){ - Chunks* chunks = level->chunks; - Player* player = level->player; - - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - Shader* uishader = assets->getShader("ui"); - uishader->use(); - uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); - - // draw debug info - Font* font = assets->getFont("normal"); - batch->begin(); - if (devdata){ - font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE); - font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE); - font->draw(batch, std::to_wstring((int)player->camera->position.y), 50, 30, STYLE_OUTLINE); - font->draw(batch, std::to_wstring((int)player->camera->position.z), 90, 30, STYLE_OUTLINE); - font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE); - font->draw(batch, std::to_wstring(fps), 40, 42, STYLE_OUTLINE); - } - batch->render(); - - // choosen block preview - Texture* blocks = assets->getTexture("block"); - Texture* sprite = assets->getTexture("sprite"); - - batch->texture(sprite); - batch->sprite(16, 640, 64, 64, 16, 0, vec4(1.0f)); - - batch->texture(blocks); - Block* cblock = Block::blocks[player->choosenBlock]; - if (cblock->type == 1){ - batch->blockSprite(24, 648, 48, 48, 16, cblock->textureFaces, vec4(1.0f)); - } else if (cblock->type == 2){ - batch->sprite(24, 648, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f)); - } - - batch->render(); -} - -void draw_world(World* world, Level* level, Camera* camera, Assets* assets, bool occlusion){ - Chunks* chunks = level->chunks; - - glClearColor(0.7f,0.81f,1.0f,1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - _chunks = chunks; - - Texture* texture = assets->getTexture("block"); - Shader* shader = assets->getShader("main"); - Shader* crosshairShader = assets->getShader("crosshair"); - Shader* linesShader = assets->getShader("lines"); - shader->use(); - shader->uniformMatrix("u_proj", camera->getProjection()); - shader->uniformMatrix("u_view", camera->getView()); - shader->uniform1f("u_gamma", 1.6f); - shader->uniform3f("u_skyLightColor", 2.2f,2.2f,2.2f); - shader->uniform3f("u_fogColor", 0.7f,0.71f,0.73f); - shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); - texture->bind(); - - std::vector indices; - - for (size_t i = 0; i < chunks->volume; i++){ - Chunk* chunk = chunks->chunks[i]; - if (chunk == nullptr) - continue; - if (chunks->meshes[i] != nullptr) - indices.push_back(i); - } - - float px = camera->position.x / (float)CHUNK_W; - float pz = camera->position.z / (float)CHUNK_D; - - _camera_cx = px; - _camera_cz = pz; - - std::sort(indices.begin(), indices.end(), chunks_comparator); - - - for (size_t i = 0; i < indices.size(); i++){ - 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)); - crosshair->draw(GL_LINES); - - linesShader->use(); - linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView()); - glLineWidth(2.0f); - lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x+0.01f, camera->position.y-0.1f, camera->position.z, 1, 0, 0, 1); - lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f, camera->position.z+0.01f, 0, 0, 1, 1); - lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f+0.01f, camera->position.z, 0, 1, 0, 1); - lineBatch->render(); -} #endif // WORLD_RENDERER_CPP From 26f70b2f0421128fffbc8bd3bdb658b945c131d3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 1 Oct 2022 16:11:31 +0300 Subject: [PATCH 52/56] Fixed previous push --- Debug/src/subdir.mk | 8 +-- src/hud_render.cpp | 69 +++++++++++++++++++ src/hud_render.h | 19 ++++++ src/world_render.cpp | 159 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 src/hud_render.cpp create mode 100644 src/hud_render.h create mode 100644 src/world_render.cpp diff --git a/Debug/src/subdir.mk b/Debug/src/subdir.mk index ff529556..68c2121d 100644 --- a/Debug/src/subdir.mk +++ b/Debug/src/subdir.mk @@ -13,15 +13,15 @@ CPP_SRCS += \ OBJS += \ ./src/Assets.o \ ./src/player_control.o \ -../src/hud_render.o \ -../src/world_render.o \ +./src/hud_render.o \ +./src/world_render.o \ ./src/voxel_engine.o CPP_DEPS += \ ./src/Assets.d \ ./src/player_control.d \ -../src/hud_render.d \ -../src/world_render.d \ +./src/hud_render.d \ +./src/world_render.d \ ./src/voxel_engine.d diff --git a/src/hud_render.cpp b/src/hud_render.cpp new file mode 100644 index 00000000..78da460a --- /dev/null +++ b/src/hud_render.cpp @@ -0,0 +1,69 @@ +#include "hud_render.h" + +#include +#include "Assets.h" +#include "graphics/Shader.h" +#include "graphics/Batch2D.h" +#include "graphics/Font.h" +#include "window/Camera.h" +#include "window/Window.h" +#include "voxels/Chunks.h" +#include "voxels/Block.h" +#include "world/World.h" +#include "world/Level.h" +#include "objects/Player.h" + + +HudRenderer::HudRenderer() { + batch = new Batch2D(1024); + uicamera = new Camera(glm::vec3(), Window::height / 1.0f); + uicamera->perspective = false; + uicamera->flipped = true; +} + +HudRenderer::~HudRenderer() { + delete batch; + delete uicamera; +} + + +void HudRenderer::draw(World* world, Level* level, Assets* assets, bool devdata, int fps){ + Chunks* chunks = level->chunks; + Player* player = level->player; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + Shader* uishader = assets->getShader("ui"); + uishader->use(); + uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); + + // Draw debug info + Font* font = assets->getFont("normal"); + batch->begin(); + if (devdata){ + font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.y), 50, 30, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.z), 90, 30, STYLE_OUTLINE); + font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE); + font->draw(batch, std::to_wstring(fps), 40, 42, STYLE_OUTLINE); + } + batch->render(); + + // Chosen block preview + Texture* blocks = assets->getTexture("block"); + Texture* sprite = assets->getTexture("sprite"); + + batch->texture(sprite); + batch->sprite(16, 640, 64, 64, 16, 0, vec4(1.0f)); + + batch->texture(blocks); + Block* cblock = Block::blocks[player->choosenBlock]; + if (cblock->model == BLOCK_MODEL_CUBE){ + batch->blockSprite(24, 648, 48, 48, 16, cblock->textureFaces, vec4(1.0f)); + } else if (cblock->model == BLOCK_MODEL_GRASS){ + batch->sprite(24, 648, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f)); + } + + batch->render(); +} diff --git a/src/hud_render.h b/src/hud_render.h new file mode 100644 index 00000000..e07d36a1 --- /dev/null +++ b/src/hud_render.h @@ -0,0 +1,19 @@ +#ifndef SRC_HUD_RENDER_H_ +#define SRC_HUD_RENDER_H_ + +class Batch2D; +class Camera; +class World; +class Level; +class Assets; + +class HudRenderer { + Batch2D *batch; + Camera *uicamera; +public: + HudRenderer(); + ~HudRenderer(); + void draw(World* world, Level* level, Assets* assets, bool devdata, int fps); +}; + +#endif /* SRC_HUD_RENDER_H_ */ diff --git a/src/world_render.cpp b/src/world_render.cpp new file mode 100644 index 00000000..8a98dc9d --- /dev/null +++ b/src/world_render.cpp @@ -0,0 +1,159 @@ +#include "world_render.h" + +#include "graphics/VoxelRenderer.h" + +#include "window/Window.h" +#include "window/Camera.h" +#include "graphics/Mesh.h" +#include "graphics/Shader.h" +#include "graphics/Texture.h" +#include "graphics/LineBatch.h" +#include "graphics/Batch3D.h" +#include "voxels/Chunks.h" +#include "voxels/Chunk.h" +#include "world/World.h" +#include "world/Level.h" +#include "Assets.h" + +float _camera_cx; +float _camera_cz; + +Mesh *crosshair; + +float vertices[] = { + // x y + -0.01f,-0.01f, + 0.01f, 0.01f, + + -0.01f, 0.01f, + 0.01f,-0.01f, +}; + +int attrs[] = { + 2, 0 //null terminator +}; + +WorldRenderer::WorldRenderer(Level* level) { + this->level = level; + crosshair = new Mesh(vertices, 4, attrs); + lineBatch = new LineBatch(4096); + batch3d = new Batch3D(1024); + renderer = new VoxelRenderer(); +} + +WorldRenderer::~WorldRenderer() { + delete crosshair; + delete lineBatch; + delete renderer; +} + +Chunks* _chunks = nullptr; + +bool chunks_distance_compare(size_t i, size_t j) { + Chunks* chunks = _chunks; + Chunk* a = chunks->chunks[i]; + Chunk* b = chunks->chunks[j]; + return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz) + > + (b->x + 0.5f - _camera_cx)*(b->x + 0.5f - _camera_cx) + (b->z + 0.5f - _camera_cz)*(b->z + 0.5f - _camera_cz)); +} + +void WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ + Chunk* chunk = level->chunks->chunks[index]; + Mesh* mesh = level->chunks->meshes[index]; + if (mesh == nullptr) + return; + + // Simple frustum culling (culling chunks behind the camera in 2D - XZ) + if (occlusion){ + const float cameraX = camera->position.x; + const float cameraZ = camera->position.z; + const float camDirX = camera->dir.x; + const float camDirZ = camera->dir.z; + + bool unoccluded = false; + do { + if ((chunk->x*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){ + unoccluded = true; break; + } + if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){ + unoccluded = true; break; + } + if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){ + unoccluded = true; break; + } + if ((chunk->x*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){ + unoccluded = true; break; + } + } while (false); + if (!unoccluded) + return; + } + + mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, chunk->y*CHUNK_H+0.5f, chunk->z*CHUNK_D+0.5f)); + shader->uniformMatrix("u_model", model); + mesh->draw(GL_TRIANGLES); +} + +void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occlusion){ + Chunks* chunks = level->chunks; + + glClearColor(0.7f,0.81f,1.0f,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + Texture* texture = assets->getTexture("block"); + Shader* shader = assets->getShader("main"); + Shader* crosshairShader = assets->getShader("crosshair"); + Shader* linesShader = assets->getShader("lines"); + shader->use(); + shader->uniformMatrix("u_proj", camera->getProjection()); + shader->uniformMatrix("u_view", camera->getView()); + shader->uniform1f("u_gamma", 1.6f); + shader->uniform3f("u_skyLightColor", 2.2f,2.2f,2.2f); + shader->uniform3f("u_fogColor", 0.7f,0.71f,0.73f); + shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); + texture->bind(); + + std::vector indices; + + for (size_t i = 0; i < chunks->volume; i++){ + Chunk* chunk = chunks->chunks[i]; + if (chunk == nullptr) + continue; + if (chunks->meshes[i] != nullptr) + indices.push_back(i); + } + + float px = camera->position.x / (float)CHUNK_W; + float pz = camera->position.z / (float)CHUNK_D; + + _camera_cx = px; + _camera_cz = pz; + _chunks = chunks; + std::sort(indices.begin(), indices.end(), chunks_distance_compare); + + + for (size_t i = 0; i < indices.size(); i++){ + drawChunk(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)); + crosshair->draw(GL_LINES); + + linesShader->use(); + linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView()); + glLineWidth(2.0f); + lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x+0.01f, camera->position.y-0.1f, camera->position.z, 1, 0, 0, 1); + lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f, camera->position.z+0.01f, 0, 0, 1, 1); + lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f+0.01f, camera->position.z, 0, 1, 0, 1); + lineBatch->render(); +} From 6965bbe80984be7edb8a07b27093694c0b3bc67e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 1 Oct 2022 17:11:43 +0300 Subject: [PATCH 53/56] PlayerController class (more OOP) --- src/player_control.cpp | 26 ++++++++++++-------------- src/player_control.h | 14 +++++++++++--- src/voxel_engine.cpp | 21 +++++++++++++++++---- src/voxels/WorldGenerator.cpp | 10 +++++----- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/player_control.cpp b/src/player_control.cpp index 48d1900c..7772f097 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -1,6 +1,5 @@ #include "player_control.h" -#include "graphics/LineBatch.h" #include "objects/Player.h" #include "physics/PhysicsSolver.h" #include "physics/Hitbox.h" @@ -30,10 +29,11 @@ #define CHEAT_SPEED_MUL 5.0f #define JUMP_FORCE 7.0f -void update_controls(PhysicsSolver* physics, - Chunks* chunks, - Player* player, - float delta){ +PlayerController::PlayerController(Level* level) : level(level) { +} + +void PlayerController::update_controls(float delta){ + Player* player = level->player; if (Events::jpressed(GLFW_KEY_ESCAPE)){ Window::setShouldClose(true); @@ -65,7 +65,7 @@ void update_controls(PhysicsSolver* physics, } int substeps = (int)(delta * 1000); substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps)); - physics->step(chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f); + level->physics->step(level->chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f); camera->position.x = hitbox->position.x; camera->position.y = hitbox->position.y + 0.7f; camera->position.z = hitbox->position.z; @@ -169,23 +169,19 @@ void update_controls(PhysicsSolver* physics, } } -void update_interaction(Level* level, LineBatch* lineBatch){ +void PlayerController::update_interaction(){ Chunks* chunks = level->chunks; Player* player = level->player; - Camera* camera = player->camera; Lighting* lighting = level->lighting; + Camera* camera = player->camera; vec3 end; vec3 norm; vec3 iend; voxel* vox = chunks->rayCast(camera->position, camera->front, 10.0f, end, norm, iend); if (vox != nullptr){ - if (Block::blocks[vox->id]->model == 1){ - lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); - } else if (Block::blocks[vox->id]->model == 2){ - lineBatch->box(iend.x+0.4f, iend.y+0.3f, iend.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f); - } + selectedBlockId = vox->id; + selectedBlockPosition = iend; - if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && Block::blocks[vox->id]->breakable){ int x = (int)iend.x; int y = (int)iend.y; @@ -208,5 +204,7 @@ void update_interaction(Level* level, LineBatch* lineBatch){ int z = (int)iend.z; player->choosenBlock = chunks->get(x,y,z)->id; } + } else { + selectedBlockId = -1; } } diff --git a/src/player_control.h b/src/player_control.h index d486b9b8..86fbc85b 100644 --- a/src/player_control.h +++ b/src/player_control.h @@ -1,13 +1,21 @@ #ifndef PLAYER_CONTROL_H_ #define PLAYER_CONTROL_H_ +#include + class PhysicsSolver; class Chunks; class Player; -class LineBatch; class Level; -void update_controls(PhysicsSolver* physics, Chunks* chunks, Player* player, float delta); -void update_interaction(Level* level, LineBatch* lineBatch); +class PlayerController { + Level* level; +public: + glm::vec3 selectedBlockPosition; + int selectedBlockId = -1; + PlayerController(Level* level); + void update_controls(float delta); + void update_interaction(); +}; #endif /* PLAYER_CONTROL_H_ */ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 31ee3cb1..74ed3206 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -78,9 +78,9 @@ void write_world(World* world, Level* level){ world->wfile->writePlayer(level->player); } -void update_level(World* world, Level* level, vec3 position, float delta, long frame, VoxelRenderer* renderer, LineBatch* lineBatch){ - update_controls(level->physics, level->chunks, level->player, delta); - update_interaction(level, lineBatch); +void update_level(World* world, Level* level, vec3 position, float delta, long frame, VoxelRenderer* renderer, PlayerController* playerController){ + playerController->update_controls(delta); + playerController->update_interaction(); level->chunks->setCenter(world->wfile, position.x, 0, position.z); int freeLoaders = level->chunksController->countFreeLoaders(); @@ -137,6 +137,7 @@ int main() { std::cout << "-- preparing systems" << std::endl; HudRenderer hud; WorldRenderer worldRenderer(level); + PlayerController playerController(level); float lastTime = glfwGetTime(); float delta = 0.0f; @@ -161,8 +162,18 @@ int main() { devdata = !devdata; } - update_level(world, level, camera->position, delta, frame, worldRenderer.renderer, worldRenderer.lineBatch); + update_level(world, level, camera->position, delta, frame, worldRenderer.renderer, &playerController); worldRenderer.draw(world, camera, assets, occlusion); + if (playerController.selectedBlockId != -1){ + Block* selectedBlock = Block::blocks[playerController.selectedBlockId]; + LineBatch* lineBatch = worldRenderer.lineBatch; + vec3 pos = playerController.selectedBlockPosition; + if (selectedBlock->model == 1){ + lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); + } else if (selectedBlock->model == 2){ + lineBatch->box(pos.x+0.4f, pos.y+0.3f, pos.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f); + } + } hud.draw(world, level, assets, devdata, fps); Window::swapBuffers(); @@ -170,6 +181,8 @@ int main() { } std::cout << "-- saving world" << std::endl; write_world(world, level); + + delete level; delete world; std::cout << "-- shutting down" << std::endl; diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index 54e80f83..c2a0f047 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -28,7 +28,7 @@ public: } void setSeed(int number){ - seed = (unsigned short)number+23729 xor (unsigned short)number+16786; + seed = ((unsigned short)number+23729 xor (unsigned short)number+16786); rand(); } }; @@ -102,7 +102,7 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ float heights[CHUNK_VOL]; - std::cout << calc_height(&noise, cx, cy) << "\n"; + // std::cout << calc_height(&noise, cx, cy) << "\n"; for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ @@ -130,11 +130,11 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ id = 1; } else { int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 16); - if (tree) + if (tree) { id = tree; - else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 19))){ + } else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 19))){ id = tree; - }else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 23))){ + } else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 23))){ id = tree; } } From fbce36a05cd26944dc82b5d44be56988966cdb4e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 1 Oct 2022 18:02:48 +0300 Subject: [PATCH 54/56] Refactor, shader fix --- res/main.glslf | 5 ++++- src/voxel_engine.cpp | 30 +++++++++++++++--------------- src/world/Level.cpp | 3 +++ src/world/Level.h | 2 ++ src/world_render.cpp | 3 ++- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/res/main.glslf b/res/main.glslf index f8197996..9f56df09 100644 --- a/res/main.glslf +++ b/res/main.glslf @@ -7,11 +7,14 @@ out vec4 f_color; uniform sampler2D u_texture0; uniform vec3 u_fogColor; +uniform float u_fogFactor; void main(){ vec4 tex_color = texture(u_texture0, a_texCoord); //if (tex_color.a < 0.5) // discard; float depth = (a_distance/256.0)*(a_distance/256.0)*256.0/6; - f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth/256.0/1.0f)); + float alpha = a_color.a * tex_color.a; + f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth*u_fogFactor)); + f_color.a = alpha; } diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 74ed3206..a24b3e92 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -78,18 +78,12 @@ void write_world(World* world, Level* level){ world->wfile->writePlayer(level->player); } -void update_level(World* world, Level* level, vec3 position, float delta, long frame, VoxelRenderer* renderer, PlayerController* playerController){ - playerController->update_controls(delta); - playerController->update_interaction(); +void update_level(World* world, Level* level, float delta, long frame, VoxelRenderer* renderer){ + level->playerController->update_controls(delta); + level->playerController->update_interaction(); + vec3 position = level->player->hitbox->position; level->chunks->setCenter(world->wfile, position.x, 0, position.z); - int freeLoaders = level->chunksController->countFreeLoaders(); - for (int i = 0; i < freeLoaders; i++) - level->chunksController->_buildMeshes(renderer, frame); - - freeLoaders = level->chunksController->countFreeLoaders(); - for (int i = 0; i < freeLoaders; i++) - level->chunksController->loadVisible(world->wfile); } Level* load_level(World* world, Player* player) { @@ -137,7 +131,6 @@ int main() { std::cout << "-- preparing systems" << std::endl; HudRenderer hud; WorldRenderer worldRenderer(level); - PlayerController playerController(level); float lastTime = glfwGetTime(); float delta = 0.0f; @@ -162,12 +155,19 @@ int main() { devdata = !devdata; } - update_level(world, level, camera->position, delta, frame, worldRenderer.renderer, &playerController); + update_level(world, level, delta, frame, worldRenderer.renderer); + int freeLoaders = level->chunksController->countFreeLoaders(); + for (int i = 0; i < freeLoaders; i++) + level->chunksController->_buildMeshes(worldRenderer.renderer, frame); + freeLoaders = level->chunksController->countFreeLoaders(); + for (int i = 0; i < freeLoaders; i++) + level->chunksController->loadVisible(world->wfile); + worldRenderer.draw(world, camera, assets, occlusion); - if (playerController.selectedBlockId != -1){ - Block* selectedBlock = Block::blocks[playerController.selectedBlockId]; + if (level->playerController->selectedBlockId != -1){ + Block* selectedBlock = Block::blocks[level->playerController->selectedBlockId]; LineBatch* lineBatch = worldRenderer.lineBatch; - vec3 pos = playerController.selectedBlockPosition; + vec3 pos = level->playerController->selectedBlockPosition; if (selectedBlock->model == 1){ lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); } else if (selectedBlock->model == 2){ diff --git a/src/world/Level.cpp b/src/world/Level.cpp index 7770d124..a04e722f 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -1,6 +1,7 @@ #include "Level.h" #include "../lighting/Lighting.h" #include "../voxels/ChunksController.h" +#include "../player_control.h" Level::Level(World* world, Player* player, Chunks* chunks, PhysicsSolver* physics) : player(player), @@ -8,6 +9,7 @@ Level::Level(World* world, Player* player, Chunks* chunks, PhysicsSolver* physic physics(physics) { lighting = new Lighting(chunks); chunksController = new ChunksController(world, chunks, lighting); + playerController = new PlayerController(this); } Level::~Level(){ @@ -16,4 +18,5 @@ Level::~Level(){ delete player; delete lighting; delete chunksController; + delete playerController; } diff --git a/src/world/Level.h b/src/world/Level.h index de4bf554..6abb74c1 100644 --- a/src/world/Level.h +++ b/src/world/Level.h @@ -7,6 +7,7 @@ class Chunks; class Lighting; class PhysicsSolver; class ChunksController; +class PlayerController; class Level { public: @@ -15,6 +16,7 @@ public: PhysicsSolver* physics; Lighting* lighting; ChunksController* chunksController; + PlayerController* playerController; Level(World* world, Player* player, Chunks* chunks, PhysicsSolver* physics); ~Level(); }; diff --git a/src/world_render.cpp b/src/world_render.cpp index 8a98dc9d..660da4c4 100644 --- a/src/world_render.cpp +++ b/src/world_render.cpp @@ -112,7 +112,8 @@ void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occl shader->uniformMatrix("u_view", camera->getView()); shader->uniform1f("u_gamma", 1.6f); shader->uniform3f("u_skyLightColor", 2.2f,2.2f,2.2f); - shader->uniform3f("u_fogColor", 0.7f,0.71f,0.73f); + shader->uniform3f("u_fogColor", 0.7f,0.81f,1.0f); + shader->uniform1f("u_fogFactor", 0.03f); shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); texture->bind(); From 8a073e4e8a303c1af7066a3fd3db04489c45aa86 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 28 Oct 2022 22:44:32 +0300 Subject: [PATCH 55/56] world-wide commit to ruin everything --- Debug/src/graphics/subdir.mk | 9 + Debug/src/subdir.mk | 3 + res/block.png | Bin 262913 -> 12498 bytes res/img.png | Bin 342 -> 793 bytes res/main.glslf | 7 +- res/main.glslv | 15 +- res/{sprite.png => slot.png} | Bin res/ui.glslv | 2 +- src/audio/Audio.cpp | 24 ++- src/audio/Audio.h | 3 +- src/declarations.cpp | 154 ++++++++++++++++ src/declarations.h | 175 +++--------------- src/files/WorldFiles.cpp | 64 ++++--- src/files/WorldFiles.h | 12 +- src/files/files.cpp | 18 +- src/graphics/Batch2D.cpp | 130 +++++++++++++- src/graphics/Batch2D.h | 14 +- src/graphics/Batch3D.cpp | 2 +- src/graphics/Font.cpp | 8 +- src/graphics/Framebuffer.cpp | 37 ++++ src/graphics/Framebuffer.h | 20 +++ src/graphics/Sprite.cpp | 17 ++ src/graphics/Sprite.h | 29 +++ src/graphics/UVRegion.cpp | 1 + src/graphics/UVRegion.h | 17 ++ src/graphics/VoxelRenderer.cpp | 307 ++++++++++++++++++++------------ src/graphics/VoxelRenderer.h | 1 + src/hud_render.cpp | 115 +++++++++--- src/hud_render.h | 10 +- src/lighting/LightSolver.cpp | 18 +- src/lighting/Lighting.cpp | 190 +++++++------------- src/lighting/Lighting.h | 4 +- src/lighting/Lightmap.h | 1 + src/loaders/png_loading.cpp | 4 + src/objects/Player.h | 1 + src/physics/PhysicsSolver.cpp | 140 ++++++++------- src/physics/PhysicsSolver.h | 8 +- src/player_control.cpp | 27 +-- src/voxel_engine.cpp | 134 +++++++------- src/voxels/Chunk.cpp | 5 +- src/voxels/Chunk.h | 40 ++++- src/voxels/Chunks.cpp | 106 +++++------ src/voxels/Chunks.h | 14 +- src/voxels/ChunksController.cpp | 260 +++++++++++++++------------ src/voxels/ChunksController.h | 2 + src/voxels/ChunksLoader.cpp | 49 +++-- src/voxels/ChunksLoader.h | 5 +- src/voxels/WorldGenerator.cpp | 33 ++-- src/voxels/WorldGenerator.h | 2 +- src/window/Camera.cpp | 14 +- src/window/Camera.h | 8 +- src/window/Window.cpp | 4 + src/window/Window.h | 1 + src/world/Level.cpp | 1 + src/world/Level.h | 1 + src/world_render.cpp | 115 ++++++------ src/world_render.h | 10 +- 57 files changed, 1433 insertions(+), 958 deletions(-) rename res/{sprite.png => slot.png} (100%) create mode 100644 src/declarations.cpp create mode 100644 src/graphics/Framebuffer.cpp create mode 100644 src/graphics/Framebuffer.h create mode 100644 src/graphics/Sprite.cpp create mode 100644 src/graphics/Sprite.h create mode 100644 src/graphics/UVRegion.cpp create mode 100644 src/graphics/UVRegion.h diff --git a/Debug/src/graphics/subdir.mk b/Debug/src/graphics/subdir.mk index 73d9da31..743d753c 100644 --- a/Debug/src/graphics/subdir.mk +++ b/Debug/src/graphics/subdir.mk @@ -11,6 +11,9 @@ CPP_SRCS += \ ../src/graphics/Mesh.cpp \ ../src/graphics/Shader.cpp \ ../src/graphics/Texture.cpp \ +../src/graphics/Sprite.cpp \ +../src/graphics/UVRegion.cpp \ +../src/graphics/Framebuffer.cpp \ ../src/graphics/VoxelRenderer.cpp OBJS += \ @@ -21,6 +24,9 @@ OBJS += \ ./src/graphics/Mesh.o \ ./src/graphics/Shader.o \ ./src/graphics/Texture.o \ +./src/graphics/Sprite.o \ +./src/graphics/UVRegion.o \ +./src/graphics/Framebuffer.o \ ./src/graphics/VoxelRenderer.o CPP_DEPS += \ @@ -31,6 +37,9 @@ CPP_DEPS += \ ./src/graphics/Mesh.d \ ./src/graphics/Shader.d \ ./src/graphics/Texture.d \ +./src/graphics/Sprite.d \ +./src/graphics/UVRegion.d \ +./src/graphics/Framebuffer.d \ ./src/graphics/VoxelRenderer.d diff --git a/Debug/src/subdir.mk b/Debug/src/subdir.mk index 68c2121d..60c123c4 100644 --- a/Debug/src/subdir.mk +++ b/Debug/src/subdir.mk @@ -8,6 +8,7 @@ CPP_SRCS += \ ../src/player_control.cpp \ ../src/hud_render.cpp \ ../src/world_render.cpp \ +../src/declarations.cpp \ ../src/voxel_engine.cpp OBJS += \ @@ -15,6 +16,7 @@ OBJS += \ ./src/player_control.o \ ./src/hud_render.o \ ./src/world_render.o \ +./src/declarations.o \ ./src/voxel_engine.o CPP_DEPS += \ @@ -22,6 +24,7 @@ CPP_DEPS += \ ./src/player_control.d \ ./src/hud_render.d \ ./src/world_render.d \ +./src/declarations.d \ ./src/voxel_engine.d diff --git a/res/block.png b/res/block.png index eb0535cd0539b6a7d1aa8207c77e3cac692737ce..e7c090d1e41f8d05bd6bd9200a6decb577010702 100644 GIT binary patch literal 12498 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 A!~g&Q literal 262913 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 JPyhYj`TufrU)}%! diff --git a/res/img.png b/res/img.png index f7704de173a6d2fcf23f2f9c02851743833aa9ce..63e4fba6b21eb32261c7f88e1d3d7ec84e4cde1f 100644 GIT binary patch literal 793 zcmV+!1LpjRP)lp7necvNxfDnSS#hl)G&K4PE)o^+;A)BR?b<6#~ zABjT6a-JbW6`+EEFbtVZr_@cuX1hlzNe~FeaYXBw-66;J4j}}K(-Vxf1X7?9t&b2$ z+OEUco=^q+x6k?V#UlD1c4$iN`gQ#n@rg5b9RS<^VO2hT2{+Bb<^Ozr)dqlLynLV_5NW)qT}Np zd9*)CHK*B(e{SAWw;gv68y+`Xdgn-!1RaMwTh8f>L7uP9*dKC)6xdI1m`)Pf&Tw;k zPx{?0n-5#AUX`S2!t%#GLI}*|TdKNdInPiesRZY`$jN{0~FFE1eC7rQ&2lncY zqO6GHh^L}NE>|H{-BQ=b27(}>svBJ6Fve1s18x|IzrAPodPP(Aw4Gr#leC>d#%V;N zVZ7#7QjuYWgKr&#<@Aj_iTi&rhJaeVSqht3pL zHp6pan?K-k7qVEHWgT;(J&#x_E z6!G#8k7*>;0H*cy)}tgn&C|e179mA|3?qiY6YCK&NtAe87$JeG81ZgkeGy}wz#7m0 XpfruEIeo9p00000NkvXXu0mjfCmwBk literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=hEVFv@zmIEGZrNluhVIAHXuLGfwB z|9MjXCvX4wAhdYvSChjhrQF%jmV+C7khzHN(SXLxta>C&eZ`VfgZc{o}-J=PL>BXZIdCV(-VE zaGJG1p~sz%XT=Qe4U9>*n3pshj1=h2VL$W#P)qpX(_ia9o-($J@tMi|g4a#9;bFs) m!`DBEzi8)_lyrxPF)%#!D+}&5S!xRmF9uInKbLh*2~7aubc+7~ diff --git a/res/main.glslf b/res/main.glslf index 9f56df09..9127e7ac 100644 --- a/res/main.glslf +++ b/res/main.glslf @@ -11,10 +11,11 @@ uniform float u_fogFactor; void main(){ vec4 tex_color = texture(u_texture0, a_texCoord); - //if (tex_color.a < 0.5) - // discard; - float depth = (a_distance/256.0)*(a_distance/256.0)*256.0/6; + float depth = (a_distance/256.0); float alpha = a_color.a * tex_color.a; + // anyway it's any alpha-test alternative required + if (alpha < 0.1f) + discard; f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth*u_fogFactor)); f_color.a = alpha; } diff --git a/res/main.glslv b/res/main.glslv index 8f3e237e..98a7acc3 100644 --- a/res/main.glslv +++ b/res/main.glslv @@ -15,12 +15,19 @@ uniform vec3 u_skyLightColor; uniform vec3 u_cameraPos; uniform float u_gamma; +uniform vec3 u_torchlightColor; +uniform float u_torchlightDistance; + void main(){ vec2 pos2d = (u_model * vec4(v_position, 1.0)).xz-u_cameraPos.xz; - vec4 viewmodelpos = u_view * u_model * vec4(v_position+vec3(0,pow(length(pos2d)*0.0, 3.0),0), 1.0); - a_color = vec4(pow(v_light.rgb, vec3(u_gamma)),1.0f); + vec4 modelpos = u_model * vec4(v_position+vec3(0,pow(length(pos2d)*0.0, 3.0),0), 1.0); + vec4 viewmodelpos = u_view * modelpos; + vec3 light = v_light.rgb; + float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz)/u_torchlightDistance); + light += torchlight * u_torchlightColor; + a_color = vec4(pow(light, vec3(u_gamma)),1.0f); a_texCoord = v_texCoord; - a_color.rgb += u_skyLightColor * v_light.a*0.5; - a_distance = length(viewmodelpos); + a_color.rgb += u_skyLightColor * v_light.a; + a_distance = pow(length(viewmodelpos), 1.5); gl_Position = u_proj * viewmodelpos; } diff --git a/res/sprite.png b/res/slot.png similarity index 100% rename from res/sprite.png rename to res/slot.png diff --git a/res/ui.glslv b/res/ui.glslv index a9110954..2b65d101 100644 --- a/res/ui.glslv +++ b/res/ui.glslv @@ -12,5 +12,5 @@ uniform mat4 u_projview; void main(){ a_textureCoord = v_textureCoord; a_color = v_color; - gl_Position = u_projview * vec4(v_position, 0.0, 1.0); + gl_Position = u_projview * vec4(v_position, 0.5, 1.0); } diff --git a/src/audio/Audio.cpp b/src/audio/Audio.cpp index 1dec8ff8..5562d2e9 100644 --- a/src/audio/Audio.cpp +++ b/src/audio/Audio.cpp @@ -15,7 +15,7 @@ std::vector Audio::freesources; std::vector Audio::allbuffers; std::vector Audio::freebuffers; -bool ALSource::setBuffer(ALBuffer* buffer){ +bool ALSource::setBuffer(ALBuffer* buffer) { alSourcei(id, AL_BUFFER, buffer->id); return alCheck(); } @@ -25,17 +25,23 @@ bool ALSource::play(){ return alCheck(); } -bool ALSource::setPosition(glm::vec3 position){ +bool ALSource::isPlaying() { + int state; + alGetSourcei(id, AL_SOURCE_STATE, &state); + return state == AL_PLAYING; +} + +bool ALSource::setPosition(glm::vec3 position) { alSource3f(id, AL_POSITION, position.x, position.y, position.z); return alCheck(); } -bool ALSource::setVelocity(glm::vec3 velocity){ +bool ALSource::setVelocity(glm::vec3 velocity) { alSource3f(id, AL_VELOCITY, velocity.x, velocity.y, velocity.z); return alCheck(); } -bool ALSource::setLoop(bool loop){ +bool ALSource::setLoop(bool loop) { alSourcei(id, AL_LOOPING, AL_TRUE ? loop : AL_FALSE); return alCheck(); } @@ -51,13 +57,13 @@ bool ALSource::setPitch(float pitch) { return alCheck(); } -bool ALBuffer::load(int format, const char* data, int size, int freq){ +bool ALBuffer::load(int format, const char* data, int size, int freq) { alBufferData(id, format, data, size, freq); return alCheck(); } -bool Audio::initialize(){ +bool Audio::initialize() { device = alcOpenDevice(nullptr); if (device == nullptr) return false; @@ -84,7 +90,9 @@ bool Audio::initialize(){ void Audio::finalize(){ for (ALSource* source : allsources){ - alSourceStop(source->id); alCheck(); + if (source->isPlaying()){ + alSourceStop(source->id); alCheck(); + } alDeleteSources(1, &source->id); alCheck(); } @@ -168,7 +176,7 @@ bool Audio::get_available_devices(std::vector& devicesVec){ return true; } -void Audio::setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up){ +void Audio::setListener(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up){ ALfloat listenerOri[] = { at.x, at.y, at.z, up.x, up.y, up.z }; alListener3f(AL_POSITION, position.x, position.y, position.z); diff --git a/src/audio/Audio.h b/src/audio/Audio.h index 9861c0bb..af0663f3 100644 --- a/src/audio/Audio.h +++ b/src/audio/Audio.h @@ -16,6 +16,7 @@ struct ALSource { ALuint id; ALSource(ALuint id) : id(id) {} + bool isPlaying(); bool setPosition(glm::vec3 position); bool setVelocity(glm::vec3 velocity); bool setBuffer(ALBuffer* buffer); @@ -54,7 +55,7 @@ public: static void finalize(); static bool get_available_devices(std::vector& devicesVec); - static void setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up); + static void setListener(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up); }; diff --git a/src/declarations.cpp b/src/declarations.cpp new file mode 100644 index 00000000..ddb6bd1d --- /dev/null +++ b/src/declarations.cpp @@ -0,0 +1,154 @@ +#include "declarations.h" + +#include "Assets.h" +#include "graphics/Shader.h" +#include "graphics/Texture.h" +#include "graphics/Font.h" +#include "window/Window.h" + +#include "voxels/Block.h" + +// Shaders, textures +bool _load_shader(Assets* assets, std::string vertex_file, std::string fragment_file, std::string name){ + Shader* shader = load_shader(vertex_file, fragment_file); + if (shader == nullptr){ + std::cerr << "failed to load shader '" << name << "'" << std::endl; + return false; + } + assets->store(shader, name); + return true; +} + +bool _load_texture(Assets* assets, std::string filename, std::string name){ + Texture* texture = load_texture(filename); + if (texture == nullptr){ + std::cerr << "failed to load texture '" << name << "'" << std::endl; + return false; + } + assets->store(texture, name); + return true; +} + +bool _load_font(Assets* assets, std::string filename, std::string name){ + std::vector pages; + for (size_t i = 0; i <= 4; i++){ + Texture* texture = load_texture(filename+"_"+std::to_string(i)+".png"); + if (texture == nullptr){ + std::cerr << "failed to load bitmap font '" << name << "' (missing page " << std::to_string(i) << ")" << std::endl; + return false; + } + pages.push_back(texture); + } + Font* font = new Font(pages); + assets->store(font, name); + return true; +} + +int initialize_assets(Assets* assets) { +#define LOAD_SHADER(VERTEX, FRAGMENT, NAME) \ + if (!_load_shader(assets, VERTEX, FRAGMENT, NAME))\ + return 1; +#define LOAD_TEXTURE(FILENAME, NAME) \ + if (!_load_texture(assets, FILENAME, NAME))\ + return 1; +#define LOAD_FONT(FILENAME, NAME) \ + if (!_load_font(assets, FILENAME, NAME))\ + return 1; + + LOAD_SHADER("res/main.glslv", "res/main.glslf", "main"); + LOAD_SHADER("res/crosshair.glslv", "res/crosshair.glslf", "crosshair"); + LOAD_SHADER("res/lines.glslv", "res/lines.glslf", "lines"); + LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui"); + + LOAD_TEXTURE("res/block.png", "block"); + LOAD_TEXTURE("res/slot.png", "slot"); + + LOAD_FONT("res/font", "normal"); + return 0; +} + +// All in-game definitions (blocks, items, etc..) +void setup_definitions() { + for (size_t i = 0; i < 256; i++) + Block::blocks[i] = nullptr; + + Block* block = new Block(BLOCK_AIR, 0); + block->drawGroup = 1; + block->lightPassing = true; + block->skyLightPassing = true; + block->obstacle = false; + block->selectable = false; + block->model = 0; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_DIRT, 2); + Block::blocks[block->id] = block; + + block = new Block(BLOCK_GRASS_BLOCK, 4); + block->textureFaces[2] = 2; + block->textureFaces[3] = 1; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_LAMP, 3); + block->emission[0] = 15; + block->emission[1] = 14; + block->emission[2] = 13; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_GLASS,5); + block->drawGroup = 2; + block->lightPassing = true; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_PLANKS, 6); + Block::blocks[block->id] = block; + + block = new Block(BLOCK_WOOD, 7); + block->textureFaces[2] = 8; + block->textureFaces[3] = 8; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_LEAVES, 9); + Block::blocks[block->id] = block; + + block = new Block(BLOCK_STONE, 10); + Block::blocks[block->id] = block; + + block = new Block(BLOCK_WATER, 11); + block->drawGroup = 4; + block->lightPassing = true; + block->skyLightPassing = false; + block->obstacle = false; + block->selectable = false; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_SAND, 12); + Block::blocks[block->id] = block; + + block = new Block(BLOCK_BEDROCK, 13); + block->breakable = false; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_GRASS, 14); + block->drawGroup = 5; + block->lightPassing = true; + block->obstacle = false; + block->model = 2; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_FLOWER, 16); + block->drawGroup = 5; + block->lightPassing = true; + block->obstacle = false; + block->model = 2; + Block::blocks[block->id] = block; + + block = new Block(BLOCK_BRICK, 17); + Block::blocks[block->id] = block; + + block = new Block(BLOCK_METAL, 18); + Block::blocks[block->id] = block; + + block = new Block(BLOCK_RUST, 19); + Block::blocks[block->id] = block; +} diff --git a/src/declarations.h b/src/declarations.h index 03491fd7..13ff14be 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -2,164 +2,29 @@ #define DECLARATIONS_H #include -#include "Assets.h" -#include "graphics/Shader.h" -#include "graphics/Texture.h" -#include "graphics/Font.h" -#include "window/Window.h" -#include "voxels/Block.h" +#define BLOCK_AIR 0 +#define BLOCK_DIRT 1 +#define BLOCK_GRASS_BLOCK 2 +#define BLOCK_LAMP 3 +#define BLOCK_GLASS 4 +#define BLOCK_PLANKS 5 +#define BLOCK_WOOD 6 +#define BLOCK_LEAVES 7 +#define BLOCK_STONE 8 +#define BLOCK_WATER 9 +#define BLOCK_SAND 10 +#define BLOCK_BEDROCK 11 +#define BLOCK_GRASS 12 +#define BLOCK_FLOWER 13 +#define BLOCK_BRICK 14 +#define BLOCK_METAL 15 +#define BLOCK_RUST 16 +class Assets; -// Shaders, textures, renderers +int initialize_assets(Assets* assets); +void setup_definitions(); -bool _load_shader(Assets* assets, std::string vertex_file, std::string fragment_file, std::string name){ - Shader* shader = load_shader(vertex_file, fragment_file); - if (shader == nullptr){ - std::cerr << "failed to load shader '" << name << "'" << std::endl; - return false; - } - assets->store(shader, name); - return true; -} - -bool _load_texture(Assets* assets, std::string filename, std::string name){ - Texture* texture = load_texture(filename); - if (texture == nullptr){ - std::cerr << "failed to load texture '" << name << "'" << std::endl; - return false; - } - assets->store(texture, name); - return true; -} - -bool _load_font(Assets* assets, std::string filename, std::string name){ - std::vector pages; - for (size_t i = 0; i <= 4; i++){ - Texture* texture = load_texture(filename+"_"+std::to_string(i)+".png"); - if (texture == nullptr){ - std::cerr << "failed to load bitmap font '" << name << "' (missing page " << std::to_string(i) << ")" << std::endl; - return false; - } - pages.push_back(texture); - } - Font* font = new Font(pages); - assets->store(font, name); - return true; -} - -int initialize_assets(Assets* assets) { -#define LOAD_SHADER(VERTEX, FRAGMENT, NAME) \ - if (!_load_shader(assets, VERTEX, FRAGMENT, NAME))\ - return 1; -#define LOAD_TEXTURE(FILENAME, NAME) \ - if (!_load_texture(assets, FILENAME, NAME))\ - return 1; -#define LOAD_FONT(FILENAME, NAME) \ - if (!_load_font(assets, FILENAME, NAME))\ - return 1; - - LOAD_SHADER("res/main.glslv", "res/main.glslf", "main"); - LOAD_SHADER("res/crosshair.glslv", "res/crosshair.glslf", "crosshair"); - LOAD_SHADER("res/lines.glslv", "res/lines.glslf", "lines"); - LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui"); - - LOAD_TEXTURE("res/block.png", "block"); - LOAD_TEXTURE("res/sprite.png", "sprite"); - - LOAD_FONT("res/font", "normal"); - return 0; -} - - -// All in-game definitions (blocks, items, etc..) -void setup_definitions() { - for (size_t i = 0; i < 256; i++) - Block::blocks[i] = nullptr; - // AIR 0 - Block* block = new Block(0,0); - block->drawGroup = 1; - block->lightPassing = true; - block->skyLightPassing = true; - block->obstacle = false; - block->selectable = false; - block->model = 0; - Block::blocks[block->id] = block; - - // DIRT 1 - block = new Block(1,2); - Block::blocks[block->id] = block; - - // GRASS BLOCK2 - block = new Block(2,4); - block->textureFaces[2] = 2; - block->textureFaces[3] = 1; - Block::blocks[block->id] = block; - - // LAMP 3 - block = new Block(3,3); - block->emission[0] = 15; - block->emission[1] = 14; - block->emission[2] = 13; - Block::blocks[block->id] = block; - - // GLASS 4 - block = new Block(4,5); - block->drawGroup = 2; - block->lightPassing = true; - Block::blocks[block->id] = block; - - // PLANKS 5 - block = new Block(5,6); - Block::blocks[block->id] = block; - - // WOOD 6 - block = new Block(6,7); - block->textureFaces[2] = 8; - block->textureFaces[3] = 8; - Block::blocks[block->id] = block; - - // LEAVES 7 - block = new Block(7,9); - Block::blocks[block->id] = block; - - // STONE 8 - block = new Block(8,10); - Block::blocks[block->id] = block; - - // WATER 9 - block = new Block(9,11); - block->drawGroup = 4; - block->lightPassing = true; - block->skyLightPassing = false; - block->obstacle = false; - block->selectable = false; - Block::blocks[block->id] = block; - - // SAND 10 - block = new Block(10,12); - Block::blocks[block->id] = block; - - // BEDROCK 11 - block = new Block(11,13); - block->breakable = false; - Block::blocks[block->id] = block; - - // GRASS 12 - block = new Block(12,14); - block->drawGroup = 5; - block->lightPassing = true; - block->obstacle = false; - block->model = 2; - Block::blocks[block->id] = block; - - // FLOWER 13 - block = new Block(13,16); - block->drawGroup = 5; - block->lightPassing = true; - block->obstacle = false; - block->model = 2; - Block::blocks[block->id] = block; -} #endif // DECLARATIONS_H diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index f9ae26ba..84388a72 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -19,6 +19,9 @@ union { #define SECTION_POSITION 1 #define SECTION_ROTATION 2 +#define SECTION_FLAGS 3 +#define PLAYER_FLAG_FLIGHT 0x1 +#define PLAYER_FLAG_NOCLIP 0x2 unsigned long WorldFiles::totalCompressed = 0; @@ -33,7 +36,7 @@ void int2Bytes(int value, char* dest, unsigned int offset){ dest[offset+3] = (char) (value >> 0 & 255); } -void float2Bytes(float fvalue, char* dest, unsigned int offset){ +void floatToBytes(float fvalue, char* dest, unsigned int offset){ uint32_t value = *((uint32_t*)&fvalue); dest[offset] = (char) (value >> 24 & 255); dest[offset+1] = (char) (value >> 16 & 255); @@ -58,15 +61,15 @@ WorldFiles::WorldFiles(std::string directory, size_t mainBufferCapacity) : direc WorldFiles::~WorldFiles(){ delete[] mainBufferIn; delete[] mainBufferOut; - std::unordered_map::iterator it; + std::unordered_map::iterator it; for (it = regions.begin(); it != regions.end(); it++){ - char** region = it->second; - if (region == nullptr) + WorldRegion region = it->second; + if (region.chunksData == nullptr) continue; for (unsigned int i = 0; i < REGION_VOL; i++){ - delete[] region[i]; + delete[] region.chunksData[i]; } - delete[] region; + delete[] region.chunksData; } regions.clear(); } @@ -82,17 +85,17 @@ void WorldFiles::put(const char* chunkData, int x, int y){ _tempcoords._coords[0] = regionX; _tempcoords._coords[1] = regionY; - char** region = regions[_tempcoords._key]; - if (region == nullptr){ - region = new char*[REGION_VOL]; + WorldRegion& region = regions[_tempcoords._key]; + region.unsaved = true; + if (region.chunksData == nullptr){ + region.chunksData = new char*[REGION_VOL]; for (unsigned int i = 0; i < REGION_VOL; i++) - region[i] = nullptr; - regions[_tempcoords._key] = region; + region.chunksData[i] = nullptr; } - char* targetChunk = region[localY * REGION_SIZE + localX]; + char* targetChunk = region.chunksData[localY * REGION_SIZE + localX]; if (targetChunk == nullptr){ targetChunk = new char[CHUNK_VOL]; - region[localY * REGION_SIZE + localX] = targetChunk; + region.chunksData[localY * REGION_SIZE + localX] = targetChunk; totalCompressed += CHUNK_VOL; } for (unsigned int i = 0; i < CHUNK_VOL; i++) @@ -122,11 +125,11 @@ bool WorldFiles::getChunk(int x, int y, char* out){ _tempcoords._coords[0] = regionX; _tempcoords._coords[1] = regionY; - char** region = regions[_tempcoords._key]; - if (region == nullptr) + WorldRegion& region = regions[_tempcoords._key]; + if (region.chunksData == nullptr) return readChunk(x,y,out); - char* chunk = region[chunkIndex]; + char* chunk = region.chunksData[chunkIndex]; if (chunk == nullptr) return readChunk(x,y,out); for (unsigned int i = 0; i < CHUNK_VOL; i++) @@ -174,34 +177,38 @@ bool WorldFiles::readChunk(int x, int y, char* out){ } void WorldFiles::write(){ - std::unordered_map::iterator it; + std::unordered_map::iterator it; for (it = regions.begin(); it != regions.end(); it++){ - if (it->second == nullptr) + if (it->second.chunksData == nullptr || !it->second.unsaved) continue; int x; int y; longToCoords(x,y, it->first); - unsigned int size = writeRegion(mainBufferOut, x,y, it->second); + unsigned int size = writeRegion(mainBufferOut, x,y, it->second.chunksData); write_binary_file(getRegionFile(x,y), mainBufferOut, size); } } void WorldFiles::writePlayer(Player* player){ - char dst[1+3*4 + 1+2*4]; + char dst[1+3*4 + 1+2*4 + 1+1]; glm::vec3 position = player->hitbox->position; size_t offset = 0; dst[offset++] = SECTION_POSITION; - float2Bytes(position.x, dst, offset); offset += 4; - float2Bytes(position.y, dst, offset); offset += 4; - float2Bytes(position.z, dst, offset); offset += 4; + floatToBytes(position.x, dst, offset); offset += 4; + floatToBytes(position.y, dst, offset); offset += 4; + floatToBytes(position.z, dst, offset); offset += 4; dst[offset++] = SECTION_ROTATION; - float2Bytes(player->camX, dst, offset); offset += 4; - float2Bytes(player->camY, dst, offset); offset += 4; + floatToBytes(player->camX, dst, offset); offset += 4; + floatToBytes(player->camY, dst, offset); offset += 4; + + dst[offset++] = SECTION_FLAGS; + dst[offset++] = player->flight * PLAYER_FLAG_FLIGHT | + player->noclip * PLAYER_FLAG_NOCLIP; write_binary_file(getPlayerFile(), (const char*)dst, sizeof(dst)); } @@ -227,6 +234,13 @@ bool WorldFiles::readPlayer(Player* player) { player->camX = bytes2Float(data, offset); offset += 4; player->camY = bytes2Float(data, offset); offset += 4; break; + case SECTION_FLAGS: + { + unsigned char flags = data[offset++]; + player->flight = flags & PLAYER_FLAG_FLIGHT; + player->noclip = flags & PLAYER_FLAG_NOCLIP; + } + break; } } player->hitbox->position = position; diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index 9ee11778..93d50db0 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -12,15 +12,15 @@ class Player; #define REGION_SIZE (1 << (REGION_SIZE_BIT)) #define REGION_VOL ((REGION_SIZE) * (REGION_SIZE)) -/* Требование: - * - высота мира = 1 чанк (любых размеров) - * Пример: - * - CHUNK_W = 16, CHUNK_H = 128, CHUNK_D = 16 - * */ +struct WorldRegion { + char** chunksData; + bool unsaved; +}; + class WorldFiles { public: static unsigned long totalCompressed; - std::unordered_map regions; + std::unordered_map regions; std::string directory; char* mainBufferIn; char* mainBufferOut; diff --git a/src/files/files.cpp b/src/files/files.cpp index 2344128b..783faa2a 100644 --- a/src/files/files.cpp +++ b/src/files/files.cpp @@ -69,16 +69,17 @@ unsigned int decompressRLE(const char* src, unsigned int length, char* dst, unsi unsigned int calcRLE(const char* src, unsigned int length) { unsigned int offset = 0; - unsigned int counter = 1; + unsigned int counter = 0; char c = src[0]; for (unsigned int i = 0; i < length; i++){ char cnext = src[i]; - if (cnext != c || counter == 256){ + if (cnext != c || counter == 255){ offset += 2; c = cnext; counter = 0; + } else { + counter++; } - counter++; } return offset + 2; } @@ -86,19 +87,20 @@ unsigned int calcRLE(const char* src, unsigned int length) { // max result size = length * 2; returns compressed length unsigned int compressRLE(const char* src, unsigned int length, char* dst) { unsigned int offset = 0; - unsigned int counter = 1; + unsigned int counter = 0; char c = src[0]; for (unsigned int i = 1; i < length; i++){ char cnext = src[i]; - if (cnext != c || counter == 256){ - dst[offset++] = counter-1; + if (cnext != c || counter == 255){ + dst[offset++] = counter; dst[offset++] = c; c = cnext; counter = 0; + } else { + counter++; } - counter++; } - dst[offset++] = counter-1; + dst[offset++] = counter; dst[offset++] = c; return offset; } diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index 4cde0087..acb9f2ec 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -1,6 +1,7 @@ #include "Batch2D.h" #include "Mesh.h" #include "Texture.h" +#include "Sprite.h" #include @@ -86,6 +87,116 @@ void Batch2D::rect(float x, float y, float w, float h){ vertex(x+w, y+h, 1, 1, r,g,b,a); } +void Batch2D::rect( + float x, float y, + float w, float h, + float ox, float oy, + float angle, + UVRegion region, + bool flippedX, + bool flippedY, + vec4 tint) { + if (index + 6*VERTEX_SIZE >= capacity) + render(); + + float centerX = w*ox; + float centerY = h*oy; + float acenterX = w-centerX; + float acenterY = h-centerY; + + float _x1 = -centerX; + float _y1 = -centerY; + + float _x2 = -centerX; + float _y2 = +acenterY; + + float _x3 = +acenterX; + float _y3 = +acenterY; + + float _x4 = +acenterX; + float _y4 = -centerY; + + float x1,y1,x2,y2,x3,y3,x4,y4; + + if (angle != 0) { + float s = sin(angle); + float c = cos(angle); + + x1 = c * _x1 - s * _y1; + y1 = s * _x1 + c * _y1; + + x2 = c * _x2 - s * _y2; + y2 = s * _x2 + c * _y2; + + x3 = c * _x3 - s * _y3; + y3 = s * _x3 + c * _y3; + + x4 = x1 + (x3 - x2); + y4 = y3 - (y2 - y1); + } else { + x1 = _x1; + y1 = _y1; + x2 = _x2; + y2 = _y2; + x3 = _x3; + y3 = _y3; + x4 = _x4; + y4 = _y4; + } + + x1 += x; x2 += x; x3 += x; x4 += x; + y1 += y; y2 += y; y3 += y; y4 += y; + + float u1 = region.u1; + float v1 = region.v1; + float u2 = region.u1; + float v2 = region.v2; + float u3 = region.u2; + float v3 = region.v2; + float u4 = region.u2; + float v4 = region.v1; + + if (flippedX) { + float temp = u1; + u1 = u3; + u4 = temp; + u2 = u3; + u3 = temp; + } + if (flippedY) { + float temp = v1; + v1 = v2; + v4 = v2; + v2 = temp; + v3 = temp; + } + + vertex(x1, y1, u1, v1, tint.r, tint.g, tint.b, tint.a); + vertex(x2, y2, u2, v2, tint.r, tint.g, tint.b, tint.a); + vertex(x3, y3, u3, v3, tint.r, tint.g, tint.b, tint.a); + + /* Right down triangle */ + vertex(x1, y1, u1, v1, tint.r, tint.g, tint.b, tint.a); + vertex(x3, y3, u3, v3, tint.r, tint.g, tint.b, tint.a); + vertex(x4, y4, u4, v4, tint.r, tint.g, tint.b, tint.a); +} + +void Batch2D::sprite(Sprite* sprite) { + vec2 position = sprite->position; + vec2 size = sprite->size; + vec2 origin = sprite->origin; + texture(sprite->texture); + rect( + position.x, position.y, + size.x, size.y, + origin.x, origin.y, + sprite->angle, + sprite->region, + sprite->flippedX, + sprite->flippedY, + sprite->color); +} + void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index, vec4 tint){ float scale = 1.0f / (float)atlasRes; float u = (index % atlasRes) * scale; @@ -99,16 +210,19 @@ void Batch2D::blockSprite(float x, float y, float w, float h, int atlasRes, int float vu = 1.0f - ((index[3] / atlasRes) * scale) - scale; float uf = (index[0] % atlasRes) * scale; float vf = 1.0f - ((index[0] / atlasRes) * scale) - scale; - if (index[0] + 6*VERTEX_SIZE >= capacity) + if (this->index + 18*VERTEX_SIZE >= capacity) render(); - vec2 points[7] = {vec2(x+(w*0.5f), y+(h*0.5f)), - vec2(x, y+(h*0.25f)), - vec2(x+(w*0.5f), y), - vec2(x+w, y+(h*0.25f)), - vec2(x+w, y+(h*0.75f)), - vec2(x+(w*0.5f), y+h), - vec2(x, y+(h*0.75f))}; + float ar = 0.88f; + float ox = x + (w * 0.5f); + float sx = w * 0.5f * ar; + vec2 points[7] = {vec2(ox, y+(h*0.5f)), + vec2(ox-sx, y+(h*0.25f)), + vec2(ox, y), + vec2(ox+sx, y+(h*0.25f)), + vec2(ox+sx, y+(h*0.75f)), + vec2(ox, y+h), + vec2(ox-sx, y+(h*0.75f))}; vec2 uvpoints[8] = {vec2(uu, vu), vec2(uu+scale, vu), diff --git a/src/graphics/Batch2D.h b/src/graphics/Batch2D.h index 814305f9..0c9b69e8 100644 --- a/src/graphics/Batch2D.h +++ b/src/graphics/Batch2D.h @@ -4,16 +4,18 @@ #include #include +#include "UVRegion.h" + using namespace glm; class Mesh; class Texture; +class Sprite; class Batch2D { float* buffer; size_t capacity; size_t offset; - glm::vec4 color; Mesh* mesh; size_t index; @@ -28,13 +30,23 @@ class Batch2D { float r, float g, float b, float a); public: + glm::vec4 color; + Batch2D(size_t capacity); ~Batch2D(); void begin(); void texture(Texture* texture); void sprite(float x, float y, float w, float h, int atlasRes, int index, vec4 tint); + void sprite(Sprite* sprite); void blockSprite(float x, float y, float w, float h, int atlasRes, int index[6], vec4 tint); + void rect(float x, float y, + float w, float h, + float ox, float oy, + float angle, UVRegion region, + bool flippedX, bool flippedY, + vec4 tint); + void rect(float x, float y, float w, float h); void rect(float x, float y, float w, float h, float u, float v, float tx, float ty, diff --git a/src/graphics/Batch3D.cpp b/src/graphics/Batch3D.cpp index 40c91cb6..2531969a 100644 --- a/src/graphics/Batch3D.cpp +++ b/src/graphics/Batch3D.cpp @@ -7,7 +7,7 @@ #define VERTEX_SIZE 9 -Batch3D::Batch3D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){ +Batch3D::Batch3D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 0.0f){ const int attrs[] = { 3, 2, 4, 0 //null terminator }; diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index 96d9c30e..3e881503 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -19,9 +19,9 @@ int Font::getGlyphWidth(char c) { case '.': case ',': case ':': - case ';': return 3; - case 't': return 5; - case ' ': return 3; + case ';': return 7; + case 't': return 8; + case ' ': return 7; } return 7; } @@ -75,7 +75,7 @@ void Font::draw(Batch2D* batch, std::wstring text, int x, int y, int style) { break; } - batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); + batch->sprite(x, y, RES, RES, 16, c, batch->color); } else if (charpage > page && charpage < next){ next = charpage; diff --git a/src/graphics/Framebuffer.cpp b/src/graphics/Framebuffer.cpp new file mode 100644 index 00000000..287be8e5 --- /dev/null +++ b/src/graphics/Framebuffer.cpp @@ -0,0 +1,37 @@ +#include "Framebuffer.h" + +#include +#include "Texture.h" + +Framebuffer::Framebuffer(int width, int height) : width(width), height(height) { + glGenFramebuffers(1, &fbo); + bind(); + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + texture = new Texture(tex, width, height); + glGenRenderbuffers(1, &depth); + glBindRenderbuffer(GL_RENDERBUFFER, depth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); + unbind(); +} + +Framebuffer::~Framebuffer() { + delete texture; + glDeleteFramebuffers(1, &fbo); +} + +void Framebuffer::bind() { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); +} + +void Framebuffer::unbind() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} diff --git a/src/graphics/Framebuffer.h b/src/graphics/Framebuffer.h new file mode 100644 index 00000000..3fd889f2 --- /dev/null +++ b/src/graphics/Framebuffer.h @@ -0,0 +1,20 @@ +#ifndef SRC_GRAPHICS_FRAMEBUFFER_H_ +#define SRC_GRAPHICS_FRAMEBUFFER_H_ + +class Texture; + +class Framebuffer { + unsigned int fbo; + unsigned int depth; +public: + int width; + int height; + Texture* texture; + Framebuffer(int width, int height); + ~Framebuffer(); + + void bind(); + void unbind(); +}; + +#endif /* SRC_GRAPHICS_FRAMEBUFFER_H_ */ diff --git a/src/graphics/Sprite.cpp b/src/graphics/Sprite.cpp new file mode 100644 index 00000000..3b0ca50f --- /dev/null +++ b/src/graphics/Sprite.cpp @@ -0,0 +1,17 @@ +#include "Sprite.h" + +#include "Texture.h" + +Sprite::Sprite(glm::vec2 position, glm::vec2 size, Texture* texture) + : position(position), + size(size), + origin(0.5f, 0.5f), + color(1.0f, 1.0f, 1.0f, 1.0f), + angle(0.0f), + texture(texture), + region() { +} + +Sprite::~Sprite() { +} + diff --git a/src/graphics/Sprite.h b/src/graphics/Sprite.h new file mode 100644 index 00000000..5d10038e --- /dev/null +++ b/src/graphics/Sprite.h @@ -0,0 +1,29 @@ +#ifndef SRC_GRAPHICS_SPRITE_H_ +#define SRC_GRAPHICS_SPRITE_H_ + +#include +#include "UVRegion.h" + +class Texture; + +class Sprite { +public: + glm::vec2 position; + glm::vec2 size; + glm::vec2 origin; + glm::vec4 color; + float angle; + bool flippedX = false; + bool flippedY = false; + Texture* texture; + UVRegion region; + + Sprite(glm::vec2 position, glm::vec2 size, Texture* texture); + virtual ~Sprite(); + + void setTexture(Texture* texture) { + this->texture = texture; + } +}; + +#endif /* SRC_GRAPHICS_SPRITE_H_ */ diff --git a/src/graphics/UVRegion.cpp b/src/graphics/UVRegion.cpp new file mode 100644 index 00000000..3f421522 --- /dev/null +++ b/src/graphics/UVRegion.cpp @@ -0,0 +1 @@ +#include "UVRegion.h" diff --git a/src/graphics/UVRegion.h b/src/graphics/UVRegion.h new file mode 100644 index 00000000..a59f6c30 --- /dev/null +++ b/src/graphics/UVRegion.h @@ -0,0 +1,17 @@ +#ifndef SRC_GRAPHICS_UVREGION_H_ +#define SRC_GRAPHICS_UVREGION_H_ + +class UVRegion { +public: + float u1; + float v1; + float u2; + float v2; + + UVRegion(float u1, float v1, float u2, float v2) + : u1(u1), v1(v1), u2(u2), v2(v2){} + + UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){} +}; + +#endif /* SRC_GRAPHICS_UVREGION_H_ */ diff --git a/src/graphics/VoxelRenderer.cpp b/src/graphics/VoxelRenderer.cpp index 7e17d676..7e9ed7fc 100644 --- a/src/graphics/VoxelRenderer.cpp +++ b/src/graphics/VoxelRenderer.cpp @@ -12,7 +12,7 @@ #define LOCAL_NEG(X, SIZE) (((X) < 0) ? ((SIZE)+(X)) : (X)) #define LOCAL(X, SIZE) ((X) >= (SIZE) ? ((X) - (SIZE)) : LOCAL_NEG(X, SIZE)) #define IS_CHUNK(X,Y,Z) (GET_CHUNK(X,Y,Z) != nullptr) -#define GET_CHUNK(X,Y,Z) (chunks[((CDIV(Y, CHUNK_H)+1) * 3 + CDIV(Z, CHUNK_D) + 1) * 3 + CDIV(X, CHUNK_W) + 1]) +#define GET_CHUNK(X,Y,Z) (chunks[(CDIV(Z, CHUNK_D) + 1) * 3 + CDIV(X, CHUNK_W) + 1]) #define LIGHT(X,Y,Z, CHANNEL) (IS_CHUNK(X,Y,Z) ? GET_CHUNK(X,Y,Z)->lightmap->get(LOCAL(X, CHUNK_W), LOCAL(Y, CHUNK_H), LOCAL(Z, CHUNK_D), (CHANNEL)) : 0) #define VOXEL(X,Y,Z) (GET_CHUNK(X,Y,Z)->voxels[(LOCAL(Y, CHUNK_H) * CHUNK_D + LOCAL(Z, CHUNK_D)) * CHUNK_W + LOCAL(X, CHUNK_W)]) @@ -43,13 +43,7 @@ VoxelRenderer::VoxelRenderer() { VoxelRenderer::~VoxelRenderer(){ } -inline void _renderBlock(std::vector& buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){ - unsigned int id = vox.id; - - if (!id){ - return; - } - +inline void _renderBlock(std::vector& buffer, int x, int y, int z, const Chunk** chunks, unsigned int id, size_t& index){ float l; float uvsize = 1.0f/16.0f; @@ -61,10 +55,10 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const SETUP_UV(block->textureFaces[3]); - float lr = LIGHT(x,y+1,z, 0) / 15.0f; - float lg = LIGHT(x,y+1,z, 1) / 15.0f; - float lb = LIGHT(x,y+1,z, 2) / 15.0f; - float ls = LIGHT(x,y+1,z, 3) / 15.0f; + const float lr = LIGHT(x,y+1,z, 0) / 15.0f; + const float lg = LIGHT(x,y+1,z, 1) / 15.0f; + const float lb = LIGHT(x,y+1,z, 2) / 15.0f; + const float ls = LIGHT(x,y+1,z, 3) / 15.0f; float lr0 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 75.0f; float lr1 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 75.0f; @@ -99,10 +93,10 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const SETUP_UV(block->textureFaces[2]); - float lr = LIGHT(x,y-1,z, 0) / 15.0f; - float lg = LIGHT(x,y-1,z, 1) / 15.0f; - float lb = LIGHT(x,y-1,z, 2) / 15.0f; - float ls = LIGHT(x,y-1,z, 3) / 15.0f; + const float lr = LIGHT(x,y-1,z, 0) / 15.0f; + const float lg = LIGHT(x,y-1,z, 1) / 15.0f; + const float lb = LIGHT(x,y-1,z, 2) / 15.0f; + const float ls = LIGHT(x,y-1,z, 3) / 15.0f; float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 75.0f; float lr1 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 75.0f; @@ -138,10 +132,10 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const SETUP_UV(block->textureFaces[1]); - float lr = LIGHT(x+1,y,z, 0) / 15.0f; - float lg = LIGHT(x+1,y,z, 1) / 15.0f; - float lb = LIGHT(x+1,y,z, 2) / 15.0f; - float ls = LIGHT(x+1,y,z, 3) / 15.0f; + const float lr = LIGHT(x+1,y,z, 0) / 15.0f; + const float lg = LIGHT(x+1,y,z, 1) / 15.0f; + const float lb = LIGHT(x+1,y,z, 2) / 15.0f; + const float ls = LIGHT(x+1,y,z, 3) / 15.0f; float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f; float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f; @@ -176,10 +170,10 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const SETUP_UV(block->textureFaces[0]); - float lr = LIGHT(x-1,y,z, 0) / 15.0f; - float lg = LIGHT(x-1,y,z, 1) / 15.0f; - float lb = LIGHT(x-1,y,z, 2) / 15.0f; - float ls = LIGHT(x-1,y,z, 3) / 15.0f; + const float lr = LIGHT(x-1,y,z, 0) / 15.0f; + const float lg = LIGHT(x-1,y,z, 1) / 15.0f; + const float lb = LIGHT(x-1,y,z, 2) / 15.0f; + const float ls = LIGHT(x-1,y,z, 3) / 15.0f; float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y-1,z,0)) / 75.0f; float lr1 = (LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y+1,z,0)) / 75.0f; @@ -215,10 +209,10 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const SETUP_UV(block->textureFaces[5]); - float lr = LIGHT(x,y,z+1, 0) / 15.0f; - float lg = LIGHT(x,y,z+1, 1) / 15.0f; - float lb = LIGHT(x,y,z+1, 2) / 15.0f; - float ls = LIGHT(x,y,z+1, 3) / 15.0f; + const float lr = LIGHT(x,y,z+1, 0) / 15.0f; + const float lg = LIGHT(x,y,z+1, 1) / 15.0f; + const float lb = LIGHT(x,y,z+1, 2) / 15.0f; + const float ls = LIGHT(x,y,z+1, 3) / 15.0f; float lr0 = l*(LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 75.0f; float lr1 = l*(LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 75.0f; @@ -253,10 +247,10 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const SETUP_UV(block->textureFaces[4]); - float lr = LIGHT(x,y,z-1, 0) / 15.0f; - float lg = LIGHT(x,y,z-1, 1) / 15.0f; - float lb = LIGHT(x,y,z-1, 2) / 15.0f; - float ls = LIGHT(x,y,z-1, 3) / 15.0f; + const float lr = LIGHT(x,y,z-1, 0) / 15.0f; + const float lg = LIGHT(x,y,z-1, 1) / 15.0f; + const float lb = LIGHT(x,y,z-1, 2) / 15.0f; + const float ls = LIGHT(x,y,z-1, 3) / 15.0f; float lr0 = l*(LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 75.0f; float lr1 = l*(LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 75.0f; @@ -288,8 +282,82 @@ inline void _renderBlock(std::vector& buffer, int x, int y, int z, const } } +inline void _renderBlockShadeless(std::vector& buffer, int x, int y, int z, const Chunk** chunks, unsigned int id, size_t& index){ + float l; + float uvsize = 1.0f/16.0f; + Block* block = Block::blocks[id]; + unsigned char group = block->drawGroup; + if (!IS_BLOCKED(x,y+1,z,group)){ + SETUP_UV(block->textureFaces[3]); + + VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0); + + VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v1, 1,1,1,0); + } + if (!IS_BLOCKED(x,y-1,z,group)){ + SETUP_UV(block->textureFaces[2]); + + VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, 1,1,1,0); + VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v2, 1,1,1,0); + + VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, 1,1,1,0); + } + + if (!IS_BLOCKED(x+1,y,z,group)){ + SETUP_UV(block->textureFaces[1]); + + VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u2,v2, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0); + + VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0); + VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u1,v1, 1,1,1,0); + } + if (!IS_BLOCKED(x-1,y,z,group)){ + SETUP_UV(block->textureFaces[0]); + + VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0); + VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0); + VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u1,v2, 1,1,1,0); + + VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0); + VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0); + } + + if (!IS_BLOCKED(x,y,z+1,group)){ + SETUP_UV(block->textureFaces[5]); + + VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0); + VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0); + + VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0); + } + if (!IS_BLOCKED(x,y,z-1,group)){ + SETUP_UV(block->textureFaces[4]); + + VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v2, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, 1,1,1,0); + + VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0); + VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, 1,1,1,0); + VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0); + } +} inline void _renderXBlock(std::vector& buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){ @@ -304,101 +372,88 @@ inline void _renderXBlock(std::vector& buffer, int x, int y, int z, const return; } - float l; float uvsize = 1.0f/16.0f; - float lr = LIGHT(x,y,z, 0) / 15.0f; - float lg = LIGHT(x,y,z, 1) / 15.0f; - float lb = LIGHT(x,y,z, 2) / 15.0f; - float ls = LIGHT(x,y,z, 3) / 15.0f; + float lr = LIGHT(x,y,z, 0) / 15.0f; + float lg = LIGHT(x,y,z, 1) / 15.0f; + float lb = LIGHT(x,y,z, 2) / 15.0f; + float ls = LIGHT(x,y,z, 3) / 15.0f; - float lr0 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; - float lr1 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; - float lr2 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; - float lr3 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; - float lr4 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; - float lr5 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; - float lr6 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; - float lr7 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + float lr0 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + float lr1 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr2 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr3 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + float lr4 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; + float lr5 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr6 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f; + float lr7 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f; - float lg0 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; - float lg1 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; - float lg2 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; - float lg3 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; - float lg4 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; - float lg5 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; - float lg6 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; - float lg7 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + float lg0 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + float lg1 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg2 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg3 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + float lg4 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; + float lg5 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg6 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f; + float lg7 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f; - float lb0 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; - float lb1 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; - float lb2 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; - float lb3 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; - float lb4 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; - float lb5 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; - float lb6 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; - float lb7 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + float lb0 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + float lb1 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb2 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb3 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + float lb4 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; + float lb5 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb6 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f; + float lb7 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f; - float ls0 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; - float ls1 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; - float ls2 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; - float ls3 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; - float ls4 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; - float ls5 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; - float ls6 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; - float ls7 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + float ls0 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + float ls1 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls2 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls3 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + float ls4 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + float ls5 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls6 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f; + float ls7 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f; + {SETUP_UV(block->textureFaces[1]); - l = 0.95f; + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr1,lg1,lb1,ls1); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); - {SETUP_UV(block->textureFaces[1]); + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); + VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr3,lg3,lb3,ls3);} - VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0); - VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr1,lg1,lb1,ls1); - VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); + {SETUP_UV(block->textureFaces[0]); - VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0); - VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); - VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr3,lg3,lb3,ls3);} - - - l = 0.85f; + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1); + VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); - {SETUP_UV(block->textureFaces[0]); + VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0); + VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr3,lg3,lb3,ls3); + VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);} - VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0); - VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1); - VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr2,lg2,lb2,ls2); + {SETUP_UV(block->textureFaces[5]); - VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0); - VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr3,lg3,lb3,ls3); - VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);} - - - l = 0.9f; + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5); + VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); - {SETUP_UV(block->textureFaces[5]); + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr7,lg7,lb7,ls7); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);} - VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4); - VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5); - VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); + {SETUP_UV(block->textureFaces[4]); - VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4); - VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr7,lg7,lb7,ls7); - VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);} + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr5,lg5,lb5,ls5); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); - - l = 0.8f; - - {SETUP_UV(block->textureFaces[4]); - - VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4); - VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr5,lg5,lb5,ls5); - VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); - - VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4); - VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); - VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr7,lg7,lb7,ls7);} + VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4); + VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6); + VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr7,lg7,lb7,ls7);} } const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& size){ @@ -408,9 +463,15 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; + if (vox.id == 0) + continue; if (vox.id == 9 || vox.id == 4 || vox.id == 12 || vox.id == 13) continue; - _renderBlock(buffer, x, y, z, chunks, vox, index); + Block* block = Block::blocks[vox.id]; + if (block->emission[0] || block->emission[1] || block->emission[2]){ + continue; + } + _renderBlock(buffer, x, y, z, chunks, vox.id, index); } } } @@ -419,9 +480,25 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; + if (vox.id == 0) + continue; + Block* block = Block::blocks[vox.id]; + if (block->emission[0] || block->emission[1] || block->emission[2]){ + _renderBlockShadeless(buffer, x, y, z, chunks, vox.id, index); + } + } + } + } + + for (int y = 0; y < CHUNK_H; y++){ + for (int z = 0; z < CHUNK_D; z++){ + for (int x = 0; x < CHUNK_W; x++){ + voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; + if (vox.id == 0) + continue; if (vox.id != 9) continue; - _renderBlock(buffer, x, y, z, chunks, vox, index); + _renderBlock(buffer, x, y, z, chunks, vox.id, index); } } } @@ -430,7 +507,9 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; - if (vox.id != 12 && vox.id != 13) + if (vox.id == 0) + continue; + if (Block::blocks[vox.id]->model != BLOCK_MODEL_GRASS) continue; _renderXBlock(buffer, x, y, z, chunks, vox, index); } @@ -441,9 +520,11 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; + if (vox.id == 0) + continue; if (vox.id != 4) continue; - _renderBlock(buffer, x, y, z, chunks, vox, index); + _renderBlock(buffer, x, y, z, chunks, vox.id, index); } } } diff --git a/src/graphics/VoxelRenderer.h b/src/graphics/VoxelRenderer.h index 84e38238..3e1d545c 100644 --- a/src/graphics/VoxelRenderer.h +++ b/src/graphics/VoxelRenderer.h @@ -12,6 +12,7 @@ class Chunk; class VoxelRenderer { public: std::vector buffer; + unsigned char lights[27 * 4]; VoxelRenderer(); ~VoxelRenderer(); diff --git a/src/hud_render.cpp b/src/hud_render.cpp index 78da460a..62894d66 100644 --- a/src/hud_render.cpp +++ b/src/hud_render.cpp @@ -1,12 +1,15 @@ #include "hud_render.h" #include +#include #include "Assets.h" #include "graphics/Shader.h" #include "graphics/Batch2D.h" #include "graphics/Font.h" +#include "graphics/Mesh.h" #include "window/Camera.h" #include "window/Window.h" +#include "window/Events.h" #include "voxels/Chunks.h" #include "voxels/Block.h" #include "world/World.h" @@ -15,6 +18,19 @@ HudRenderer::HudRenderer() { + float vertices[] = { + // x y + -0.01f,-0.01f, + 0.01f, 0.01f, + + -0.01f, 0.01f, + 0.01f,-0.01f, + }; + int attrs[] = { + 2, 0 //null terminator + }; + crosshair = new Mesh(vertices, 4, attrs); + batch = new Batch2D(1024); uicamera = new Camera(glm::vec3(), Window::height / 1.0f); uicamera->perspective = false; @@ -22,48 +38,103 @@ HudRenderer::HudRenderer() { } HudRenderer::~HudRenderer() { + delete crosshair; delete batch; delete uicamera; } - -void HudRenderer::draw(World* world, Level* level, Assets* assets, bool devdata, int fps){ +void HudRenderer::drawDebug(Level* level, Assets* assets, int fps, bool occlusion){ Chunks* chunks = level->chunks; Player* player = level->player; + Font* font = assets->getFont("normal"); + + Shader* uishader = assets->getShader("ui"); + uishader->use(); + uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); + batch->color = vec4(1.0f); + batch->begin(); + font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.y), 50, 30, STYLE_OUTLINE); + font->draw(batch, std::to_wstring((int)player->camera->position.z), 90, 30, STYLE_OUTLINE); + font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE); + font->draw(batch, std::to_wstring(fps), 44, 42, STYLE_OUTLINE); + font->draw(batch, L"occlusion: "+std::to_wstring(occlusion), 16, 54, STYLE_OUTLINE); + batch->render(); +} + + +void HudRenderer::draw(Level* level, Assets* assets){ + uicamera->fov = Window::height; + glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); + Shader* uishader = assets->getShader("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); - // Draw debug info - Font* font = assets->getFont("normal"); - batch->begin(); - if (devdata){ - font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE); - font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE); - font->draw(batch, std::to_wstring((int)player->camera->position.y), 50, 30, STYLE_OUTLINE); - font->draw(batch, std::to_wstring((int)player->camera->position.z), 90, 30, STYLE_OUTLINE); - font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE); - font->draw(batch, std::to_wstring(fps), 40, 42, STYLE_OUTLINE); - } - batch->render(); - // Chosen block preview Texture* blocks = assets->getTexture("block"); - Texture* sprite = assets->getTexture("sprite"); + Texture* sprite = assets->getTexture("slot"); + if (!Events::_cursor_locked) { + batch->texture(nullptr); + batch->color = vec4(0.0f, 0.0f, 0.0f, 0.5f); + batch->rect(0, 0, Window::width, Window::height); + } + + batch->color = vec4(1.0f); batch->texture(sprite); - batch->sprite(16, 640, 64, 64, 16, 0, vec4(1.0f)); + batch->sprite(16, uicamera->fov - 80, 64, 64, 16, 0, vec4(1.0f)); batch->texture(blocks); - Block* cblock = Block::blocks[player->choosenBlock]; - if (cblock->model == BLOCK_MODEL_CUBE){ - batch->blockSprite(24, 648, 48, 48, 16, cblock->textureFaces, vec4(1.0f)); - } else if (cblock->model == BLOCK_MODEL_GRASS){ - batch->sprite(24, 648, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f)); + Player* player = level->player; + { + Block* cblock = Block::blocks[player->choosenBlock]; + if (cblock->model == BLOCK_MODEL_CUBE){ + batch->blockSprite(24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces, vec4(1.0f)); + } else if (cblock->model == BLOCK_MODEL_GRASS){ + batch->sprite(24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f)); + } + } + + if (!Events::_cursor_locked) { + for (unsigned i = 1; i < 256; i++) { + Block* cblock = Block::blocks[i]; + if (cblock == nullptr) + break; + int size = 48; + int step = 70; + int x = 24 + (i-1) * step; + int y = uicamera->fov - 72 - 70; + y -= 72 * (x / (Window::width - step)); + x %= (Window::width - step); + vec4 tint(1.0f); + int mx = Events::x; + int my = Events::y; + if (mx > x && mx < x + size && my > y && my < y + size) { + tint.r *= 2.0f; + tint.g *= 2.0f; + tint.b *= 2.0f; + if (Events::jclicked(GLFW_MOUSE_BUTTON_LEFT)) { + player->choosenBlock = i; + } + } + if (cblock->model == BLOCK_MODEL_CUBE){ + batch->blockSprite(x, y, size, size, 16, cblock->textureFaces, tint); + } else if (cblock->model == BLOCK_MODEL_GRASS){ + batch->sprite(x, y, size, size, 16, cblock->textureFaces[3], tint); + } + } } batch->render(); + + Shader* crosshairShader = assets->getShader("crosshair"); + crosshairShader->use(); + crosshairShader->uniform1f("u_ar", (float)Window::height / (float)Window::width); + crosshairShader->uniform1f("u_scale", 1.0f / ((float)Window::height / 1000.0f)); + crosshair->draw(GL_LINES); } diff --git a/src/hud_render.h b/src/hud_render.h index e07d36a1..08984627 100644 --- a/src/hud_render.h +++ b/src/hud_render.h @@ -3,17 +3,19 @@ class Batch2D; class Camera; -class World; class Level; class Assets; +class Mesh; class HudRenderer { - Batch2D *batch; - Camera *uicamera; + Batch2D* batch; + Camera* uicamera; + Mesh* crosshair; public: HudRenderer(); ~HudRenderer(); - void draw(World* world, Level* level, Assets* assets, bool devdata, int fps); + void draw(Level* level, Assets* assets); + void drawDebug(Level* level, Assets* assets, int fps, bool occlusion); }; #endif /* SRC_HUD_RENDER_H_ */ diff --git a/src/lighting/LightSolver.cpp b/src/lighting/LightSolver.cpp index b4f22bd6..07070a05 100644 --- a/src/lighting/LightSolver.cpp +++ b/src/lighting/LightSolver.cpp @@ -21,8 +21,8 @@ void LightSolver::add(int x, int y, int z, int emission) { addqueue.push(entry); Chunk* chunk = chunks->getChunkByVoxel(entry.x, entry.y, entry.z); - chunk->modified = true; - chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y-chunk->y*CHUNK_H, entry.z-chunk->z*CHUNK_D, channel, entry.light); + chunk->setModified(true); + chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y, entry.z-chunk->z*CHUNK_D, channel, entry.light); } void LightSolver::add(int x, int y, int z) { @@ -35,7 +35,7 @@ void LightSolver::remove(int x, int y, int z) { if (chunk == nullptr) return; - int light = chunk->lightmap->get(x-chunk->x*CHUNK_W, y-chunk->y*CHUNK_H, z-chunk->z*CHUNK_D, channel); + int light = chunk->lightmap->get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel); if (light == 0){ return; } @@ -47,7 +47,7 @@ void LightSolver::remove(int x, int y, int z) { entry.light = light; remqueue.push(entry); - chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y-chunk->y*CHUNK_H, entry.z-chunk->z*CHUNK_D, channel, 0); + chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y, entry.z-chunk->z*CHUNK_D, channel, 0); } void LightSolver::solve(){ @@ -78,8 +78,8 @@ void LightSolver::solve(){ nentry.z = z; nentry.light = light; remqueue.push(nentry); - chunk->lightmap->set(x-chunk->x*CHUNK_W, y-chunk->y*CHUNK_H, z-chunk->z*CHUNK_D, channel, 0); - chunk->modified = true; + chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0); + chunk->setModified(true); } else if (light >= entry.light){ lightentry nentry; @@ -94,7 +94,7 @@ void LightSolver::solve(){ } while (!addqueue.empty()){ - lightentry entry = addqueue.front(); + const lightentry entry = addqueue.front(); addqueue.pop(); if (entry.light <= 1) @@ -110,8 +110,8 @@ void LightSolver::solve(){ voxel* v = chunks->get(x,y,z); Block* block = Block::blocks[v->id]; if (block->lightPassing && light+2 <= entry.light){ - chunk->lightmap->set(x-chunk->x*CHUNK_W, y-chunk->y*CHUNK_H, z-chunk->z*CHUNK_D, channel, entry.light-1); - chunk->modified = true; + chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, entry.light-1); + chunk->setModified(true); lightentry nentry; nentry.x = x; nentry.y = y; diff --git a/src/lighting/Lighting.cpp b/src/lighting/Lighting.cpp index b1fe4f80..5a036d76 100644 --- a/src/lighting/Lighting.cpp +++ b/src/lighting/Lighting.cpp @@ -35,154 +35,94 @@ void Lighting::clear(){ } } -void Lighting::onChunkLoaded(int cx, int cy, int cz, bool sky){ - Chunk* chunk = chunks->getChunk(cx, cy, cz); - Chunk* chunkUpper = chunks->getChunk(cx, cy+1, cz); - Chunk* chunkLower = chunks->getChunk(cx, cy-1, cz); - if (chunkLower && sky){ - for (int z = 0; z < CHUNK_D; z++){ - for (int x = 0; x < CHUNK_W; x++){ +void Lighting::prebuildSkyLight(int cx, int cz){ + Chunk* chunk = chunks->getChunk(cx, cz); + int highestPoint = 0; + for (int z = 0; z < CHUNK_D; z++){ + for (int x = 0; x < CHUNK_W; x++){ + for (int y = CHUNK_H-1;;y--){ + if (y < 0) + break; + voxel* vox = &(chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]); + Block* block = Block::blocks[vox->id]; + if (!block->skyLightPassing) { + if (highestPoint < y) + highestPoint = y; + break; + } + chunk->lightmap->setS(x,y,z, 15); + } + } + } + if (highestPoint < CHUNK_H-1) + highestPoint++; + chunk->lightmap->highestPoint = highestPoint; +} + +void Lighting::buildSkyLight(int cx, int cz){ + Chunk* chunk = chunks->getChunk(cx, cz); + for (int z = 0; z < CHUNK_D; z++){ + for (int x = 0; x < CHUNK_W; x++){ + for (int y = chunk->lightmap->highestPoint; y >= 0; y--){ int gx = x + cx * CHUNK_W; int gz = z + cz * CHUNK_D; - - int light = chunk->lightmap->getS(x,0,z); - int ncy = cy-1; - if (light < 15){ - Chunk* current = chunkLower; - if (chunkLower->lightmap->getS(x,15,z) == 0) - continue; - for (int y = 15;;y--){ - if (y < 0){ - ncy--; - y += CHUNK_H; - } - if (ncy != current->y) - current = chunks->getChunk(cx,ncy,cz); - if (!current) - break; - voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz); - Block* block = Block::blocks[vox->id]; - if (!block->skyLightPassing) - break; - //current->lightmap->setS(x,y,z, 0); - current->modified = true; - solverS->remove(gx,y+ncy*CHUNK_H,gz); - current->lightmap->setS(x,y,z, 0); + while (y > 0 && !Block::blocks[chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x].id]->lightPassing) { + y--; + } + if (chunk->lightmap->getS(x, y, z) != 15) { + solverS->add(gx,y+1,gz); + for (; y >= 0; y--){ + solverS->add(gx+1,y,gz); + solverS->add(gx-1,y,gz); + solverS->add(gx,y,gz+1); + solverS->add(gx,y,gz-1); } } } } } - if (chunkUpper && sky){ - for (int z = 0; z < CHUNK_D; z++){ - for (int x = 0; x < CHUNK_W; x++){ - int gx = x + cx * CHUNK_W; - int gy = cy * CHUNK_H; - int gz = z + cz * CHUNK_D; - int ncy = cy; + solverS->solve(); +} - int light = chunkUpper->lightmap->getS(x,0,z); +void Lighting::onChunkLoaded(int cx, int cz){ + const Chunk* chunk = chunks->getChunk(cx, cz); - Chunk* current = chunk; - if (light == 15){ - for (int y = CHUNK_H-1;;y--){ - if (y < 0){ - ncy--; - y += CHUNK_H; - } - if (ncy != current->y) - current = chunks->getChunk(cx,ncy,cz); - if (!current) - break; - voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz); - Block* block = Block::blocks[vox->id]; - if (!block->skyLightPassing) - break; - current->lightmap->setS(x,y,z, 15); - current->modified = true; - solverS->add(gx,y+ncy*CHUNK_H,gz); - } - } else if (light){ - solverS->add(gx,gy+CHUNK_H,gz); - } - } - } - } else if (sky){ - for (int z = 0; z < CHUNK_D; z++){ - for (int x = 0; x < CHUNK_W; x++){ - int gx = x + cx * CHUNK_W; - int gz = z + cz * CHUNK_D; - int ncy = cy; - - Chunk* current = chunk; - for (int y = CHUNK_H-1;;y--){ - if (y < 0){ - ncy--; - y += CHUNK_H; - } - if (ncy != current->y) - current = chunks->getChunk(cx,ncy,cz); - if (!current) - break; - voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz); - Block* block = Block::blocks[vox->id]; - if (!block->skyLightPassing) - break; - current->lightmap->setS(x,y,z, 15); - current->modified = true; - solverS->add(gx,y+ncy*CHUNK_H,gz); - } - } - } - } - //std::cout << "DONE" << std::endl; for (unsigned int y = 0; y < CHUNK_H; y++){ for (unsigned int z = 0; z < CHUNK_D; z++){ for (unsigned int x = 0; x < CHUNK_W; x++){ voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; Block* block = Block::blocks[vox.id]; - if (block->emission[0] || block->emission[1] || block->emission[2]){ - int gx = x + cx * CHUNK_W; - int gy = y + cy * CHUNK_H; - int gz = z + cz * CHUNK_D; - solverR->add(gx,gy,gz,block->emission[0]); - solverG->add(gx,gy,gz,block->emission[1]); - solverB->add(gx,gy,gz,block->emission[2]); - } - } - } - } - for (int y = -1; y <= CHUNK_H; y++){ - for (int z = -1; z <= CHUNK_D; z++){ - for (int x = -1; x <= CHUNK_W; x++){ - if (!(x == -1 || x == CHUNK_W || y == -1 || y == CHUNK_H || z == -1 || z == CHUNK_D)) - continue; int gx = x + cx * CHUNK_W; - int gy = y + cy * CHUNK_H; int gz = z + cz * CHUNK_D; - if (chunks->getLight(x,y,z)){ - solverR->add(gx,gy,gz); - solverG->add(gx,gy,gz); - solverB->add(gx,gy,gz); - if (sky) - solverS->add(gx,gy,gz); + if (block->emission[0] || block->emission[1] || block->emission[2]){ + solverR->add(gx,y,gz,block->emission[0]); + solverG->add(gx,y,gz,block->emission[1]); + solverB->add(gx,y,gz,block->emission[2]); } } } } + for (int y = -1; y <= CHUNK_H; y++){ + for (int z = -1; z <= CHUNK_D; z++){ + for (int x = -1; x <= CHUNK_W; x++){ + if (!(x == -1 || x == CHUNK_W || z == -1 || z == CHUNK_D)) + continue; + int gx = x + cx * CHUNK_W; + int gz = z + cz * CHUNK_D; + if (chunks->getLight(x,y,z)){ + solverR->add(gx,y,gz); + solverG->add(gx,y,gz); + solverB->add(gx,y,gz); + solverS->add(gx,y,gz); + } + } + } + } solverR->solve(); solverG->solve(); solverB->solve(); solverS->solve(); - - Chunk* other; - other = chunks->getChunk(cx-1,cy,cz); if (other) other->modified = true; - other = chunks->getChunk(cx+1,cy,cz); if (other) other->modified = true; - other = chunks->getChunk(cx,cy-1,cz); if (other) other->modified = true; - other = chunks->getChunk(cx,cy+1,cz); if (other) other->modified = true; - other = chunks->getChunk(cx,cy,cz-1); if (other) other->modified = true; - other = chunks->getChunk(cx,cy,cz+1); if (other) other->modified = true; } void Lighting::onBlockSet(int x, int y, int z, int id){ @@ -191,11 +131,9 @@ void Lighting::onBlockSet(int x, int y, int z, int id){ solverR->remove(x,y,z); solverG->remove(x,y,z); solverB->remove(x,y,z); - solverR->solve(); solverG->solve(); solverB->solve(); - if (chunks->getLight(x,y+1,z, 3) == 0xF){ for (int i = y; i >= 0; i--){ voxel* vox = chunks->get(x,i,z); @@ -204,14 +142,12 @@ void Lighting::onBlockSet(int x, int y, int z, int id){ solverS->add(x,i,z, 0xF); } } - solverR->add(x,y+1,z); solverG->add(x,y+1,z); solverB->add(x,y+1,z); solverS->add(x,y+1,z); solverR->add(x,y-1,z); solverG->add(x,y-1,z); solverB->add(x,y-1,z); solverS->add(x,y-1,z); solverR->add(x+1,y,z); solverG->add(x+1,y,z); solverB->add(x+1,y,z); solverS->add(x+1,y,z); solverR->add(x-1,y,z); solverG->add(x-1,y,z); solverB->add(x-1,y,z); solverS->add(x-1,y,z); solverR->add(x,y,z+1); solverG->add(x,y,z+1); solverB->add(x,y,z+1); solverS->add(x,y,z+1); solverR->add(x,y,z-1); solverG->add(x,y,z-1); solverB->add(x,y,z-1); solverS->add(x,y,z-1); - solverR->solve(); solverG->solve(); solverB->solve(); diff --git a/src/lighting/Lighting.h b/src/lighting/Lighting.h index ebbb2173..e1caf777 100644 --- a/src/lighting/Lighting.h +++ b/src/lighting/Lighting.h @@ -15,7 +15,9 @@ public: ~Lighting(); void clear(); - void onChunkLoaded(int cx, int cy, int cz, bool sky); + void prebuildSkyLight(int cx, int cz); + void buildSkyLight(int cx, int cz); + void onChunkLoaded(int cx, int cz); void onBlockSet(int x, int y, int z, int id); }; diff --git a/src/lighting/Lightmap.h b/src/lighting/Lightmap.h index bee5c5e7..c0ca007a 100644 --- a/src/lighting/Lightmap.h +++ b/src/lighting/Lightmap.h @@ -6,6 +6,7 @@ class Lightmap { public: unsigned short* map; + int highestPoint = 0; Lightmap(); ~Lightmap(); diff --git a/src/loaders/png_loading.cpp b/src/loaders/png_loading.cpp index 0a02b04a..7757b564 100644 --- a/src/loaders/png_loading.cpp +++ b/src/loaders/png_loading.cpp @@ -102,6 +102,8 @@ int _png_load(const char* file, int* width, int* height){ alpha, GL_UNSIGNED_BYTE, (GLvoid *) image_data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); @@ -210,6 +212,8 @@ int _png_load(const char* file, int* pwidth, int* pheight){ alpha, GL_UNSIGNED_BYTE, (GLvoid *) flipped); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0); pwidth[0] = ihdr.width; diff --git a/src/objects/Player.h b/src/objects/Player.h index 2147458f..af7a9fe7 100644 --- a/src/objects/Player.h +++ b/src/objects/Player.h @@ -14,6 +14,7 @@ public: Camera* camera; Hitbox* hitbox; bool flight = false; + bool noclip = false; int choosenBlock; float camX, camY; float cameraShaking = 0.0f; diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index bab04f0b..dac915df 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -10,7 +10,9 @@ PhysicsSolver::PhysicsSolver(vec3 gravity) : gravity(gravity) { } -void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting, float gravityScale) { +void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting, + float gravityScale, + bool collisions) { hitbox->grounded = false; for (unsigned i = 0; i < substeps; i++){ float dt = delta / (float)substeps; @@ -25,85 +27,87 @@ void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned s float px = pos.x; float pz = pos.z; - if (vel.x < 0.0){ - for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ - for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ - int x = floor(pos.x-half.x-E); - if (chunks->isObstacle(x,y,z)){ - vel.x *= 0.0; - pos.x = x + 1 + half.x + E; - break; + if (collisions) { + if (vel.x < 0.0){ + for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ + for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ + int x = floor(pos.x-half.x-E); + if (chunks->isObstacle(x,y,z)){ + vel.x *= 0.0; + pos.x = x + 1 + half.x + E; + break; + } } } } - } - if (vel.x > 0.0){ - for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ - for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ - int x = floor(pos.x+half.x+E); - if (chunks->isObstacle(x,y,z)){ - vel.x *= 0.0; - pos.x = x - half.x - E; - break; + if (vel.x > 0.0){ + for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ + for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ + int x = floor(pos.x+half.x+E); + if (chunks->isObstacle(x,y,z)){ + vel.x *= 0.0; + pos.x = x - half.x - E; + break; + } } } } - } - if (vel.z < 0.0){ - for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ + if (vel.z < 0.0){ + for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ + for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){ + int z = floor(pos.z-half.z-E); + if (chunks->isObstacle(x,y,z)){ + vel.z *= 0.0; + pos.z = z + 1 + half.z + E; + break; + } + } + } + } + + if (vel.z > 0.0){ + for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ + for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){ + int z = floor(pos.z+half.z+E); + if (chunks->isObstacle(x,y,z)){ + vel.z *= 0.0; + pos.z = z - half.z - E; + break; + } + } + } + } + + if (vel.y < 0.0){ for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){ - int z = floor(pos.z-half.z-E); - if (chunks->isObstacle(x,y,z)){ - vel.z *= 0.0; - pos.z = z + 1 + half.z + E; - break; + bool broken = false; + for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ + int y = floor(pos.y-half.y-E); + if (chunks->isObstacle(x,y,z)){ + vel.y *= 0.0; + pos.y = y + 1 + half.y; + int f = DEFAULT_FRICTION; + vel.x *= max(0.0, 1.0 - dt * f); + vel.z *= max(0.0, 1.0 - dt * f); + hitbox->grounded = true; + broken = true; + break; + } } + if (broken) + break; } } - } - - if (vel.z > 0.0){ - for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){ + if (vel.y > 0.0){ for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){ - int z = floor(pos.z+half.z+E); - if (chunks->isObstacle(x,y,z)){ - vel.z *= 0.0; - pos.z = z - half.z - E; - break; - } - } - } - } - - if (vel.y < 0.0){ - for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){ - bool broken = false; - for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ - int y = floor(pos.y-half.y-E); - if (chunks->isObstacle(x,y,z)){ - vel.y *= 0.0; - pos.y = y + 1 + half.y; - int f = DEFAULT_FRICTION; - vel.x *= max(0.0, 1.0 - dt * f); - vel.z *= max(0.0, 1.0 - dt * f); - hitbox->grounded = true; - broken = true; - break; - } - } - if (broken) - break; - } - } - if (vel.y > 0.0){ - for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){ - for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ - int y = floor(pos.y+half.y+E); - if (chunks->isObstacle(x,y,z)){ - vel.y *= 0.0; - pos.y = y - half.y - E; - break; + for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){ + int y = floor(pos.y+half.y+E); + if (chunks->isObstacle(x,y,z)){ + vel.y *= 0.0; + pos.y = y - half.y - E; + break; + } } } } diff --git a/src/physics/PhysicsSolver.h b/src/physics/PhysicsSolver.h index 469d73a8..f2302b34 100644 --- a/src/physics/PhysicsSolver.h +++ b/src/physics/PhysicsSolver.h @@ -14,7 +14,13 @@ class PhysicsSolver { vec3 gravity; public: PhysicsSolver(vec3 gravity); - void step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting, float gravityScale); + void step(Chunks* chunks, + Hitbox* hitbox, + float delta, + unsigned substeps, + bool shifting, + float gravityScale, + bool collisions); bool isBlockInside(int x, int y, int z, Hitbox* hitbox); }; diff --git a/src/player_control.cpp b/src/player_control.cpp index 7772f097..59fbe276 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -25,7 +25,7 @@ #define CAMERA_SHAKING_OFFSET_Y 0.031f #define CAMERA_SHAKING_SPEED 1.6f #define CAMERA_SHAKING_DELTA_K 10.0f -#define FLIGHT_SPEED_MUL 8.0f +#define FLIGHT_SPEED_MUL 4.0f #define CHEAT_SPEED_MUL 5.0f #define JUMP_FORCE 7.0f @@ -35,13 +35,6 @@ PlayerController::PlayerController(Level* level) : level(level) { void PlayerController::update_controls(float delta){ Player* player = level->player; - if (Events::jpressed(GLFW_KEY_ESCAPE)){ - Window::setShouldClose(true); - } - if (Events::jpressed(GLFW_KEY_TAB)){ - Events::toogleCursor(); - } - for (int i = 1; i < 10; i++){ if (Events::jpressed(GLFW_KEY_0+i)){ player->choosenBlock = i; @@ -65,7 +58,7 @@ void PlayerController::update_controls(float delta){ } int substeps = (int)(delta * 1000); substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps)); - level->physics->step(level->chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f); + level->physics->step(level->chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f, !player->noclip); camera->position.x = hitbox->position.x; camera->position.y = hitbox->position.y + 0.7f; camera->position.z = hitbox->position.z; @@ -85,18 +78,20 @@ void PlayerController::update_controls(float delta){ camera->position += camera->up * abs(cos(shakeTimer)) * CAMERA_SHAKING_OFFSET_Y * player->cameraShaking; camera->position -= min(player->interpVel * 0.05f, 1.0f); - if (Events::jpressed(GLFW_KEY_F)){ + if ((Events::jpressed(GLFW_KEY_F) && !player->noclip) || + (Events::jpressed(GLFW_KEY_N) && player->flight == player->noclip)){ player->flight = !player->flight; if (player->flight){ hitbox->velocity.y += 1; hitbox->grounded = false; } } + if (Events::jpressed(GLFW_KEY_N)) { + player->noclip = !player->noclip; + } // Field of view manipulations float dt = min(1.0f, delta * ZOOM_SPEED); - if (dt > 1.0f) - dt = 1.0f; float zoomValue = 1.0f; if (shift){ speed *= CROUCH_SPEED_MUL; @@ -182,7 +177,8 @@ void PlayerController::update_interaction(){ selectedBlockId = vox->id; selectedBlockPosition = iend; - if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && Block::blocks[vox->id]->breakable){ + Block* block = Block::blocks[vox->id]; + if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && block->breakable){ int x = (int)iend.x; int y = (int)iend.y; int z = (int)iend.z; @@ -193,6 +189,11 @@ void PlayerController::update_interaction(){ int x = (int)(iend.x)+(int)(norm.x); int y = (int)(iend.y)+(int)(norm.y); int z = (int)(iend.z)+(int)(norm.z); + if (block->model == BLOCK_MODEL_GRASS){ + x = (int)iend.x; + y = (int)iend.y; + z = (int)iend.z; + } if (!level->physics->isBlockInside(x,y,z, player->hitbox)){ chunks->set(x, y, z, player->choosenBlock); lighting->onBlockSet(x,y,z, player->choosenBlock); diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index a24b3e92..bfb13c67 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -24,6 +24,7 @@ using namespace glm; #include "graphics/VoxelRenderer.h" #include "graphics/LineBatch.h" #include "graphics/Batch2D.h" +#include "graphics/Framebuffer.h" #include "window/Window.h" #include "window/Events.h" #include "window/Camera.h" @@ -54,13 +55,9 @@ using namespace glm; #include "hud_render.h" #include "player_control.h" - -float gravity = 19.6f; - int WIDTH = 1280; int HEIGHT = 720; - // Save all world data to files void write_world(World* world, Level* level){ WorldFiles* wfile = world->wfile; @@ -68,7 +65,7 @@ void write_world(World* world, Level* level){ for (unsigned int i = 0; i < chunks->volume; i++){ Chunk* chunk = chunks->chunks[i]; - if (chunk == nullptr) + if (chunk == nullptr || !chunk->isUnsaved()) continue; wfile->put((const char*)chunk->voxels, chunk->x, chunk->z); } @@ -78,16 +75,17 @@ void write_world(World* world, Level* level){ world->wfile->writePlayer(level->player); } -void update_level(World* world, Level* level, float delta, long frame, VoxelRenderer* renderer){ +void update_level(World* world, Level* level, float delta, long frame, VoxelRenderer* renderer) { level->playerController->update_controls(delta); - level->playerController->update_interaction(); + if (Events::_cursor_locked) + level->playerController->update_interaction(); vec3 position = level->player->hitbox->position; - level->chunks->setCenter(world->wfile, position.x, 0, position.z); + level->chunks->setCenter(world->wfile, position.x, position.z); } Level* load_level(World* world, Player* player) { - Level* level = new Level(world, player, new Chunks(34,1,34, 0,0,0), new PhysicsSolver(vec3(0, -gravity, 0))); + Level* level = new Level(world, player, new Chunks(56, 56, 0, 0), new PhysicsSolver(vec3(0, -19.6f, 0))); world->wfile->readPlayer(player); Camera* camera = player->camera; @@ -96,10 +94,8 @@ Level* load_level(World* world, Player* player) { return level; } - -int initialize(Assets*& assets){ - Audio::initialize(); - Window::initialize(WIDTH, HEIGHT, "VoxelEngine-Cpp v.12"); +int initialize(Assets*& assets) { + Window::initialize(WIDTH, HEIGHT, "VoxelEngine-Cpp v12"); Events::initialize(); assets = new Assets(); @@ -113,6 +109,66 @@ int initialize(Assets*& assets){ return 0; } +void mainloop(Level* level, Assets* assets) { + Camera* camera = level->player->camera; + std::cout << "-- preparing systems" << std::endl; + World* world = level->world; + WorldRenderer worldRenderer(level, assets); + HudRenderer hud; + long frame = 0; + float lastTime = glfwGetTime(); + float delta = 0.0f; + bool occlusion = true; + bool devdata = false; + Window::swapInterval(1); + while (!Window::isShouldClose()){ + frame++; + float currentTime = glfwGetTime(); + delta = currentTime - lastTime; + lastTime = currentTime; + int fps = 1 / delta; + if (Events::jpressed(GLFW_KEY_ESCAPE)){ + Window::setShouldClose(true); + } + if (Events::jpressed(GLFW_KEY_TAB)){ + Events::toogleCursor(); + } + if (Events::jpressed(GLFW_KEY_O)){ + occlusion = !occlusion; + } + if (Events::jpressed(GLFW_KEY_F3)){ + devdata = !devdata; + } + if (Events::jpressed(GLFW_KEY_F5)){ + for (unsigned i = 0; i < level->chunks->volume; i++) { + Chunk* chunk = level->chunks->chunks[i]; + if (chunk != nullptr && chunk->isReady()){ + chunk->setModified(true); + } + } + } + + update_level(world, level, delta, frame, worldRenderer.renderer); + int freeLoaders = level->chunksController->countFreeLoaders(); + for (int i = 0; i < freeLoaders; i++) + level->chunksController->_buildMeshes(worldRenderer.renderer, frame); + freeLoaders = level->chunksController->countFreeLoaders(); + for (int i = 0; i < freeLoaders; i++) + level->chunksController->calculateLights(); + freeLoaders = level->chunksController->countFreeLoaders(); + for (int i = 0; i < freeLoaders; i++) + level->chunksController->loadVisible(world->wfile); + + worldRenderer.draw(world, camera, occlusion); + hud.draw(level, assets); + if (devdata) { + hud.drawDebug(level, assets, fps, occlusion); + } + + Window::swapBuffers(); + Events::pullEvents(); + } +} int main() { setup_definitions(); @@ -128,57 +184,12 @@ int main() { Player* player = new Player(playerPosition, 4.0f, camera); Level* level = load_level(world, player); - std::cout << "-- preparing systems" << std::endl; - HudRenderer hud; - WorldRenderer worldRenderer(level); - - float lastTime = glfwGetTime(); - float delta = 0.0f; - long frame = 0; - bool occlusion = false; - bool devdata = false; - - Window::swapInterval(1); - std::cout << "-- initializing finished" << std::endl; - while (!Window::isShouldClose()){ - frame++; - float currentTime = glfwGetTime(); - delta = currentTime - lastTime; - lastTime = currentTime; - int fps = 1 / delta; - if (Events::jpressed(GLFW_KEY_O)){ - occlusion = !occlusion; - } - if (Events::jpressed(GLFW_KEY_F3)){ - devdata = !devdata; - } + Audio::initialize(); + mainloop(level, assets); + Audio::finalize(); - update_level(world, level, delta, frame, worldRenderer.renderer); - int freeLoaders = level->chunksController->countFreeLoaders(); - for (int i = 0; i < freeLoaders; i++) - level->chunksController->_buildMeshes(worldRenderer.renderer, frame); - freeLoaders = level->chunksController->countFreeLoaders(); - for (int i = 0; i < freeLoaders; i++) - level->chunksController->loadVisible(world->wfile); - - worldRenderer.draw(world, camera, assets, occlusion); - if (level->playerController->selectedBlockId != -1){ - Block* selectedBlock = Block::blocks[level->playerController->selectedBlockId]; - LineBatch* lineBatch = worldRenderer.lineBatch; - vec3 pos = level->playerController->selectedBlockPosition; - if (selectedBlock->model == 1){ - lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); - } else if (selectedBlock->model == 2){ - lineBatch->box(pos.x+0.4f, pos.y+0.3f, pos.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f); - } - } - hud.draw(world, level, assets, devdata, fps); - - Window::swapBuffers(); - Events::pullEvents(); - } std::cout << "-- saving world" << std::endl; write_world(world, level); @@ -187,7 +198,6 @@ int main() { std::cout << "-- shutting down" << std::endl; delete assets; - Audio::finalize(); Events::finalize(); Window::terminate(); return 0; diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index 5bf9006e..52debffe 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -2,8 +2,7 @@ #include "voxel.h" #include "../lighting/Lightmap.h" - -Chunk::Chunk(int xpos, int ypos, int zpos) : x(xpos), y(ypos), z(zpos){ +Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos){ voxels = new voxel[CHUNK_VOL]; for (unsigned int i = 0; i < CHUNK_VOL; i++) voxels[i].id = 1; @@ -30,7 +29,7 @@ bool Chunk::isEmpty(){ } Chunk* Chunk::clone() const { - Chunk* other = new Chunk(x,y,z); + Chunk* other = new Chunk(x,z); for (int i = 0; i < CHUNK_VOL; i++) other->voxels[i] = voxels[i]; other->lightmap->set(lightmap); diff --git a/src/voxels/Chunk.h b/src/voxels/Chunk.h index 2c37fed9..1ff29b7a 100644 --- a/src/voxels/Chunk.h +++ b/src/voxels/Chunk.h @@ -8,6 +8,12 @@ #define CHUNK_D 16 #define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D) +#define CHUNK_MODIFIED 0x1 +#define CHUNK_READY 0x2 +#define CHUNK_LOADED 0x4 +#define CHUNK_LIGHTED 0x8 +#define CHUNK_UNSAVED 0x10 + class voxel; class Lightmap; @@ -16,19 +22,21 @@ struct RenderData { size_t size; }; +#define BIT_ON(f,i) do{f|= i;} while(0) +#define BIT_OFF(f,i) do{f&=~(i);} while(0) +#define BITSET(f,i,s) if (s) BIT_ON(f,i); else BIT_OFF(f,i); + class Chunk { public: - int x,y,z; + int x, z; voxel* voxels; Lightmap* lightmap; - bool modified = true; - bool ready = false; - bool loaded = false; + int flags = 0; int surrounding = 0; int references = 1; RenderData renderData; - Chunk(int x, int y, int z); + Chunk(int x, int z); ~Chunk(); bool isEmpty(); @@ -36,6 +44,28 @@ public: Chunk* clone() const; void incref(); void decref(); + + // flags getters/setters below + + inline bool isUnsaved() const {return flags & CHUNK_UNSAVED;} + + inline bool isModified() const {return flags & CHUNK_MODIFIED;} + + inline bool isLighted() const {return flags & CHUNK_LIGHTED;} + + inline bool isLoaded() const {return flags & CHUNK_LOADED;} + + inline bool isReady() const {return flags & CHUNK_READY;} + + inline void setUnsaved(bool flag) {BITSET(flags, CHUNK_UNSAVED, flag);} + + inline void setModified(bool flag) {BITSET(flags, CHUNK_MODIFIED, flag);} + + inline void setLoaded(bool flag) {BITSET(flags, CHUNK_LOADED, flag);} + + inline void setLighted(bool flag) {BITSET(flags, CHUNK_LIGHTED, flag);} + + inline void setReady(bool flag) {BITSET(flags, CHUNK_READY, flag);} }; #endif /* VOXELS_CHUNK_H_ */ diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index ce255800..b16aecd5 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -11,8 +11,8 @@ #include #include -Chunks::Chunks(int w, int h, int d, int ox, int oy, int oz) : w(w), h(h), d(d), ox(ox), oy(oy), oz(oz){ - volume = w*h*d; +Chunks::Chunks(int w, int d, int ox, int oz) : w(w), d(d), ox(ox), oz(oz){ + volume = w*d; chunks = new Chunk*[volume]; chunksSecond = new Chunk*[volume]; @@ -36,7 +36,6 @@ Chunks::~Chunks(){ voxel* Chunks::get(int x, int y, int z){ x -= ox * CHUNK_W; - y -= oy * CHUNK_H; z -= oz * CHUNK_D; int cx = x / CHUNK_W; int cy = y / CHUNK_H; @@ -44,7 +43,7 @@ voxel* Chunks::get(int x, int y, int z){ if (x < 0) cx--; if (y < 0) cy--; if (z < 0) cz--; - if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d) + if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d) return nullptr; Chunk* chunk = chunks[(cy * d + cz) * w + cx]; if (chunk == nullptr) @@ -64,7 +63,6 @@ bool Chunks::isObstacle(int x, int y, int z){ unsigned char Chunks::getLight(int x, int y, int z, int channel){ x -= ox * CHUNK_W; - y -= oy * CHUNK_H; z -= oz * CHUNK_D; int cx = x / CHUNK_W; int cy = y / CHUNK_H; @@ -72,7 +70,7 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){ if (x < 0) cx--; if (y < 0) cy--; if (z < 0) cz--; - if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d) + if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d) return 0; Chunk* chunk = chunks[(cy * d + cz) * w + cx]; if (chunk == nullptr) @@ -85,7 +83,6 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){ unsigned short Chunks::getLight(int x, int y, int z){ x -= ox * CHUNK_W; - y -= oy * CHUNK_H; z -= oz * CHUNK_D; int cx = x / CHUNK_W; int cy = y / CHUNK_H; @@ -93,7 +90,7 @@ unsigned short Chunks::getLight(int x, int y, int z){ if (x < 0) cx--; if (y < 0) cy--; if (z < 0) cz--; - if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d) + if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d) return 0; Chunk* chunk = chunks[(cy * d + cz) * w + cx]; if (chunk == nullptr) @@ -106,7 +103,6 @@ unsigned short Chunks::getLight(int x, int y, int z){ Chunk* Chunks::getChunkByVoxel(int x, int y, int z){ x -= ox * CHUNK_W; - y -= oy * CHUNK_H; z -= oz * CHUNK_D; int cx = x / CHUNK_W; int cy = y / CHUNK_H; @@ -114,48 +110,44 @@ Chunk* Chunks::getChunkByVoxel(int x, int y, int z){ if (x < 0) cx--; if (y < 0) cy--; if (z < 0) cz--; - if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d) + if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d) return nullptr; return chunks[(cy * d + cz) * w + cx]; } -Chunk* Chunks::getChunk(int x, int y, int z){ +Chunk* Chunks::getChunk(int x, int z){ x -= ox; - y -= oy; z -= oz; - if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d) + if (x < 0 || z < 0 || x >= w || z >= d) return nullptr; - return chunks[(y * d + z) * w + x]; + return chunks[z * w + x]; } void Chunks::set(int x, int y, int z, int id){ x -= ox * CHUNK_W; - y -= oy * CHUNK_H; z -= oz * CHUNK_D; int cx = x / CHUNK_W; - int cy = y / CHUNK_H; + if (y < 0 || y >= CHUNK_H) + return; int cz = z / CHUNK_D; if (x < 0) cx--; - if (y < 0) cy--; if (z < 0) cz--; - if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d) + if (cx < 0 || cz < 0 || cx >= w || cz >= d) return; - Chunk* chunk = chunks[(cy * d + cz) * w + cx]; + Chunk* chunk = chunks[cz * w + cx]; if (chunk == nullptr) return; int lx = x - cx * CHUNK_W; - int ly = y - cy * CHUNK_H; int lz = z - cz * CHUNK_D; - chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx].id = id; - chunk->modified = true; + chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx].id = id; + chunk->setUnsaved(true); + chunk->setModified(true); - if (lx == 0 && (chunk = getChunk(cx+ox-1, cy+oy, cz+oz))) chunk->modified = true; - if (ly == 0 && (chunk = getChunk(cx+ox, cy+oy-1, cz+oz))) chunk->modified = true; - if (lz == 0 && (chunk = getChunk(cx+ox, cy+oy, cz+oz-1))) chunk->modified = true; + if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz))) chunk->setModified(true); + if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1))) chunk->setModified(true); - if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cy+oy, cz+oz))) chunk->modified = true; - if (ly == CHUNK_H-1 && (chunk = getChunk(cx+ox, cy+oy+1, cz+oz))) chunk->modified = true; - if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cy+oy, cz+oz+1))) chunk->modified = true; + if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz))) chunk->setModified(true); + if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1))) chunk->setModified(true); } voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, vec3& iend) { @@ -246,48 +238,42 @@ voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, v return nullptr; } -void Chunks::setCenter(WorldFiles* worldFiles, int x, int y, int z) { +void Chunks::setCenter(WorldFiles* worldFiles, int x, int z) { int cx = x / CHUNK_W; - int cy = y / CHUNK_H; int cz = z / CHUNK_D; cx -= ox; - cy -= oy; cz -= oz; if (x < 0) cx--; - if (y < 0) cy--; if (z < 0) cz--; cx -= w/2; - cy -= h/2; cz -= d/2; - if (cx != 0 || cy != 0 || cz != 0) - translate(worldFiles, cx,cy,cz); + if (cx | cz) { + translate(worldFiles, cx,cz); + } } -void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){ +void Chunks::translate(WorldFiles* worldFiles, int dx, int dz){ for (unsigned int i = 0; i < volume; i++){ chunksSecond[i] = nullptr; meshesSecond[i] = nullptr; } - for (unsigned int y = 0; y < h; y++){ - for (unsigned int z = 0; z < d; z++){ - for (unsigned int x = 0; x < w; x++){ - Chunk* chunk = chunks[(y * d + z) * w + x]; - int nx = x - dx; - int ny = y - dy; - int nz = z - dz; - if (chunk == nullptr) - continue; - Mesh* mesh = meshes[(y * d + z) * w + x]; - if (nx < 0 || ny < 0 || nz < 0 || nx >= w || ny >= h || nz >= d){ - worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z); - chunk->decref(); - delete mesh; - chunksCount--; - continue; - } - meshesSecond[(ny * d + nz) * w + nx] = mesh; - chunksSecond[(ny * d + nz) * w + nx] = chunk; + for (int z = 0; z < d; z++){ + for (int x = 0; x < w; x++){ + Chunk* chunk = chunks[z * w + x]; + int nx = x - dx; + int nz = z - dz; + if (chunk == nullptr) + continue; + Mesh* mesh = meshes[z * w + x]; + if (nx < 0 || nz < 0 || nx >= w || nz >= d){ + worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z); + chunk->decref(); + delete mesh; + chunksCount--; + continue; } + meshesSecond[nz * w + nx] = mesh; + chunksSecond[nz * w + nx] = chunk; } } Chunk** ctemp = chunks; @@ -299,26 +285,22 @@ void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){ meshesSecond = mtemp; ox += dx; - oy += dy; oz += dz; } -void Chunks::_setOffset(int x, int y, int z){ +void Chunks::_setOffset(int x, int z){ ox = x; - oy = y; oz = z; } bool Chunks::putChunk(Chunk* chunk) { int x = chunk->x; - int y = chunk->y; int z = chunk->z; x -= ox; - y -= oy; z -= oz; - if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d) + if (x < 0 || z < 0 || x >= w || z >= d) return false; - chunks[(y * d + z) * w + x] = chunk; + chunks[z * w + x] = chunk; chunksCount++; return true; } diff --git a/src/voxels/Chunks.h b/src/voxels/Chunks.h index c9c70bea..5b5f9a3a 100644 --- a/src/voxels/Chunks.h +++ b/src/voxels/Chunks.h @@ -21,15 +21,15 @@ public: Mesh** meshesSecond; size_t volume; size_t chunksCount; - unsigned int w,h,d; - int ox,oy,oz; + int w,d; + int ox,oz; - Chunks(int w, int h, int d, int ox, int oy, int oz); + Chunks(int w, int d, int ox, int oz); ~Chunks(); bool putChunk(Chunk* chunk); - Chunk* getChunk(int x, int y, int z); + Chunk* getChunk(int x, int z); Chunk* getChunkByVoxel(int x, int y, int z); voxel* get(int x, int y, int z); unsigned short getLight(int x, int y, int z); @@ -40,10 +40,10 @@ public: bool isObstacle(int x, int y, int z); // does not move chunks inside - void _setOffset(int x, int y, int z); + void _setOffset(int x, int z); - void setCenter(WorldFiles* worldFiles, int x, int y, int z); - void translate(WorldFiles* worldFiles, int x, int y, int z); + void setCenter(WorldFiles* worldFiles, int x, int z); + void translate(WorldFiles* worldFiles, int x, int z); void clear(bool freeMemory); }; diff --git a/src/voxels/ChunksController.cpp b/src/voxels/ChunksController.cpp index 96b2cac4..1ca47b52 100644 --- a/src/voxels/ChunksController.cpp +++ b/src/voxels/ChunksController.cpp @@ -48,117 +48,78 @@ int ChunksController::countFreeLoaders(){ bool ChunksController::loadVisible(WorldFiles* worldFiles){ const int w = chunks->w; - const int h = chunks->h; const int d = chunks->d; const int ox = chunks->ox; - const int oy = chunks->oy; const int oz = chunks->oz; int nearX = 0; - int nearY = 0; int nearZ = 0; int minDistance = (w/2)*(w/2); - for (int y = 0; y < h; y++){ - for (int z = 2; z < d-2; z++){ - for (int x = 2; x < w-2; x++){ - int index = (y * d + z) * w + x; - Chunk* chunk = chunks->chunks[index]; - if (chunk != nullptr){ - int surrounding = 0; - for (int oz = -1; oz <= 1; oz++){ - for (int ox = -1; ox <= 1; ox++){ - Chunk* other = chunks->getChunk(chunk->x+ox, chunk->y, chunk->z+oz); - if (other != nullptr && other->ready) surrounding++; - } + for (int z = 2; z < d-2; z++){ + for (int x = 2; x < w-2; x++){ + int index = z * w + x; + Chunk* chunk = chunks->chunks[index]; + if (chunk != nullptr){ + int surrounding = 0; + for (int oz = -1; oz <= 1; oz++){ + for (int ox = -1; ox <= 1; ox++){ + Chunk* other = chunks->getChunk(chunk->x+ox, chunk->z+oz); + if (other != nullptr && other->isReady()) surrounding++; } - chunk->surrounding = surrounding; - continue; - } - int lx = x - w / 2; - int ly = y - h / 2; - int lz = z - d / 2; - int distance = (lx * lx + ly * ly + lz * lz); - if (distance < minDistance){ - minDistance = distance; - nearX = x; - nearY = y; - nearZ = z; } + chunk->surrounding = surrounding; + continue; + } + int lx = x - w / 2; + int lz = z - d / 2; + int distance = (lx * lx + lz * lz); + if (distance < minDistance){ + minDistance = distance; + nearX = x; + nearZ = z; } } } - int index = (nearY * d + nearZ) * w + nearX; + int index = nearZ * w + nearX; Chunk* chunk = chunks->chunks[index]; if (chunk != nullptr) return false; - ChunksLoader* freeLoader = nullptr; - for (int i = 0; i < loadersCount; i++){ - ChunksLoader* loader = loaders[i]; - if (loader->isBusy()){ - continue; - } - freeLoader = loader; - break; - } + ChunksLoader* freeLoader = getFreeLoader(); if (freeLoader == nullptr) return false; - chunk = new Chunk(nearX+ox,nearY+oy,nearZ+oz); + + chunk = new Chunk(nearX+ox, nearZ+oz); if (worldFiles->getChunk(chunk->x, chunk->z, (char*)chunk->voxels)) - chunk->loaded = true; + chunk->setLoaded(true); chunks->putChunk(chunk); - Chunk* closes[27]; - for (int i = 0; i < 27; i++) + Chunk* closes[9]; + for (int i = 0; i < 9; i++) closes[i] = nullptr; for (size_t j = 0; j < chunks->volume; j++){ Chunk* other = chunks->chunks[j]; if (other == nullptr) continue; - if (!other->ready) + if (!other->isReady()) continue; int ox = other->x - chunk->x; - int oy = other->y - chunk->y; int oz = other->z - chunk->z; - if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1) + if (abs(ox) > 1 || abs(oz) > 1) continue; ox += 1; - oy += 1; oz += 1; - closes[(oy * 3 + oz) * 3 + ox] = other; + closes[oz * 3 + ox] = other; } freeLoader->load(chunk, (Chunk**)closes); return true; } -bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { - const int w = chunks->w; - const int h = chunks->h; - const int d = chunks->d; - - for (int y = 0; y < h; y++){ - for (int z = 1; z < d-1; z++){ - for (int x = 1; x < w-1; x++){ - int index = (y * d + z) * w + x; - Chunk* chunk = chunks->chunks[index]; - if (chunk == nullptr) - continue; - if (chunk->renderData.vertices > (void*)1){ - const int chunk_attrs[] = {3,2,4, 0}; - Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs); - if (chunks->meshes[index]) - delete chunks->meshes[index]; - chunks->meshes[index] = mesh; - delete[] chunk->renderData.vertices; - chunk->renderData.vertices = nullptr; - } - } - } - } +ChunksLoader* ChunksController::getFreeLoader() { ChunksLoader* freeLoader = nullptr; for (int i = 0; i < loadersCount; i++){ ChunksLoader* loader = loaders[i]; @@ -168,85 +129,152 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { freeLoader = loader; break; } + return freeLoader; +} + +void ChunksController::calculateLights() { + ChunksLoader* freeLoader = getFreeLoader(); + if (freeLoader == nullptr) + return; + const int w = chunks->w; + const int d = chunks->d; + int nearX = 0; + int nearZ = 0; + int minDistance = INT_MAX; + for (int z = 1; z < d-1; z++){ + for (int x = 1; x < w-1; x++){ + int index = z * w + x; + Chunk* chunk = chunks->chunks[index]; + if (chunk == nullptr) + continue; + if (chunk->isLighted() || chunk->surrounding < MIN_SURROUNDING){ + continue; + } + int lx = x - w / 2; + int lz = z - d / 2; + int distance = (lx * lx + lz * lz); + if (distance < minDistance){ + minDistance = distance; + nearX = x; + nearZ = z; + } + } + } + int index = nearZ * w + nearX; + Chunk* chunk = chunks->chunks[index]; + if (chunk == nullptr) + return; + Chunk* closes[9]; + for (int i = 0; i < 9; i++) + closes[i] = nullptr; + for (size_t j = 0; j < chunks->volume; j++){ + Chunk* other = chunks->chunks[j]; + if (other == nullptr) + continue; + + int ox = other->x - chunk->x; + int oz = other->z - chunk->z; + + if (abs(ox) > 1|| abs(oz) > 1) + continue; + + ox += 1; + oz += 1; + closes[oz * 3 + ox] = other; + } + freeLoader->lights(chunk, (Chunk**)closes); +} + +bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) { + const int w = chunks->w; + const int d = chunks->d; + + for (int z = 1; z < d-1; z++){ + for (int x = 1; x < w-1; x++){ + int index = z * w + x; + Chunk* chunk = chunks->chunks[index]; + if (chunk == nullptr) + continue; + if (chunk->renderData.vertices > (void*)1){ + const int chunk_attrs[] = {3,2,4, 0}; + Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs); + if (chunks->meshes[index]) + delete chunks->meshes[index]; + chunks->meshes[index] = mesh; + delete[] chunk->renderData.vertices; + chunk->renderData.vertices = nullptr; + } + } + } + ChunksLoader* freeLoader = getFreeLoader(); if (freeLoader == nullptr) return false; int nearX = 0; - int nearY = 0; int nearZ = 0; int minDistance = INT_MAX; - for (int y = 0; y < h; y++){ - for (int z = 1; z < d-1; z++){ - for (int x = 1; x < w-1; x++){ - int index = (y * d + z) * w + x; - Chunk* chunk = chunks->chunks[index]; - if (chunk == nullptr) - continue; - Mesh* mesh = chunks->meshes[index]; - if (mesh != nullptr && !chunk->modified) - continue; - if (!chunk->ready || chunk->surrounding < MIN_SURROUNDING){ - continue; - } - int lx = x - w / 2; - int ly = y - h / 2; - int lz = z - d / 2; - int distance = (lx * lx + ly * ly + lz * lz); - if (distance < minDistance){ - minDistance = distance; - nearX = x; - nearY = y; - nearZ = z; - } + for (int z = 1; z < d-1; z++){ + for (int x = 1; x < w-1; x++){ + int index = z * w + x; + Chunk* chunk = chunks->chunks[index]; + if (chunk == nullptr) + continue; + Mesh* mesh = chunks->meshes[index]; + if (mesh != nullptr && !chunk->isModified()) + continue; + if (!chunk->isReady() || !chunk->isLighted() || chunk->surrounding < MIN_SURROUNDING){ + continue; + } + int lx = x - w / 2; + int lz = z - d / 2; + int distance = (lx * lx + lz * lz); + if (distance < minDistance){ + minDistance = distance; + nearX = x; + nearZ = z; } } } - - int index = (nearY * d + nearZ) * w + nearX; - - + int index = nearZ * w + nearX; Chunk* chunk = chunks->chunks[index]; if (chunk == nullptr){ return false; } Mesh* mesh = chunks->meshes[index]; - if (mesh == nullptr || chunk->modified){ - Chunk* closes[27]; + if (mesh == nullptr || chunk->isModified()){ + if (chunk->renderData.vertices != nullptr) { + return false; + } + Chunk* closes[9]; if (chunk->isEmpty()){ chunks->meshes[index] = nullptr; return false; } - chunk->modified = false; - for (int i = 0; i < 27; i++) + + for (int i = 0; i < 9; i++) closes[i] = nullptr; for (size_t j = 0; j < chunks->volume; j++){ Chunk* other = chunks->chunks[j]; if (other == nullptr) continue; - if (!other->ready) - continue; int ox = other->x - chunk->x; - int oy = other->y - chunk->y; int oz = other->z - chunk->z; - if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1) + if (abs(ox) > 1 || abs(oz) > 1) continue; ox += 1; - oy += 1; oz += 1; - closes[(oy * 3 + oz) * 3 + ox] = other; + if ((!other->isReady() || !other->isLighted()) && other != chunk) + return false; + closes[oz * 3 + ox] = other; } - if (chunk->renderData.vertices == nullptr){ - chunk->renderData.vertices = (float*)1; - freeLoader->render(chunk, (Chunk**)closes); - - return true; - } - //mesh = renderer->render(chunk, (const Chunk**)closes); - //chunks->meshes[index] = mesh; + chunk->setModified(false); + chunk->renderData.vertices = (float*)1; + freeLoader->render(chunk, (Chunk**)closes); + return true; } return false; } diff --git a/src/voxels/ChunksController.h b/src/voxels/ChunksController.h index 9212e207..d9315f00 100644 --- a/src/voxels/ChunksController.h +++ b/src/voxels/ChunksController.h @@ -18,8 +18,10 @@ public: ChunksController(World* world, Chunks* chunks, Lighting* lighting); ~ChunksController(); + ChunksLoader* getFreeLoader(); int countFreeLoaders(); bool loadVisible(WorldFiles* worldFiles); + void calculateLights(); bool _buildMeshes(VoxelRenderer* renderer, int tick); }; diff --git a/src/voxels/ChunksLoader.cpp b/src/voxels/ChunksLoader.cpp index 0b41241d..f688a70a 100644 --- a/src/voxels/ChunksLoader.cpp +++ b/src/voxels/ChunksLoader.cpp @@ -12,10 +12,10 @@ #include -#define CLOSES_C 27 +#define SURROUNDINGS_C 9 void ChunksLoader::_thread(){ - Chunks chunks(3,3,3, -1,-1,-1); + Chunks chunks(3, 3, -1, -1); Lighting lighting(&chunks); VoxelRenderer renderer; while (state != OFF){ @@ -24,9 +24,9 @@ void ChunksLoader::_thread(){ continue; } Chunk* chunk = current; - chunks._setOffset(chunk->x-1, chunk->y-1, chunk->z-1); - for (size_t i = 0; i < CLOSES_C; i++){ - Chunk* other = closes[i]; + chunks._setOffset(chunk->x-1, chunk->z-1); + for (size_t i = 0; i < SURROUNDINGS_C; i++){ + Chunk* other = surroundings[i]; if (other){ chunks.putChunk(other); } @@ -34,8 +34,9 @@ void ChunksLoader::_thread(){ if (state == LOAD){ chunks.putChunk(chunk); - if (!chunk->loaded){ - WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world->seed); + if (!chunk->isLoaded()){ + WorldGenerator::generate(chunk->voxels, chunk->x, chunk->z, world->seed); + chunk->setUnsaved(true); } for (size_t i = 0; i < CHUNK_VOL; i++){ @@ -44,11 +45,17 @@ void ChunksLoader::_thread(){ chunk->voxels[i].id = 11; } } - lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true); + lighting.prebuildSkyLight(chunk->x, chunk->z); + } + else if (state == LIGHTS) { + lighting.buildSkyLight(chunk->x, chunk->z); + lighting.onChunkLoaded(chunk->x, chunk->z); + chunk->setLighted(true); } else if (state == RENDER){ + chunk->setModified(false); size_t size; - renderer.render(chunk, (const Chunk**)(closes.load()), size); + renderer.render(chunk, (const Chunk**)(surroundings.load()), size); float* vertices = new float[size]; for (size_t i = 0; i < size; i++) vertices[i] = renderer.buffer[i]; @@ -57,33 +64,33 @@ void ChunksLoader::_thread(){ } chunks.clear(false); - for (int i = 0; i < CLOSES_C; i++){ - Chunk* other = closes[i]; + for (int i = 0; i < SURROUNDINGS_C; i++){ + Chunk* other = surroundings[i]; if (other) other->decref(); } - chunk->ready = true; + chunk->setReady(true); current = nullptr; chunk->decref(); } } -void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode){ +void ChunksLoader::perform(Chunk* chunk, Chunk** surroundings_passed, LoaderMode mode){ if (isBusy()){ std::cerr << "performing while busy" << std::endl; return; } chunk->incref(); - if (closes == nullptr){ - closes = new Chunk*[CLOSES_C]; + if (surroundings == nullptr){ + surroundings = new Chunk*[SURROUNDINGS_C]; } - for (int i = 0; i < CLOSES_C; i++){ - Chunk* other = closes_passed[i]; + for (int i = 0; i < SURROUNDINGS_C; i++){ + Chunk* other = surroundings_passed[i]; if (other == nullptr) - closes[i] = nullptr; + surroundings[i] = nullptr; else { other->incref(); - closes[i] = other; + surroundings[i] = other; } } current = chunk; @@ -94,6 +101,10 @@ void ChunksLoader::load(Chunk* chunk, Chunk** closes_passed){ perform(chunk, closes_passed, LOAD); } +void ChunksLoader::lights(Chunk* chunk, Chunk** closes_passed){ + perform(chunk, closes_passed, LIGHTS); +} + void ChunksLoader::render(Chunk* chunk, Chunk** closes_passed){ perform(chunk, closes_passed, RENDER); } diff --git a/src/voxels/ChunksLoader.h b/src/voxels/ChunksLoader.h index 37c623fd..876b0c8c 100644 --- a/src/voxels/ChunksLoader.h +++ b/src/voxels/ChunksLoader.h @@ -14,7 +14,7 @@ class Chunk; class World; enum LoaderMode { - OFF, IDLE, LOAD, RENDER, + OFF, IDLE, LOAD, LIGHTS, RENDER, }; class ChunksLoader final { @@ -22,7 +22,7 @@ private: std::thread loaderThread; void _thread(); std::atomic current {nullptr}; - std::atomic closes {nullptr}; + std::atomic surroundings {nullptr}; std::atomic state {IDLE}; World* world; @@ -41,6 +41,7 @@ public: } void load(Chunk* chunk, Chunk** closes_passed); + void lights(Chunk* chunk, Chunk** closes_passed); void render(Chunk* chunk, Chunk** closes_passed); void stop(){ diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index c2a0f047..1664bbda 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -2,6 +2,7 @@ #include "voxel.h" #include "Chunk.h" +#include #include #include #include @@ -9,6 +10,8 @@ #include "../maths/FastNoiseLite.h" #include +#include "../declarations.h" + class PseudoRandom { unsigned short seed; public: @@ -64,7 +67,7 @@ float calc_height_faster(fnl_state *noise, int real_x, int real_z){ height *= 64.0f; return height; } -#include + int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights, int real_x, int real_y, int real_z, int tileSize){ const int tileX = floor((double)real_x/(double)tileSize); const int tileY = floor((double)real_z/(double)tileSize); @@ -92,18 +95,14 @@ int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights, return 0; } -void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ +void WorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){ fnl_state noise = fnlCreateState(); noise.noise_type = FNL_NOISE_OPENSIMPLEX2; noise.seed = seed * 60617077 % 25896307; - PseudoRandom randomtree; - // PseudoRandom random; float heights[CHUNK_VOL]; - // std::cout << calc_height(&noise, cx, cy) << "\n"; - for (int z = 0; z < CHUNK_D; z++){ for (int x = 0; x < CHUNK_W; x++){ int real_x = x + cx * CHUNK_W; @@ -120,14 +119,14 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ float height = heights[z*CHUNK_W+x]; for (int y = 0; y < CHUNK_H; y++){ - int real_y = y + cy * CHUNK_H; - int id = real_y < 55 ? 9 : 0; - if ((real_y == (int)height) && (54 < real_y)) - id = 2; - else if (real_y < (height - 6)){ - id = 8; + int real_y = y; + int id = real_y < 55 ? BLOCK_WATER : BLOCK_AIR; + if ((real_y == (int)height) && (54 < real_y)) { + id = BLOCK_GRASS_BLOCK; + } else if (real_y < (height - 6)){ + id = BLOCK_STONE; } else if (real_y < height){ - id = 1; + id = BLOCK_DIRT; } else { int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 16); if (tree) { @@ -139,15 +138,15 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){ } } if ( ((height - (1.5 - 0.2 * pow(height - 54, 4))) < real_y) && (real_y < height)){ - id = 10; + id = BLOCK_SAND; } if (real_y <= 2) - id = 11; + id = BLOCK_BEDROCK; if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 56000)){ - id = 12; + id = BLOCK_GRASS; } if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 64000)){ - id = 13; + id = BLOCK_FLOWER; } voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id; } diff --git a/src/voxels/WorldGenerator.h b/src/voxels/WorldGenerator.h index ae164319..0b910441 100644 --- a/src/voxels/WorldGenerator.h +++ b/src/voxels/WorldGenerator.h @@ -5,7 +5,7 @@ class voxel; class WorldGenerator { public: - static void generate(voxel* voxels, int x, int y, int z, int seed); + static void generate(voxel* voxels, int x, int z, int seed); }; #endif /* VOXELS_WORLDGENERATOR_H_ */ diff --git a/src/window/Camera.cpp b/src/window/Camera.cpp index 1fe9b77c..2cebfa35 100644 --- a/src/window/Camera.cpp +++ b/src/window/Camera.cpp @@ -1,10 +1,3 @@ -/* - * Camera.cpp - * - * Created on: Feb 11, 2020 - * Author: MihailRis - */ - #include "Camera.h" #include "Window.h" @@ -36,7 +29,10 @@ void Camera::rotate(float x, float y, float z){ } mat4 Camera::getProjection(){ - float aspect = (float)Window::width / (float)Window::height; + float aspect = this->aspect; + if (aspect == 0.0f){ + aspect = (float)Window::width / (float)Window::height; + } if (perspective) return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f); else @@ -50,5 +46,5 @@ mat4 Camera::getView(){ if (perspective) return glm::lookAt(position, position+front, up); else - return glm::mat4(1.0f); + return glm::translate(glm::mat4(1.0f), position); } diff --git a/src/window/Camera.h b/src/window/Camera.h index 28aabe94..3e82bac3 100644 --- a/src/window/Camera.h +++ b/src/window/Camera.h @@ -1,10 +1,3 @@ -/* - * Camera.h - * - * Created on: Feb 11, 2020 - * Author: MihailRis - */ - #ifndef WINDOW_CAMERA_H_ #define WINDOW_CAMERA_H_ @@ -25,6 +18,7 @@ public: mat4 rotation; bool perspective = true; bool flipped = false; + float aspect = 0.0f; Camera(vec3 position, float fov); void rotate(float x, float y, float z); diff --git a/src/window/Window.cpp b/src/window/Window.cpp index a761631e..9031edc7 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -41,6 +41,10 @@ int Window::initialize(int width, int height, const char* title){ return 0; } +void Window::viewport(int x, int y, int width, int height){ + glViewport(x, y, width, height); +} + void Window::setCursorMode(int mode){ glfwSetInputMode(window, GLFW_CURSOR, mode); } diff --git a/src/window/Window.h b/src/window/Window.h index b54e1a58..dfce56b6 100644 --- a/src/window/Window.h +++ b/src/window/Window.h @@ -11,6 +11,7 @@ public: static int initialize(int width, int height, const char* title); static void terminate(); + static void viewport(int x, int y, int width, int height); static void setCursorMode(int mode); static bool isShouldClose(); static void setShouldClose(bool flag); diff --git a/src/world/Level.cpp b/src/world/Level.cpp index a04e722f..d85df92e 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -4,6 +4,7 @@ #include "../player_control.h" Level::Level(World* world, Player* player, Chunks* chunks, PhysicsSolver* physics) : + world(world), player(player), chunks(chunks), physics(physics) { diff --git a/src/world/Level.h b/src/world/Level.h index 6abb74c1..47728e2a 100644 --- a/src/world/Level.h +++ b/src/world/Level.h @@ -11,6 +11,7 @@ class PlayerController; class Level { public: + World* world; Player* player; Chunks* chunks; PhysicsSolver* physics; diff --git a/src/world_render.cpp b/src/world_render.cpp index 660da4c4..48209214 100644 --- a/src/world_render.cpp +++ b/src/world_render.cpp @@ -1,5 +1,6 @@ #include "world_render.h" +#include #include "graphics/VoxelRenderer.h" #include "window/Window.h" @@ -11,38 +12,24 @@ #include "graphics/Batch3D.h" #include "voxels/Chunks.h" #include "voxels/Chunk.h" +#include "voxels/Block.h" #include "world/World.h" #include "world/Level.h" +#include "objects/Player.h" #include "Assets.h" +#include "player_control.h" float _camera_cx; float _camera_cz; -Mesh *crosshair; - -float vertices[] = { - // x y - -0.01f,-0.01f, - 0.01f, 0.01f, - - -0.01f, 0.01f, - 0.01f,-0.01f, -}; - -int attrs[] = { - 2, 0 //null terminator -}; - -WorldRenderer::WorldRenderer(Level* level) { - this->level = level; - crosshair = new Mesh(vertices, 4, attrs); +WorldRenderer::WorldRenderer(Level* level, Assets* assets) : assets(assets), level(level) { lineBatch = new LineBatch(4096); batch3d = new Batch3D(1024); renderer = new VoxelRenderer(); } WorldRenderer::~WorldRenderer() { - delete crosshair; + delete batch3d; delete lineBatch; delete renderer; } @@ -50,71 +37,71 @@ WorldRenderer::~WorldRenderer() { Chunks* _chunks = nullptr; bool chunks_distance_compare(size_t i, size_t j) { - Chunks* chunks = _chunks; - Chunk* a = chunks->chunks[i]; - Chunk* b = chunks->chunks[j]; - return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz) - > + Chunk* a = _chunks->chunks[i]; + Chunk* b = _chunks->chunks[j]; + return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz) > (b->x + 0.5f - _camera_cx)*(b->x + 0.5f - _camera_cx) + (b->z + 0.5f - _camera_cz)*(b->z + 0.5f - _camera_cz)); } -void WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ +bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ Chunk* chunk = level->chunks->chunks[index]; Mesh* mesh = level->chunks->meshes[index]; if (mesh == nullptr) - return; + return false; - // Simple frustum culling (culling chunks behind the camera in 2D - XZ) + // Simple frustum culling if (occlusion){ - const float cameraX = camera->position.x; - const float cameraZ = camera->position.z; - const float camDirX = camera->dir.x; - const float camDirZ = camera->dir.z; - - bool unoccluded = false; - do { - if ((chunk->x*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; + float y = camera->position.y+camera->front.y * CHUNK_H * 0.5f; + if (y < 0.0f) + y = 0.0f; + if (y > CHUNK_H) + y = CHUNK_H; + vec3 v = vec3(chunk->x*CHUNK_W, y, chunk->z*CHUNK_D)-camera->position; + if (v.x*v.x+v.z*v.z > (CHUNK_W*3)*(CHUNK_W*3)) { + if (dot(camera->front, v) < 0.0f){ + return true; } - if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; - } - if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; - } - if ((chunk->x*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){ - unoccluded = true; break; - } - } while (false); - if (!unoccluded) - return; + } } - mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, chunk->y*CHUNK_H+0.5f, chunk->z*CHUNK_D+0.5f)); + mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f)); shader->uniformMatrix("u_model", model); mesh->draw(GL_TRIANGLES); + return false; } -void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occlusion){ + +void WorldRenderer::draw(World* world, Camera* camera, bool occlusion){ Chunks* chunks = level->chunks; - glClearColor(0.7f,0.81f,1.0f,1); + vec4 skyColor(0.7f, 0.81f, 1.0f, 1.0f); + glClearColor(skyColor.r, skyColor.g, skyColor.b, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + Window::viewport(0, 0, Window::width, Window::height); + glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); Texture* texture = assets->getTexture("block"); Shader* shader = assets->getShader("main"); - Shader* crosshairShader = assets->getShader("crosshair"); Shader* linesShader = assets->getShader("lines"); shader->use(); shader->uniformMatrix("u_proj", camera->getProjection()); shader->uniformMatrix("u_view", camera->getView()); shader->uniform1f("u_gamma", 1.6f); - shader->uniform3f("u_skyLightColor", 2.2f,2.2f,2.2f); - shader->uniform3f("u_fogColor", 0.7f,0.81f,1.0f); - shader->uniform1f("u_fogFactor", 0.03f); + shader->uniform3f("u_skyLightColor", 1.1f,1.1f,1.1f); + shader->uniform3f("u_fogColor", skyColor.r,skyColor.g,skyColor.b); + shader->uniform1f("u_fogFactor", 0.025f); shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z); + + Block* cblock = Block::blocks[level->player->choosenBlock]; + shader->uniform3f("u_torchlightColor", + cblock->emission[0] / 15.0f, + cblock->emission[1] / 15.0f, + cblock->emission[2] / 15.0f); + shader->uniform1f("u_torchlightDistance", 6.0f); + shader->uniform1f("u_fogFactor", 0.025f); texture->bind(); std::vector indices; @@ -136,8 +123,9 @@ void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occl std::sort(indices.begin(), indices.end(), chunks_distance_compare); + int occludedChunks = 0; for (size_t i = 0; i < indices.size(); i++){ - drawChunk(indices[i], camera, shader, occlusion); + occludedChunks += drawChunk(indices[i], camera, shader, occlusion); } shader->uniformMatrix("u_model", mat4(1.0f)); @@ -145,11 +133,6 @@ void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occl // 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)); - crosshair->draw(GL_LINES); - linesShader->use(); linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView()); glLineWidth(2.0f); @@ -157,4 +140,14 @@ void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occl lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f, camera->position.z+0.01f, 0, 0, 1, 1); lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f+0.01f, camera->position.z, 0, 1, 0, 1); lineBatch->render(); + + if (level->playerController->selectedBlockId != -1){ + Block* selectedBlock = Block::blocks[level->playerController->selectedBlockId]; + vec3 pos = level->playerController->selectedBlockPosition; + if (selectedBlock->model == 1){ + lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); + } else if (selectedBlock->model == 2){ + lineBatch->box(pos.x+0.4f, pos.y+0.3f, pos.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f); + } + } } diff --git a/src/world_render.h b/src/world_render.h index 124caf8b..d237ed29 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -21,21 +21,23 @@ class LineBatch; class Batch3D; class VoxelRenderer; class Shader; +class Texture; +class Framebuffer; class WorldRenderer { Batch3D *batch3d; + Assets* assets; Level* level; - - void drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion); + bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion); public: VoxelRenderer *renderer; LineBatch *lineBatch; - WorldRenderer(Level* level); + WorldRenderer(Level* level, Assets* assets); ~WorldRenderer(); - void draw(World* world, Camera* camera, Assets* assets, bool occlusion); + void draw(World* world, Camera* camera, bool occlusion); }; From 815aa9048974e6c82a63ff2aa21fdf4ef13824da Mon Sep 17 00:00:00 2001 From: zebra Date: Tue, 8 Nov 2022 10:51:13 +0300 Subject: [PATCH 56/56] func name fix --- src/voxel_engine.cpp | 4 ++-- src/window/Events.cpp | 2 +- src/window/Events.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index bfb13c67..99c95676 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -120,7 +120,7 @@ void mainloop(Level* level, Assets* assets) { float delta = 0.0f; bool occlusion = true; bool devdata = false; - Window::swapInterval(1); + Window::swapInterval(0); while (!Window::isShouldClose()){ frame++; float currentTime = glfwGetTime(); @@ -131,7 +131,7 @@ void mainloop(Level* level, Assets* assets) { Window::setShouldClose(true); } if (Events::jpressed(GLFW_KEY_TAB)){ - Events::toogleCursor(); + Events::toggleCursor(); } if (Events::jpressed(GLFW_KEY_O)){ occlusion = !occlusion; diff --git a/src/window/Events.cpp b/src/window/Events.cpp index 18d0e0b0..13327b3b 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -97,7 +97,7 @@ bool Events::jclicked(int button){ return _keys[index] && _frames[index] == _current; } -void Events::toogleCursor(){ +void Events::toggleCursor(){ _cursor_locked = !_cursor_locked; Window::setCursorMode(_cursor_locked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL); } diff --git a/src/window/Events.h b/src/window/Events.h index 996d4a03..d2a92c26 100644 --- a/src/window/Events.h +++ b/src/window/Events.h @@ -27,7 +27,7 @@ public: static bool clicked(int button); static bool jclicked(int button); - static void toogleCursor(); + static void toggleCursor(); }; #endif /* WINDOW_EVENTS_H_ */