Release chuncks generation with Noise and blocks

This commit is contained in:
itqop 2024-05-15 13:25:16 +03:00
parent fe6124ea18
commit 587ce37b75
3 changed files with 1551 additions and 0 deletions

115
include/chunks.h Normal file
View File

@ -0,0 +1,115 @@
#pragma once
#include "block.h"
#include <vector>
#include <cstring>
#include <glm/vec3.hpp>
#include "renderer.h"
#include <set>
#include <FastNoiseSIMD.h>
constexpr int CHUNK_SIZE = 16;
constexpr int CHUNK_HEIGHT = 256;
class Chunk
{
public:
Block *getBlock(int x, int y, int z)
{
return &blocks[x][z][y];
}
void clearBlockData()
{
memset(blocks, 0, sizeof(blocks));
}
void calculateFaces();
glm::ivec2 &getChunkPosition()
{
return position;
}
glm::ivec2 &getChunkPositionx16()
{
return glm::ivec2(position) * glm::ivec2(16, 16);
}
void sortTransparentFaces(glm::vec3 playerPos);
friend class ChunksRenderer;
friend class ChunkManager;
protected:
void updateNeighbours();
void removeReferenceToNeighbours();
std::vector<glm::ivec3> positions[6];
std::vector<uint8_t> ao[6];
std::vector<glm::ivec2> UVs[6];
std::vector<glm::ivec3> transparentPositions[6];
std::vector<glm::ivec2> transparentUVs[6];
Block blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_HEIGHT];
glm::ivec2 position;
Chunk *chunkInFront = 0;
Chunk *chunkInBack = 0;
Chunk *chunkAtLeft = 0;
Chunk *chunkAtRight = 0;
};
class ChunkManager
{
public:
ChunkManager();
void setGridSize(int size, glm::ivec2 playerPos);
void setPlayerPos(glm::vec2 playerPos);
friend class ChunksRenderer;
glm::ivec2 bottomCorner;
glm::ivec2 topCorner;
bool rayCast(glm::ivec3 &pos, glm::ivec3 &lastPos, glm::vec3 start, glm::vec3 direction, float maxRaySize = 10);
Block *getBlockRaw(glm::ivec3 pos, Chunk **c = nullptr);
glm::ivec2 getPlayerInChunk(glm::vec2 playerPos);
glm::ivec2 getPlayerInChunk(glm::vec3 playerPos)
{
return getPlayerInChunk({ playerPos.x, playerPos.z });
}
bool placeBlock(glm::ivec3 pos, Block b, glm::vec3 playerPos);
Chunk *getChunk(glm::ivec2 pos);
private:
glm::ivec2 computeBottomCorner(glm::vec2 playerPos, int size);
glm::ivec2 computeTopCorner(glm::vec2 playerPos, int size);
void setNeighbours(std::set<int> &newCreatedChunks, std::set<int> &chunksToRecalculate);
int gridSize;
std::vector< Chunk * > loadedChunks;
glm::ivec2 playerPos;
FastNoiseSIMD *heightNoise = FastNoiseSIMD::NewFastNoiseSIMD();
void generateChunk(Chunk &c);
};

1261
src/chunks.cpp Normal file

File diff suppressed because it is too large Load Diff

175
src/game.cpp Normal file
View File

@ -0,0 +1,175 @@
#include "game.h"
#include <iostream>
#include "glm/gtc/matrix_transform.hpp"
#include "chunks.h"
void Game::onCreate(int screenW, int screenH)
{
camera = new CreativeModeCamera();
isCreativeCamera = true;
updateWindowMetrics(screenW, screenH);
//create 2D renderer
renderer2d.create();
font.createFromFile(RESOURCES_PATH "roboto_black.ttf");
camera->getPosition() = { 0,70,0 };
chunkManager.setGridSize(10, glm::vec2{camera->getPosition().x, camera->getPosition().z});
//std::cout << chunkManager.bottomCorner.x << " " << chunkManager.bottomCorner.y << "\n";
//std::cout << chunkManager.topCorner.x << " " << chunkManager.topCorner.y << "\n";
arrowTexture.loadFromFile(RESOURCES_PATH "arrow.png");
skyBox.create();
const char* faces[6] =
{
RESOURCES_PATH "right.jpg",
RESOURCES_PATH "left.jpg",
RESOURCES_PATH "top.jpg",
RESOURCES_PATH "bottom.jpg",
RESOURCES_PATH "front.jpg",
RESOURCES_PATH "back.jpg"
};
skyBox.loadTexturesFromCrossTexture(RESOURCES_PATH "skyBox.png");
}
void Game::onUpdate(float deltaTime, const GameInput &input)
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glDisable(GL_MULTISAMPLE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//input
{
if(input.getKey(GameInput::C).isReleased())
{
if(isCreativeCamera)
{
Camera *c = new FlyCamera();
*c = *camera;
delete camera;
camera = c;
}
else
{
Camera *c = new CreativeModeCamera();
*c = *camera;
delete camera;
camera = c;
}
isCreativeCamera = !isCreativeCamera;
}
if (input.getKey(GameInput::P).isReleased())
{
renderer.getAo() = !renderer.getAo();
}
const float speed = 16 * deltaTime;
glm::vec3 movePos = {};
if (input.getKey(GameInput::LEFT).isHeld())
{
movePos.x -= speed;
}
if (input.getKey(GameInput::RIGHT).isHeld())
{
movePos.x += speed;
}
if (input.getKey(GameInput::FRONT).isHeld())
{
movePos.z -= speed;
}
if (input.getKey(GameInput::BACK).isHeld())
{
movePos.z += speed;
}
if (input.getKey(GameInput::DOWN).isHeld())
{
movePos.y -= speed;
}
if (input.getKey(GameInput::UP).isHeld())
{
movePos.y += speed;
}
camera->move(movePos);
static int lastMouseX;
static int lastMouseY;
glm::vec2 delta = input.getMousePos();
delta -= glm::vec2(lastMouseX, lastMouseY);
camera->rotateCamera(delta * deltaTime);
lastMouseX = input.getMousePosX();
lastMouseY = input.getMousePosY();
}
chunkManager.setPlayerPos(glm::vec2{ camera->getPosition().x, camera->getPosition().z });
glm::ivec3 rayEnd = {};
glm::ivec3 blockPlace = {};
if(chunkManager.rayCast(rayEnd, blockPlace, camera->getPosition() +
glm::vec3{0.5, 0.5, 0.5},
camera->getViewDirection()))
{
auto b = chunkManager.getBlockRaw(rayEnd);
if(b)
{
//std::cout << *b << "\n";
}
if(input.getKey(GameInput::RIGHT_CLICK).isReleased())
{
chunkManager.placeBlock(blockPlace, stone , camera->getPosition());
}
if (input.getKey(GameInput::LEFT_CLICK).isReleased())
{
chunkManager.placeBlock(rayEnd, 0, camera->getPosition());
}
}
renderer.render(*camera, chunkManager, skyBox);
renderer2d.renderRectangle({ screenW / 2 - 15, screenH / 2 - 15, 30, 30 },
{}, {},
arrowTexture);
renderer2d.flush();
}
void Game::updateWindowMetrics(int screenW, int screenH)
{
this->screenW = screenW;
this->screenH = screenH;
renderer2d.updateWindowMetrics(screenW, screenH);
glViewport(0, 0, screenW, screenH);
camera->updateAspectRatio(screenW, screenH);
}