Optimization interne de chunk!

This commit is contained in:
Marc-Eric Martel 2021-10-31 00:31:08 -04:00
parent c3c432c369
commit 1639b38c2c
9 changed files with 129 additions and 71 deletions

View File

@ -1,7 +1,7 @@
#include "blockinfo.h"
#include <iostream>
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;
}

View File

@ -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;

View File

@ -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) {
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, 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);
// -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, 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);
// 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, 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 == 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, .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);
// 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);
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(); }

View File

@ -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;

View File

@ -13,17 +13,17 @@
#endif
#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__

View File

@ -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)
// 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();
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));
}
if (m_testChunk.IsDirty())
m_testChunk.Update();
m_testChunk.Render();
m_shader01.Disable();
if (m_wireframe)

View File

@ -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<Chunk*> m_chunks = Array2d<Chunk*>(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;

View File

@ -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; }

View File

@ -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;