X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld.cpp;h=5244d152bbe1326e190d2819120c1e54d7b3729f;hb=30d36f3d545617faef76f90c4121d6ed118ba272;hp=2dd7b307a6ffa292fd24027414af746a5123504b;hpb=482114e156e91729f2529ea6bb1fe98dacdee97f;p=blank.git diff --git a/src/world.cpp b/src/world.cpp index 2dd7b30..5244d15 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1,102 +1,163 @@ #include "world.hpp" +#include +#include + namespace blank { -const BlockType BlockType::DEFAULT; - -void BlockType::FillVBO( - const glm::vec3 &pos, - std::vector &vertices, - std::vector &colors, - std::vector &normals -) const { - vertices.emplace_back(pos.x , pos.y , pos.z + 1); // front - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z ); // back - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); // top - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z ); // bottom - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z ); // left - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); // right - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1); - - colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // front - colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // back - colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // top - colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // bottom - colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // left - colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // right - - normals.insert(normals.end(), 6, glm::vec3( 0.0f, 0.0f, 1.0f)); // front - normals.insert(normals.end(), 6, glm::vec3( 0.0f, 0.0f, -1.0f)); // back - normals.insert(normals.end(), 6, glm::vec3( 0.0f, 1.0f, 0.0f)); // top - normals.insert(normals.end(), 6, glm::vec3( 0.0f, -1.0f, 0.0f)); // bottom - normals.insert(normals.end(), 6, glm::vec3(-1.0f, 0.0f, 0.0f)); // left - normals.insert(normals.end(), 6, glm::vec3( 1.0f, 0.0f, 0.0f)); // right -} +World::World() +: blockType() +, blockShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}) +, stairShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}, { 0.0f, 0.0f }) +, slabShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }}) +, generate(0) +, chunks(blockType, generate) +, player() { + BlockType::Faces block_fill = { true, true, true, true, true, true }; + BlockType::Faces slab_fill = { false, true, false, false, false, false }; + BlockType::Faces stair_fill = { false, true, false, false, false, true }; + + { // white block + BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // white slab + BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // white stair + BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } + + { // red block + BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // red slab + BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // red stair + BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } + + { // green block + BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // green slab + BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // green stair + BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } + + { // blue block + BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // blue slab + BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // blue stair + BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } + generate.Space(0); + generate.Solids({ 1, 4, 7, 10 }); -Chunk::Chunk() -: blocks(Size()) -, model() -, dirty(false) { + player.Position({ 4.0f, 4.0f, 4.0f }); + chunks.Generate({ -4, -4, -4 }, { 5, 5, 5}); } -void Chunk::Draw() { - if (dirty) { - Update(); +bool World::Intersection( + const Ray &ray, + const glm::mat4 &M, + Chunk **chunk, + int *blkid, + float *dist, + glm::vec3 *normal) { + Chunk *closest_chunk = nullptr; + int closest_blkid = -1; + float closest_dist = std::numeric_limits::infinity(); + glm::vec3 closest_normal; + + for (Chunk &cur_chunk : chunks.Loaded()) { + int cur_blkid; + float cur_dist; + glm::vec3 cur_normal; + if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player.ChunkCoords()), &cur_blkid, &cur_dist, &cur_normal)) { + if (cur_dist < closest_dist) { + closest_chunk = &cur_chunk; + closest_blkid = cur_blkid; + closest_dist = cur_dist; + closest_normal = cur_normal; + } + } + } + + if (chunk) { + *chunk = closest_chunk; + } + if (blkid) { + *blkid = closest_blkid; } - model.Draw(); + if (dist) { + *dist = closest_dist; + } + if (normal) { + *normal = closest_normal; + } + return closest_chunk; } -int Chunk::VertexCount() const { - // TODO: query blocks as soon as type shapes are implemented - return Size() * 6 * 6; +Chunk &World::Next(const Chunk &to, const glm::tvec3 &dir) { + const Chunk::Pos tgt_pos = to.Position() + dir; + return chunks.ForceLoad(tgt_pos); } -void Chunk::Update() { - model.Clear(); - model.Reserve(VertexCount()); - for (int i = 0; i < Size(); ++i) { - if (blocks[i].type->visible) { - blocks[i].type->FillModel(ToCoords(i), model); +void World::Update(int dt) { + player.Update(dt); + chunks.Rebase(player.ChunkCoords()); + chunks.Update(); +} + + +void World::Render(DirectionalLighting &program) { + program.SetLightDirection({ -1.0f, -3.0f, -2.0f }); + program.SetView(glm::inverse(player.Transform(player.ChunkCoords()))); + + for (Chunk &chunk : chunks.Loaded()) { + glm::mat4 m(chunk.Transform(player.ChunkCoords())); + program.SetM(m); + glm::mat4 mvp(program.GetVP() * m); + if (!CullTest(Chunk::Bounds(), mvp)) { + chunk.Draw(); } } - - model.Invalidate(); - dirty = false; } }