From 1639b38c2cb6704086c5f893fac5ad5c837b087f Mon Sep 17 00:00:00 2001 From: Marc-Eric Martel <1205697@etu.cegepsth.qc.ca> Date: Sun, 31 Oct 2021 00:31:08 -0400 Subject: [PATCH] Optimization interne de chunk! --- SQCSim2021/blockinfo.cpp | 10 +++++- SQCSim2021/blockinfo.h | 6 +++- SQCSim2021/chunk.cpp | 75 +++++++++++++++++++++++++--------------- SQCSim2021/chunk.h | 5 +-- SQCSim2021/define.h | 10 +++--- SQCSim2021/engine.cpp | 57 +++++++++++++++++++----------- SQCSim2021/engine.h | 9 +++-- SQCSim2021/player.cpp | 27 ++++++++------- SQCSim2021/player.h | 1 + 9 files changed, 129 insertions(+), 71 deletions(-) diff --git a/SQCSim2021/blockinfo.cpp b/SQCSim2021/blockinfo.cpp index e4670b7..1e42825 100644 --- a/SQCSim2021/blockinfo.cpp +++ b/SQCSim2021/blockinfo.cpp @@ -1,7 +1,7 @@ #include "blockinfo.h" #include -BlockInfo::BlockInfo(BlockType type, const std::string& name) : m_type(type), m_name(name), m_durability(1) +BlockInfo::BlockInfo(BlockType type, const std::string& name, float u, float v, float s, int dur) : m_type(type), m_name(name), m_u(u), m_v(v), m_s(s), m_durability(dur) { } @@ -24,11 +24,19 @@ int BlockInfo::GetDurability() const return m_durability; } +void BlockInfo::GetTexture(float& u, float& v, float& s) +{ + u = m_u; + v = m_v; + s = m_s; +} + void BlockInfo::Show() const { std::cout << "Type: " << m_type << std::endl; std::cout << "Nom: " << m_name << std::endl; std::cout << "Durabilite: " << m_durability << std::endl; + std::cout << "Coordonnees Texture: " << m_u << ", " << m_v << ", " << m_s << std::endl; } diff --git a/SQCSim2021/blockinfo.h b/SQCSim2021/blockinfo.h index 37fcf40..8a2afe7 100644 --- a/SQCSim2021/blockinfo.h +++ b/SQCSim2021/blockinfo.h @@ -7,7 +7,7 @@ class BlockInfo { public: - BlockInfo(BlockType type, const std::string& name); + BlockInfo(BlockType type, const std::string& name, float u, float v, float s, int dur); ~BlockInfo(); BlockType GetType() const; @@ -15,11 +15,15 @@ class BlockInfo void SetDurability(int durability); int GetDurability() const; + void GetTexture(float& u, float& v, float& s); void Show() const; private: BlockType m_type; + float m_u; + float m_v; + float m_s; std::string m_name; int m_durability; diff --git a/SQCSim2021/chunk.cpp b/SQCSim2021/chunk.cpp index 95d9f76..5fe0b2d 100644 --- a/SQCSim2021/chunk.cpp +++ b/SQCSim2021/chunk.cpp @@ -16,7 +16,8 @@ void Chunk::SetBlock(int x, int y, int z, BlockType type) { BlockType Chunk::GetBlock(int x, int y, int z) { return m_blocks.Get(x, y, z); } -void Chunk::Update() { +void Chunk::Update(BlockInfo* blockinfo[BTYPE_LAST]) { + float u, v, s; // Update mesh if (m_isDirty) { int maxVertexCount = (CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z) * (6 * 4); @@ -29,7 +30,8 @@ void Chunk::Update() { break; BlockType bt = GetBlock(x, y, z); if (bt != BTYPE_AIR) { - AddBlockToMesh(vd, count, bt, x, y, z); + blockinfo[bt]->GetTexture(u, v, s); + AddBlockToMesh(vd, count, bt, x, y, z, u, v, s); } } } @@ -44,37 +46,54 @@ void Chunk::Update() { m_isDirty = false; } -void Chunk::AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z) { - - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 0.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 0.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 1.f); +void Chunk::AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, float u, float v, float s) { + // x + if (x == CHUNK_SIZE_X - 1 || GetBlock(x + 1, y, z) == BTYPE_AIR) { + vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, .9f, .9f, .9f, u, v); + vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, .9f, .9f, .9f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, .9f, .9f, .9f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, .9f, .9f, .9f, u + s, v); + } - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 0.f); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 0.f); + // -x + if (x == 0 || GetBlock(x - 1, y, z) == BTYPE_AIR) { + vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, .9f, .9f, .9f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, .9f, .9f, .9f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, .9f, .9f, .9f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, .9f, .9f, .9f, u, v); + } - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, .9f, .9f, .9f, 0.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, .9f, .9f, .9f, 1.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, .9f, .9f, .9f, 1.f, 0.f); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, .9f, .9f, .9f, 0.f, 0.f); + // y + if (y == CHUNK_SIZE_Y - 1 || GetBlock(x, y + 1, z) == BTYPE_AIR) { + vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, .8f, .8f, .8f, u, v); + vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, .8f, .8f, .8f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, .8f, .8f, .8f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, .8f, .8f, .8f, u + s, v); + } - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, .9f, .9f, .9f, 0.f, 0.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, .9f, .9f, .9f, 0.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, .9f, .9f, .9f, 1.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, .9f, .9f, .9f, 1.f, 0.f); + // - y + if (y == 0 || GetBlock(x, y - 1, z) == BTYPE_AIR) { + vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, .8f, .8f, .8f, u, v); + vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, .8f, .8f, .8f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, .8f, .8f, .8f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, .8f, .8f, .8f, u + s, v); + } - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, .8f, .8f, .8f, 0.f, 0.f); - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, .8f, .8f, .8f, 0.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, .8f, .8f, .8f, 1.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, .8f, .8f, .8f, 1.f, 0.f); + // z + if (z == CHUNK_SIZE_Z - 1 || GetBlock(x, y, z + 1) == BTYPE_AIR) { + vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, u, v); + vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, u, v + s); + } - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, .8f, .8f, .8f, 0.f, 0.f); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, .8f, .8f, .8f, 0.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, .8f, .8f, .8f, 1.f, 1.f); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, .8f, .8f, .8f, 1.f, 0.f); + // -z + if (z == 0 || GetBlock(x, y, z - 1) == BTYPE_AIR) { + vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, u, v); + } } void Chunk::Render() const { m_vertexBuffer.Render(); } diff --git a/SQCSim2021/chunk.h b/SQCSim2021/chunk.h index 40fe88f..ec0e9b6 100644 --- a/SQCSim2021/chunk.h +++ b/SQCSim2021/chunk.h @@ -3,6 +3,7 @@ #include "define.h" #include "array3d.h" #include "vertexbuffer.h" +#include "blockinfo.h" class Chunk { private: @@ -10,7 +11,7 @@ class Chunk { VertexBuffer m_vertexBuffer; bool m_isDirty = true; - void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z); + void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, float u, float v, float s); public: Chunk(); @@ -20,7 +21,7 @@ class Chunk { void SetBlock(int x, int y, int z, BlockType type); BlockType GetBlock(int x, int y, int z); - void Update(); + void Update(BlockInfo* blockinfo[BTYPE_LAST]); void Render() const; bool IsDirty() const; diff --git a/SQCSim2021/define.h b/SQCSim2021/define.h index afed738..e5b65ae 100644 --- a/SQCSim2021/define.h +++ b/SQCSim2021/define.h @@ -13,17 +13,17 @@ #endif -#define CHUNK_SIZE_X 16 -#define CHUNK_SIZE_Y 128 -#define CHUNK_SIZE_Z 16 +#define VIEW_DISTANCE 32 +#define CHUNK_SIZE_X 16 +#define CHUNK_SIZE_Y 128 +#define CHUNK_SIZE_Z 16 typedef uint8_t BlockType; -enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS }; +enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS, BTYPE_METAL, BTYPE_ICE, BTYPE_LAST }; #define TEXTURE_PATH "../SQCSim2021/media/textures/" #define SHADER_PATH "../SQCSim2021/media/shaders/" #define AUDIO_PATH "../SQCSim2021/media/audio/" -#define VIEW_DISTANCE 128 #endif // DEFINE_H__ diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index 7e68dd8..8690d19 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -47,16 +47,19 @@ void Engine::Init() // Objet de musique! m_audio.ToggleMusicState(); - // Init testChunk - for (int x = 0; x < CHUNK_SIZE_X; ++x) { - for (int z = 0; z < CHUNK_SIZE_Z; ++z) { - for (int y = 0; y < 32; ++y) { - if (x % 2 == 0 && y % 2 == 0 && z % 2 == 0) - m_testChunk.SetBlock(x, y, z, BTYPE_DIRT); - } - } - } + // Init Chunks + for (int x = 0; x < CHUNK_SIZE_X; ++x) + for (int z = 0; z < CHUNK_SIZE_Z; ++z) + for (int y = 0; y < 32; ++y) + m_testChunk.SetBlock(x, y, z, BTYPE_DIRT); + for (int chx = 0; chx < VIEW_DISTANCE; ++chx) + for (int chy = 0; chy < VIEW_DISTANCE; ++chy) + m_chunks.Set(chx, chy, &m_testChunk); + + //m_chunks.Set(0, 0, &m_testChunk); + + // Gestion de souris. CenterMouse(); HideCursor(); } @@ -66,19 +69,28 @@ void Engine::DeInit() { } void Engine::LoadResource() { LoadTexture(m_textureFloor, TEXTURE_PATH "grass.png"); LoadTexture(m_skybox.GetTexture(), TEXTURE_PATH "skybox.png"); - LoadTexture(m_textureCube1, TEXTURE_PATH "metal1.png"); LoadTexture(m_textureCrosshair, TEXTURE_PATH "cross.bmp"); LoadTexture(m_textureFont, TEXTURE_PATH "font.bmp"); + TextureAtlas::TextureIndex texDirtIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal3.png"); + TextureAtlas::TextureIndex texIceIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "dirt.png"); + TextureAtlas::TextureIndex texGrassIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "grass.png"); + TextureAtlas::TextureIndex texMetalIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal.png"); - TextureAtlas::TextureIndex texCheckerIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "checker.png"); - TextureAtlas::TextureIndex texDirtIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "dirt.png"); - - if (!m_textureAtlas.Generate(128, false)) - { + if (!m_textureAtlas.Generate(512, false)) { std::cout << " Unable to generate texture atlas ..." << std::endl; abort(); } + float u, v, s; + m_textureAtlas.TextureIndexToCoord(texDirtIndex, u, v, s, s); + m_blockinfo[BTYPE_DIRT] = new BlockInfo(BTYPE_DIRT, "Dirt", u, v, s, 1); + m_textureAtlas.TextureIndexToCoord(texGrassIndex, u, v, s, s); + m_blockinfo[BTYPE_GRASS] = new BlockInfo(BTYPE_GRASS, "Grass", u, v, s, 1); + m_textureAtlas.TextureIndexToCoord(texMetalIndex, u, v, s, s); + m_blockinfo[BTYPE_METAL] = new BlockInfo(BTYPE_METAL, "Metal", u, v, s, 1); + m_textureAtlas.TextureIndexToCoord(texIceIndex, u, v, s, s); + m_blockinfo[BTYPE_ICE] = new BlockInfo(BTYPE_ICE, "Ice", u, v, s, 1); + std::cout << " Loading and compiling shaders ..." << std::endl; if (!m_shader01.Load(SHADER_PATH "shader01.vert", SHADER_PATH "shader01.frag", true)) { std::cout << " Failed to load shader " << std::endl; @@ -210,13 +222,18 @@ void Engine::Render(float elapsedTime) { glVertex3f(-100.f, -2.f, -100.f); glEnd(); - // Chunk + // Chunks m_textureAtlas.Bind(); - - if (m_testChunk.IsDirty()) - m_testChunk.Update(); + for (int chx = 0; chx < VIEW_DISTANCE; chx++) + for (int chy = 0; chy < VIEW_DISTANCE; chy++) { + all.ApplyTranslation(chx * CHUNK_SIZE_X, 0, chy * CHUNK_SIZE_Z); + all.Use(); + if (m_chunks.Get(chx, chy)->IsDirty()) + m_chunks.Get(chx, chy)->Update(m_blockinfo); + m_chunks.Get(chx, chy)->Render(); + all.ApplyTranslation(-(chx * CHUNK_SIZE_X), 0, -(chy * CHUNK_SIZE_Z)); + } - m_testChunk.Render(); m_shader01.Disable(); if (m_wireframe) diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index 587c8ba..05acf17 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -10,6 +10,8 @@ #include "skybox.h" #include "audio.h" #include "textureatlas.h" +#include "blockinfo.h" +#include "array2d.h" class Engine : public OpenglContext { @@ -36,13 +38,16 @@ private: private: bool m_wireframe = false; + BlockInfo* m_blockinfo[BTYPE_LAST]; + TextureAtlas m_textureAtlas = TextureAtlas(BTYPE_LAST); + Array2d m_chunks = Array2d(VIEW_DISTANCE, VIEW_DISTANCE); + Texture m_textureFloor; Texture m_textureSkybox; Texture m_textureFont; Texture m_textureCrosshair; Texture m_textureCube1; - - TextureAtlas m_textureAtlas = TextureAtlas(128); + Skybox m_skybox; Shader m_shader01; Chunk m_testChunk; diff --git a/SQCSim2021/player.cpp b/SQCSim2021/player.cpp index 7c6d01b..2f7f80d 100644 --- a/SQCSim2021/player.cpp +++ b/SQCSim2021/player.cpp @@ -25,9 +25,13 @@ void Player::Move(bool front, bool back, bool left, bool right, bool jump, bool static bool jumped = true; static int dbljump = 0; // Peut sauter ou dasher tant que la variable est en dessous de 2. static float dashtimeout = 0; - static float gametime = 0; + static float bobbingtime = 0; - if (gametime <= 360.f) gametime += elapsedTime * m_topspeed / 2; else gametime = 0; + m_direction = Vector3f(cos(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f), + -sin(m_rotX / 57.2957795056f), + sin(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f)); + + if (bobbingtime <= 360.f) bobbingtime += elapsedTime * m_topspeed / 2; else bobbingtime = 0; if (dashtimeout > 0.f) { dash = false; @@ -73,18 +77,16 @@ void Player::Move(bool front, bool back, bool left, bool right, bool jump, bool } if ((dbljump < 1 && ( left || right || front || back)) || - (dash && !(left || right || front || back)) ) - { + (dash && !(left || right || front || back)) ) { yrotrad = (m_rotY / 57.2957795056f); // 180/Pi = 57.295... xrotrad = (m_rotX / 57.2957795056f); if (dash) accWS = m_topspeed; // Pour avoir un boost de vitesse vers l'avant si le dash est appuyé seul. } // Ajoute l'accélération de saut et le view bobbing. - m_velocity.y = accjmp + (sin(gametime) - 0.5f) * ((abs(accWS) + abs(accAD)) / 2.f) / (10.f * m_topspeed); + m_velocity.y = accjmp + (sin(bobbingtime) - 0.5f) * ((abs(accWS) + abs(accAD)) / 2.f) / (10.f * m_topspeed); m_position.y += m_velocity.y; - if (front) { if (dbljump == 0) if (accWS < m_topspeed) accWS += elapsedTime * 30; else accWS = m_topspeed; @@ -144,13 +146,16 @@ void Player::Move(bool front, bool back, bool left, bool right, bool jump, bool if (accAD < 1.f && accAD > -1.f) accAD = 0; } - - // Gestion de si le personnage va en diagonale, qu'il n'aille pas plus vite que s'il allait en ligne droite. - if ((accWS >= 0.f ? accWS : -accWS + accAD >= 0.f ? accAD : -accAD) > sqrtf(exp2f(m_topspeed) * 2)) { + if (abs(accAD) + abs(accWS) > sqrtf(exp2f(m_topspeed) * 2)) { accWS *= 0.8f; accAD *= 0.8f; } + + // Threshold de vélocité. + if (abs(m_velocity.x) < 0.02f) m_velocity.x = 0; + if (abs(m_velocity.y) < 0.02f) m_velocity.y = 0; + if (abs(m_velocity.z) < 0.02f) m_velocity.z = 0; } void Player::ApplyTransformation(Transformation& transformation, bool rel) const { @@ -163,6 +168,4 @@ Vector3f Player::GetPosition() const { return m_position; } Vector3f Player::GetVelocity() const { return m_velocity; } -Vector3f Player::GetDirection() const { return Vector3f(cos(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f), - -sin(m_rotX / 57.2957795056f) , - sin(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f)); } +Vector3f Player::GetDirection() const { return m_direction; } diff --git a/SQCSim2021/player.h b/SQCSim2021/player.h index 249cf2c..e482e5d 100644 --- a/SQCSim2021/player.h +++ b/SQCSim2021/player.h @@ -19,6 +19,7 @@ public: private: Vector3f m_position; Vector3f m_velocity; + Vector3f m_direction; float m_rotX = 0; float m_rotY = 0; float m_topspeed = 40;