This commit is contained in:
MarcEricMartel 2021-11-30 19:55:11 -05:00
parent de7945038c
commit 97ffc34e24
26 changed files with 221 additions and 203 deletions

View File

@ -3,7 +3,32 @@
Chunk::Chunk(int x, int y) : m_posX(x), m_posY(y) { m_blocks.Reset(BTYPE_AIR); } Chunk::Chunk(int x, int y) : m_posX(x), m_posY(y) { m_blocks.Reset(BTYPE_AIR); }
Chunk::~Chunk() { } Chunk::Chunk(int x, int y, char data[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z]) : m_posX(x), m_posY(y) {
for (int x = 0; x < CHUNK_SIZE_X; ++x)
for (int z = 0; z < CHUNK_SIZE_Z; ++z)
for (int y = 0; y < CHUNK_SIZE_Y; ++y)
m_blocks.Set(x, y, z, data[x + (z * CHUNK_SIZE_X) + (y * CHUNK_SIZE_Z * CHUNK_SIZE_X)]);
}
Chunk::~Chunk() {
if (m_isModified) {
char data[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z];
for (int x = 0; x < CHUNK_SIZE_X; ++x)
for (int z = 0; z < CHUNK_SIZE_Z; ++z)
for (int y = 0; y < CHUNK_SIZE_Y; ++y)
data[x + (z * CHUNK_SIZE_X) + (y * CHUNK_SIZE_Z * CHUNK_SIZE_X)] = (char)GetBlock(x, y, z);
std::ostringstream pos;
pos << CHUNK_PATH << m_posX << '_' << m_posY << ".chunk";
std::ofstream output(pos.str().c_str(), std::fstream::binary);
output.write(data, sizeof(data));
output.close();
}
}
void Chunk::RemoveBlock(int x, int y, int z, World* world) { void Chunk::RemoveBlock(int x, int y, int z, World* world) {
m_blocks.Set(x, y, z, BTYPE_AIR); m_blocks.Set(x, y, z, BTYPE_AIR);
@ -39,9 +64,10 @@ void Chunk::CheckNeighbors(int x, int z, World* world) {
world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY + 1) * CHUNK_SIZE_Z)->MakeDirty(); world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY + 1) * CHUNK_SIZE_Z)->MakeDirty();
} }
int Chunk::GetPosX() const { return m_posX; } void Chunk::GetPosition(int& x, int& y) const {
x = m_posX;
int Chunk::GetPosY() const { return m_posY; } y = m_posY;
}
void Chunk::Update(BlockInfo* blockinfo[BTYPE_LAST], World* world) { void Chunk::Update(BlockInfo* blockinfo[BTYPE_LAST], World* world) {
float u, v, s; float u, v, s;
@ -88,10 +114,10 @@ void Chunk::AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType b
} }
if (y == 0 || GetBlock(x, y - 1, z) == BTYPE_AIR) { // -y if (y == 0 || GetBlock(x, y - 1, z) == BTYPE_AIR) { // -y
vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, .8f, .8f, .8f, u, v); vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, .2f, .2f, .2f, u, v);
vd[count++] = VertexBuffer::VertexData(x, y, z, .8f, .8f, .8f, u, v + s); vd[count++] = VertexBuffer::VertexData(x, y, z, .2f, .2f, .2f, u, v + s);
vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z, .8f, .8f, .8f, u + s, v + s); vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z, .2f, .2f, .2f, u + s, v + s);
vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z + 1.f, .8f, .8f, .8f, u + s, v); vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z + 1.f, .2f, .2f, .2f, u + s, v);
} }
if (world->BlockAt(cx + 1, y, cy) == BTYPE_AIR) { // x if (world->BlockAt(cx + 1, y, cy) == BTYPE_AIR) { // x
@ -102,17 +128,17 @@ void Chunk::AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType b
} }
if (world->BlockAt(cx - 1, y, cy) == BTYPE_AIR) { // -x if (world->BlockAt(cx - 1, y, cy) == BTYPE_AIR) { // -x
vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z + 1.f, .9f, .9f, .9f, u, v + s); vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z + 1.f, .5f, .5f, .5f, u, v + s);
vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z, .9f, .9f, .9f, u + s, v + s); vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z, .5f, .5f, .5f, u + s, v + s);
vd[count++] = VertexBuffer::VertexData(x, y, z, .9f, .9f, .9f, u + s, v); vd[count++] = VertexBuffer::VertexData(x, y, z, .5f, .5f, .5f, u + s, v);
vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, .9f, .9f, .9f, u, v); vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, .5f, .5f, .5f, u, v);
} }
if (world->BlockAt(cx, y, cy + 1) == BTYPE_AIR) { // z if (world->BlockAt(cx, y, cy + 1) == BTYPE_AIR) { // z
vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, 1.f, 1.f, 1.f, u, v); vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, .4f, .4f, .4f, u, v);
vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z + 1.f, 1.f, 1.f, 1.f, u + s, v); vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z + 1.f, .4f, .4f, .4f, u + s, v);
vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z + 1.f, 1.f, 1.f, 1.f, u + s, v + s); vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z + 1.f, .4f, .4f, .4f, u + s, v + s);
vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z + 1.f, 1.f, 1.f, 1.f, u, v + s); vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z + 1.f, .4f, .4f, .4f, u, v + s);
} }
if (world->BlockAt(cx, y, cy - 1) == BTYPE_AIR) { // -z if (world->BlockAt(cx, y, cy - 1) == BTYPE_AIR) { // -z

View File

@ -22,14 +22,14 @@ class Chunk {
public: public:
Chunk(int x, int y); Chunk(int x, int y);
Chunk(int x, int y, char data[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z]);
~Chunk(); ~Chunk();
void RemoveBlock(int x, int y, int z, World* world); void RemoveBlock(int x, int y, int z, World* world);
void SetBlock(int x, int y, int z, BlockType type, World* world); void SetBlock(int x, int y, int z, BlockType type, World* world);
BlockType GetBlock(int x, int y, int z); BlockType GetBlock(int x, int y, int z);
void CheckNeighbors(int x, int z, World* world); void CheckNeighbors(int x, int z, World* world);
int GetPosX() const; void GetPosition(int& x, int& y) const;
int GetPosY() const;
void Update(BlockInfo* blockinfo[BTYPE_LAST], World* world); void Update(BlockInfo* blockinfo[BTYPE_LAST], World* world);

View File

@ -22,7 +22,7 @@
#define FRAMES_RENDER_CHUNKS 2 #define FRAMES_RENDER_CHUNKS 2
#define FRAMES_UPDATE_CHUNKS 2 #define FRAMES_UPDATE_CHUNKS 2
#define VIEW_DISTANCE 128 #define VIEW_DISTANCE 512
#define MAX_SELECTION_DISTANCE 5 #define MAX_SELECTION_DISTANCE 5
typedef uint8_t BlockType; typedef uint8_t BlockType;
@ -31,5 +31,6 @@ enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS, BTYPE_METAL, BTYPE_ICE, BT
#define TEXTURE_PATH "../SQCSim2021/media/textures/" #define TEXTURE_PATH "../SQCSim2021/media/textures/"
#define SHADER_PATH "../SQCSim2021/media/shaders/" #define SHADER_PATH "../SQCSim2021/media/shaders/"
#define AUDIO_PATH "../SQCSim2021/media/audio/" #define AUDIO_PATH "../SQCSim2021/media/audio/"
#define CHUNK_PATH "../SQCSim2021/media/chunks/"
#endif // DEFINE_H__ #endif // DEFINE_H__

View File

@ -8,8 +8,7 @@ Engine::Engine() { }
Engine::~Engine() { } Engine::~Engine() { }
void Engine::Init() void Engine::Init() {
{
GLenum glewErr = glewInit(); GLenum glewErr = glewInit();
if (glewErr != GLEW_OK) { if (glewErr != GLEW_OK) {
std::cerr << " ERREUR GLEW : " << glewGetErrorString(glewErr) << std::endl; std::cerr << " ERREUR GLEW : " << glewGetErrorString(glewErr) << std::endl;
@ -18,17 +17,21 @@ void Engine::Init()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluPerspective(45.0f, (float)Width() / (float)Height(), 0.0001f, 1000.0f); gluPerspective(45.0f, (float)Width() / (float)Height(), 0.0001f, 1000.0f);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH); //glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glDisable(GL_FRAMEBUFFER_SRGB);
glEnable(GL_BLEND);
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
// Light // Light
GLfloat light0Pos[4] = { 0.0f, CHUNK_SIZE_Y, 0.0f, 1.0f }; GLfloat light0Pos[4] = { 0.0f, CHUNK_SIZE_Y, 0.0f, 1.0f };
GLfloat light0Amb[4] = { 0.2f, 0.2f, 0.2f, 1.f }; GLfloat light0Amb[4] = { 0.2f, 0.2f, 0.2f, 1.f };
@ -41,11 +44,14 @@ void Engine::Init()
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diff); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diff);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0Spec); glLightfv(GL_LIGHT0, GL_SPECULAR, light0Spec);
// Init manifeste de chunks renderés.
m_renderManifest.reserve(3000);
// Objet de skybox avec sa propre texture et son propre shader! // Objet de skybox avec sa propre texture et son propre shader!
m_skybox.Init(0.00013f); m_skybox.Init(0.00013f);
// Objet de musique! // Objet de musique!
m_audio.ToggleMusicState(); //m_audio.ToggleMusicState();
// Init Chunks // Init Chunks
m_world.GetChunks().Reset(nullptr); m_world.GetChunks().Reset(nullptr);
@ -67,7 +73,7 @@ void Engine::LoadResource() {
TextureAtlas::TextureIndex texGrassIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "grass.png"); TextureAtlas::TextureIndex texGrassIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "grass.png");
TextureAtlas::TextureIndex texMetalIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal.png"); TextureAtlas::TextureIndex texMetalIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal.png");
if (!m_textureAtlas.Generate(128, false)) { if (!m_textureAtlas.Generate(512, false)) {
std::cout << " Unable to generate texture atlas ..." << std::endl; std::cout << " Unable to generate texture atlas ..." << std::endl;
abort(); abort();
} }
@ -101,7 +107,7 @@ void Engine::DrawHud(float elapsedTime) {
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND); //glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix(); glPushMatrix();
@ -119,6 +125,9 @@ void Engine::DrawHud(float elapsedTime) {
ss << " Rendered Chunks : " << m_renderCount; ss << " Rendered Chunks : " << m_renderCount;
PrintText(10, Height() - 35, ss.str()); PrintText(10, Height() - 35, ss.str());
ss.str(""); ss.str("");
ss << " Bad Hits on Chunks : " << m_badHitCount;
PrintText(10, Height() - 45, ss.str());
ss.str("");
ss << " Velocity : " << m_player.GetVelocity(); // IMPORTANT : on utilise l operateur << pour afficher la position ss << " Velocity : " << m_player.GetVelocity(); // IMPORTANT : on utilise l operateur << pour afficher la position
PrintText(10, 10, ss.str()); PrintText(10, 10, ss.str());
ss.str(""); ss.str("");
@ -146,7 +155,9 @@ void Engine::DrawHud(float elapsedTime) {
glVertex2i(0, crossSize); glVertex2i(0, crossSize);
glEnd(); glEnd();
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
glDisable(GL_BLEND); //glDisable(GL_BLEND);
//glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_DST_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPopMatrix(); glPopMatrix();
@ -198,25 +209,29 @@ void Engine::Render(float elapsedTime) {
m_player.ApplyTransformation(skybox, false); // Version d'ApplyTransformation qui ne tient compte que de la rotation m_player.ApplyTransformation(skybox, false); // Version d'ApplyTransformation qui ne tient compte que de la rotation
// (donc l'objet ne bouge pas relativement au joueur, ce qui est pratique pour une skybox!). // (donc l'objet ne bouge pas relativement au joueur, ce qui est pratique pour une skybox!).
glDisable(GL_LIGHT0); glDisable(GL_LIGHT0);
m_skybox.Render(skybox); //m_skybox.Render(skybox);
// Génération/Update de Chunks.
glEnable(GL_LIGHT0); glEnable(GL_LIGHT0);
if (m_mouseL)
ChangeBlockAtCursor(BTYPE_DIRT);
else if (m_mouseR)
ChangeBlockAtCursor(BTYPE_AIR);
// Génération/Update des Chunks.
m_textureAtlas.Bind(); m_textureAtlas.Bind();
int cx = m_player.GetPosition().x; int cx = m_player.GetPosition().x;
int cy = m_player.GetPosition().z; int cy = m_player.GetPosition().z;
static int frameGenerate = 0; static int frameGenerate = 0;
static int frameUpdate = 0; static int frameUpdate = 0;
int side = 0; int side = 0;
m_shader01.Use();
m_renderCount = 0;
if (frameGenerate > 0) --frameGenerate; if (frameGenerate > 0) --frameGenerate;
if (frameUpdate > 0) --frameUpdate; if (frameUpdate > 0) --frameUpdate;
if (!frameGenerate || !frameUpdate) if (!frameGenerate || !frameUpdate)
while (side * CHUNK_SIZE_X <= VIEW_DISTANCE) { while (side * CHUNK_SIZE_X <= VIEW_DISTANCE * 2) {
int tx = -side, ty = -side; int tx = -side, ty = -side;
for (; tx <= side; ++tx) for (; tx <= side; ++tx)
@ -231,77 +246,69 @@ void Engine::Render(float elapsedTime) {
++side; ++side;
} }
// Rendering de Chunks. // Rendering des Chunks.
all.Use(); m_shader01.Use();
if (m_renderer) { // Choix d'algorithme de rendu pour comparer. m_renderCount = 0;
Vector3f direct = m_player.GetDirection(); m_badHitCount = 0;
Vector3f renderpos = m_player.GetPosition(); Vector3f angle;
Vector3f cursor;
Vector3f direct = m_player.GetDirection();
Vector3f pos = m_player.GetPosition() - direct;
direct.y = 0; direct.y = 0;
direct.Normalize(); direct.Normalize();
pos.y = 1;
m_renderManifest.clear();
Vector3f viewL = renderpos - direct * CHUNK_SIZE_X * 2, for (int dist = VIEW_DISTANCE; dist >= 0; dist -= CHUNK_SIZE_X) {
viewR = viewL; // Configuration du radar.
angle.x = direct.z + direct.x;
angle.y = 0;
angle.z = direct.z - direct.x;
angle.Normalize();
viewL.Dot(direct); float sinus = .01745240643; // sin(1 degré)
viewR.Dot(direct); float cosinus = .99984769515; // cos(1 degré)
int echantillons = 90;
for (int x = -3; x <= VIEW_DISTANCE / CHUNK_SIZE_X; ++x) { for (int radar = 0; radar < echantillons; ++radar) {
int chunkxL = -1, chunkyL = -1, chunkxR = -1, chunkyR = -1; float x = angle.x;
float z = angle.z;
if (m_world.ChunkAt(viewL)) { angle.x = x * cosinus - z * sinus;
chunkxL = m_world.ChunkAt(viewL)->GetPosX(); angle.z = z * cosinus + x * sinus;
chunkyL = m_world.ChunkAt(viewL)->GetPosY(); angle.Normalize();
}
if (m_world.ChunkAt(viewR)) {
chunkxR = m_world.ChunkAt(viewR)->GetPosX();
chunkyR = m_world.ChunkAt(viewR)->GetPosY();
}
if (chunkxL == chunkxR) { cursor = pos - direct * CHUNK_SIZE_X * 2 + angle * dist;
++chunkxR; if (cursor.y >= 128.f || cursor.y >= 0.f) cursor.y = 1;
--chunkxL;
}
if (chunkyL == chunkyR) {
++chunkyR;
--chunkyL;
}
if (chunkxL >= 0 && chunkyL >= 0 && chunkxR >= 0 && chunkyR >= 0) bool valide = true;
for (int rx = chunkxL; rx != chunkxR; chunkxL < chunkxR ? ++rx : --rx)
for (int ry = chunkyL; ry != chunkyR; chunkyL < chunkyR ? ++ry : --ry) { if (m_world.ChunkAt(cursor)) {
all.ApplyTranslation(rx * CHUNK_SIZE_X, 0, ry * CHUNK_SIZE_Z); int chx, chy;
all.Use(); m_world.ChunkAt(cursor)->GetPosition(chx, chy);
if (m_world.GetChunks().Get(rx, ry)) { for (int index = 0; index < m_renderManifest.size(); ++index)
m_world.GetChunks().Get(rx, ry)->Render(); if (m_renderManifest[index] == Vector3i(chx, 0, chy)) {
++m_renderCount; valide = false;
} ++m_badHitCount;
all.ApplyTranslation(-rx * CHUNK_SIZE_X, 0, -ry * CHUNK_SIZE_Z);
} }
viewL.x += (direct.x + direct.z) * CHUNK_SIZE_X / 2; if (valide) {
viewL.z += (direct.z - direct.x) * CHUNK_SIZE_X / 2; all.ApplyTranslation(chx * CHUNK_SIZE_X, 0, chy * CHUNK_SIZE_Z);
viewR.x += (direct.x - direct.z) * CHUNK_SIZE_X / 2; all.Use();
viewR.z += (direct.z + direct.x) * CHUNK_SIZE_X / 2; float dist = (pos - cursor).Length();
} float blend = ((float)VIEW_DISTANCE - dist * 2.f + 128.f) / (float)VIEW_DISTANCE;
} glBlendColor(0.f,0.f,0.f,blend);
else {
for (int chx = 0; chx < WORLD_SIZE_X; chx++)
for (int chy = 0; chy < WORLD_SIZE_Y; chy++) {
all.ApplyTranslation(chx * CHUNK_SIZE_X, 0, chy * CHUNK_SIZE_Z);
all.Use();
if (m_world.GetChunks().Get(chx, chy)) {
m_world.GetChunks().Get(chx, chy)->Render(); m_world.GetChunks().Get(chx, chy)->Render();
all.ApplyTranslation(-chx * CHUNK_SIZE_X, 0, -chy * CHUNK_SIZE_Z);
m_renderManifest.push_back(Vector3i(chx, 0, chy));
++m_renderCount; ++m_renderCount;
} }
all.ApplyTranslation(-chx * CHUNK_SIZE_X, 0, -chy * CHUNK_SIZE_Z);
} }
}
} }
m_shader01.Disable();
if (m_mouseL) m_shader01.Disable();
GetBlockAtCursor(BTYPE_DIRT);
else if (m_mouseR) GetBlockAtCursor(BTYPE_AIR);
if (m_wireframe) if (m_wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -309,15 +316,19 @@ void Engine::Render(float elapsedTime) {
if (m_wireframe) if (m_wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
if (m_player.GetPosition().y < -20.f) if (m_player.GetPosition().y < -20.f)
m_player = Player(Vector3f(CHUNK_SIZE_X * WORLD_SIZE_X / 2, CHUNK_SIZE_Y + 1.7f, CHUNK_SIZE_Z * WORLD_SIZE_X / 2)); // Respawn si le bonho- joueur tombe en bas du monde. m_player = Player(Vector3f(CHUNK_SIZE_X * WORLD_SIZE_X / 2, CHUNK_SIZE_Y + 1.8f, CHUNK_SIZE_Z * WORLD_SIZE_X / 2)); // Respawn si le bonho- joueur tombe en bas du monde.
} }
void Engine::KeyPressEvent(unsigned char key) void Engine::KeyPressEvent(unsigned char key)
{ {
switch (key) { switch (key) {
case 36: // ESC case 36: // ESC
for (int x = 0; x < WORLD_SIZE_X; ++x) // Les destructeurs de Chunks ont de la misère je les aide un peu!
for (int y = 0; y < WORLD_SIZE_Y; ++y)
if (m_world.GetChunks().Get(x,y))
m_world.GetChunks().Get(x, y)->~Chunk();
m_world.GetChunks().Reset(nullptr); // Hack cheap qui empêche d'avoir une exception en sortant du jeu
Stop(); Stop();
break; break;
case 94: // F10 case 94: // F10
@ -490,17 +501,80 @@ bool Engine::GenerateChunk(int chx, int chy) {
if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z && if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z &&
chx >= 0 && chy >= 0) chx >= 0 && chy >= 0)
if (!m_world.ChunkAt(chx, 1, chy)) { if (!m_world.ChunkAt(chx, 1, chy)) {
m_world.GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, new Chunk(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z));
Chunk* chunk = m_world.GetChunks().Get(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z);
for (int x = 0; x < CHUNK_SIZE_X; ++x) std::ostringstream pos;
for (int z = 0; z < CHUNK_SIZE_Z; ++z) pos << CHUNK_PATH << chx / CHUNK_SIZE_X << '_' << chy / CHUNK_SIZE_Z << ".chunk";
for (int y = 0; y < 32; ++y)
chunk->SetBlock(x, y, z, (chx + chy) % (BTYPE_LAST - 1) + 1, &m_world);
std::ifstream input(pos.str().c_str(), std::fstream::binary);
if (input.fail()) {
m_world.GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, new Chunk(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z));
Chunk* chunk = m_world.GetChunks().Get(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z);
for (int x = 0; x < CHUNK_SIZE_X; ++x)
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
Vector3f perlin;
perlin.z = x * CHUNK_SIZE_X + CHUNK_SIZE_X * chx;
perlin.y = 0;
perlin.x = z * CHUNK_SIZE_Z + CHUNK_SIZE_Z * chy;
perlin.Normalize();
float height = m_perlin.Get(perlin.x, perlin.z) * 3 - 32;
for (int y = 0; y <= (int)height % CHUNK_SIZE_Y; ++y) {
chunk->SetBlock(x, y, z, BTYPE_METAL, &m_world);
}
}
for (int x = 0; x < CHUNK_SIZE_X; ++x)
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
Vector3f perlin;
perlin.x = x * CHUNK_SIZE_X + CHUNK_SIZE_X * chx;
perlin.y = 0;
perlin.z = z * CHUNK_SIZE_Z + CHUNK_SIZE_Z * chy;
perlin.Normalize();
float height = m_perlin.Get(perlin.x, perlin.z) + 16;
for (int y = 0; y <= (int)height % CHUNK_SIZE_Y; ++y) {
if (chunk->GetBlock(x, y, z) == BTYPE_AIR)
chunk->SetBlock(x, y, z, BTYPE_GRASS, &m_world);
}
}
for (int x = 0; x < CHUNK_SIZE_X; ++x)
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
for (int y = 0; y <= 10; ++y) {
if (chunk->GetBlock(x, y, z) == BTYPE_AIR)
chunk->SetBlock(x, y, z, BTYPE_ICE, &m_world);
}
}
for (int x = 0; x < CHUNK_SIZE_X; ++x)
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
for (int y = 0; y < CHUNK_SIZE_Y; ++y) {
Vector3f perlin;
perlin.x = x * CHUNK_SIZE_X + CHUNK_SIZE_X * chx;
perlin.y = (x + z) * CHUNK_SIZE_Y;
perlin.z = z * CHUNK_SIZE_Z + CHUNK_SIZE_Z * chy;
perlin.Normalize();
float height = m_perlin.Get(perlin.x, perlin.y, perlin.z);
if (chunk->GetBlock(x, y, z) != BTYPE_AIR && height > 18)
chunk->SetBlock(x, y, z, BTYPE_DIRT, &m_world);
}
}
}
else {
input.seekg(0, std::ios_base::end);
int size = input.tellg();
input.seekg(0, std::ios_base::beg);
char* data = new char[size];
input.read(data, size);
input.close();
m_world.GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, new Chunk(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, data));
delete[] data;
}
std::cout << "Chunk generated: " << chx / CHUNK_SIZE_X << ", " << chy / CHUNK_SIZE_Z << std::endl; std::cout << "Chunk generated: " << chx / CHUNK_SIZE_X << ", " << chy / CHUNK_SIZE_Z << std::endl;
return true; return true;
} }
return false; return false;
@ -515,7 +589,7 @@ void Engine::UpdateWorld(int& generates, int& updates, int chx, int chy) {
} }
} }
void Engine::GetBlockAtCursor(BlockType blockType) { void Engine::ChangeBlockAtCursor(BlockType blockType) {
Vector3f currentPos = m_player.GetPosition(); Vector3f currentPos = m_player.GetPosition();
Vector3f currentBlock = currentPos; Vector3f currentBlock = currentPos;
Vector3f ray = m_player.GetDirection(); Vector3f ray = m_player.GetDirection();
@ -527,7 +601,7 @@ void Engine::GetBlockAtCursor(BlockType blockType) {
currentBlock += ray / 10.f; currentBlock += ray / 10.f;
BlockType bt = m_world.BlockAt(currentBlock); BlockType bt = m_world.BlockAt(currentBlock);
if (bt != BTYPE_AIR) if (bt != BTYPE_AIR)
found = true; found = true;
} }
@ -540,7 +614,7 @@ void Engine::GetBlockAtCursor(BlockType blockType) {
BlockType bt = m_world.BlockAt(currentBlock); BlockType bt = m_world.BlockAt(currentBlock);
if (bt == BTYPE_AIR) { if (bt == BTYPE_AIR) { // Vérification pour être sûr que le bloc à changer n'est pas dans le joueur.
int Bx = (int)currentBlock.x; int Bx = (int)currentBlock.x;
int By = (int)currentBlock.y; int By = (int)currentBlock.y;
int Bz = (int)currentBlock.z; int Bz = (int)currentBlock.z;
@ -551,12 +625,12 @@ void Engine::GetBlockAtCursor(BlockType blockType) {
int PyC = (int)(currentPos.y - 1.7f); int PyC = (int)(currentPos.y - 1.7f);
int Pz = (int)currentPos.z; int Pz = (int)currentPos.z;
if (!(Bx == Px && if (!(Bx == Px &&
(By == PyA || (By == PyA ||
By == PyB || By == PyB ||
By == PyC) && By == PyC) &&
Bz == Pz)) Bz == Pz))
found = true; found = true;
} }
} }
} }

View File

@ -13,6 +13,7 @@
#include "blockinfo.h" #include "blockinfo.h"
#include "array2d.h" #include "array2d.h"
#include "world.h" #include "world.h"
#include "perlin.h"
class Engine : public OpenglContext { class Engine : public OpenglContext {
public: public:
@ -37,17 +38,19 @@ private:
bool GenerateChunk(int chx, int chy); bool GenerateChunk(int chx, int chy);
void UpdateWorld(int& generates, int& updates, int chx, int chy); void UpdateWorld(int& generates, int& updates, int chx, int chy);
void GetBlockAtCursor(BlockType blocktype); void ChangeBlockAtCursor(BlockType blocktype);
bool m_wireframe = false; bool m_wireframe = false;
bool m_renderer = false; bool m_renderer = false;
int m_renderCount = 0; int m_renderCount = 0;
int m_badHitCount = 0;
std::vector<Vector3i> m_renderManifest;
BlockInfo* m_blockinfo[BTYPE_LAST]; BlockInfo* m_blockinfo[BTYPE_LAST];
TextureAtlas m_textureAtlas = TextureAtlas(BTYPE_LAST); TextureAtlas m_textureAtlas = TextureAtlas(BTYPE_LAST);
World m_world = World(); World m_world = World();
Perlin m_perlin = Perlin(3,5.f,64.f,12345);
Texture m_textureFloor; Texture m_textureFloor;
Texture m_textureSkybox; Texture m_textureSkybox;
@ -59,7 +62,7 @@ private:
Shader m_shader01; Shader m_shader01;
Audio m_audio = Audio(AUDIO_PATH "music01.wav"); Audio m_audio = Audio(AUDIO_PATH "music01.wav");
Player m_player = Player(Vector3f(CHUNK_SIZE_X * WORLD_SIZE_X / 2, CHUNK_SIZE_Y + 1.7f, CHUNK_SIZE_Z * WORLD_SIZE_X / 2)); Player m_player = Player(Vector3f(CHUNK_SIZE_X * WORLD_SIZE_X / 2, CHUNK_SIZE_Y + 1.8f, CHUNK_SIZE_Z * WORLD_SIZE_X / 2));
bool m_keyW = false; bool m_keyW = false;
bool m_keyA = false; bool m_keyA = false;

View File

@ -1,90 +0,0 @@
#include <iostream>
#include <fstream>
#include <cstdlib>
void FichierTexte()
{
std::ofstream sortie("fichier.txt"); // std::fstream::app
if(!sortie.is_open())
{
std::cerr << "Erreur d'ouverture de fichier" << std::endl;
return;
}
sortie << "Premiere ligne de plusieurs mots" << std::endl;
sortie << "Age: " << 6 << std::endl;
sortie.close();
std::ifstream entree("fichier.txt");
if(!entree.is_open())
{
std::cerr << "Erreur d'ouverture de fichier" << std::endl;
return;
}
std::string mot;
std::string line;
int age;
entree >> mot;
std::cout << mot << std::endl;
std::getline(entree, line);
std::cout << line << std::endl;
entree >> mot;
entree >> age;
std::cout << age << std::endl;
// TODO montrer eof..
}
void FichierBinaire()
{
srand(time(0));
char data[1024];
for(int i = 0; i < sizeof(data); ++i)
data[i] = rand() % 256;
std::ofstream sortie("fichier.bin", std::fstream::binary);
sortie.write(data, sizeof(data));
sortie.close();
// Relire le fichier et comparer...
std::ifstream entree("fichier.bin", std::fstream::binary);
// Obtenir la taille du fichier
entree.seekg(0, std::ios_base::end);
int size = entree.tellg();
entree.seekg(0, std::ios_base::beg);
char* data2 = new char[size];
entree.read(data2, size);
entree.close();
// Comparaison
bool pareil = true;
for(int i = 0; i < size; ++i)
{
if(data[i] != data2[i])
{
pareil = false;
break;
}
}
std::cout << "Les donnees sont " << (pareil ? "pareilles" : "differentes") << std::endl;
delete [] data2;
}
int main()
{
FichierTexte();
FichierBinaire();
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -7,6 +7,7 @@ void main()
texel = texture2D(tex,gl_TexCoord[0].st); texel = texture2D(tex,gl_TexCoord[0].st);
texel *= light; texel *= light;
texel.a = 255;
gl_FragColor = texel; gl_FragColor = texel;
} }

View File

@ -2,7 +2,7 @@ varying vec4 light;
void main() void main()
{ {
light = gl_Color; light = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0; gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform(); gl_Position = ftransform();
} }

View File

@ -26,5 +26,4 @@ class Shader
bool CheckProgramError(GLenum program, bool showWarning, bool verbose); bool CheckProgramError(GLenum program, bool showWarning, bool verbose);
}; };
#endif // SHADER_H__ #endif // SHADER_H__

View File

@ -35,3 +35,4 @@ BlockType World::BlockAt(float x, float y, float z, BlockType defaultBlockType)
BlockType World::BlockAt(const Vector3f& pos, BlockType defaultBlockType) const { BlockType World::BlockAt(const Vector3f& pos, BlockType defaultBlockType) const {
return BlockAt(pos.x, pos.y, pos.z, defaultBlockType); return BlockAt(pos.x, pos.y, pos.z, defaultBlockType);
} }

View File

@ -5,6 +5,8 @@
#include "array2d.h" #include "array2d.h"
#include "vector3.h" #include "vector3.h"
#include "transformation.h" #include "transformation.h"
#include <fstream>
#include <string>
class Chunk; class Chunk;