Kaynağa Gözat

face class, base for blocks, block checks in renderer

Kajetan Johannes Hammerle 6 yıl önce
ebeveyn
işleme
8a7846f86c

+ 26 - 1
Makefile

@@ -2,7 +2,7 @@ VERSION = -std=c++14
 CFLAGS = $(shell pkg-config --cflags glfw3)
 LDFLAGS = $(shell pkg-config --static --libs glfw3) -lGL -lGLEW -lpng
 
-all: game
+all: run_client
 
 run_client: game_client
 	vblank_mode=0 optirun ./game_client
@@ -13,6 +13,8 @@ game_client: MainClient.cpp\
 	SSAOShader.o SSAOBlurShader.o WorldPostShader.o OverlayShader.o\
 	Matrix3D.o Matrix3DStack.o StackOverflow.o StackUnderflow.o Vector3D.o Plane3D.o Camera3D.o\
 	Client.o\
+	Block.o Blocks.o BlockAir.o\
+	Face.o\
 	Chunk.o World.o ChunkRenderer.o ClientChunkProvider.o
 	g++ $(VERSION) -o $@ MainClient.cpp *.o $(LDFLAGS)
 
@@ -80,6 +82,26 @@ ChunkRenderer.o: client/rendering/ChunkRenderer.h client/rendering/ChunkRenderer
 	
 ClientChunkProvider.o: client/rendering/ClientChunkProvider.h client/rendering/ClientChunkProvider.cpp world/IChunkProvider.h
 	g++ $(VERSION) -c client/rendering/ClientChunkProvider.cpp -o $@
+
+# ------------------------------------------------------------------------------	
+# Utils
+# ------------------------------------------------------------------------------
+	
+Face.o: utils/Face.h utils/Face.cpp
+	g++ $(VERSION) -c utils/Face.cpp -o $@
+	
+# ------------------------------------------------------------------------------	
+# Block
+# ------------------------------------------------------------------------------
+	
+Block.o: block/Block.h block/Block.cpp
+	g++ $(VERSION) -c block/Block.cpp -o $@
+	
+Blocks.o: block/Blocks.h block/Blocks.cpp
+	g++ $(VERSION) -c block/Blocks.cpp -o $@
+	
+BlockAir.o: block/BlockAir.h block/BlockAir.cpp
+	g++ $(VERSION) -c block/BlockAir.cpp -o $@
 	
 # ------------------------------------------------------------------------------	
 # World
@@ -142,3 +164,6 @@ test: MainTest.cpp data/UnsortedArrayList.h data/HashMap.h
 	
 clean:
 	rm -f game_server game_client *.o test
+
+clean_o:
+	rm -f *.o

+ 32 - 0
block/Block.cpp

@@ -0,0 +1,32 @@
+#include "Block.h"
+
+#include <iostream>
+
+using namespace std;
+
+BlockId Block::idCounter = 0;
+
+Block::Block()
+{
+    id = idCounter++;
+    cout << "Block " << id << endl;
+}
+
+Block::~Block()
+{
+}
+
+BlockId Block::getId() const
+{
+    return id;
+}
+
+bool Block::isEmpty() const
+{
+    return false;
+}
+
+bool Block::isBlockingFace(Face& f) const
+{
+    return !isEmpty();
+}

+ 24 - 0
block/Block.h

@@ -0,0 +1,24 @@
+#ifndef BLOCK_H
+#define BLOCK_H
+
+#include "../utils/Face.h"
+
+typedef unsigned short BlockId;
+
+class Block
+{
+public:
+    Block();
+    virtual ~Block();
+    
+    BlockId getId() const;
+    
+    virtual bool isEmpty() const;
+    virtual bool isBlockingFace(Face& f) const;
+private:
+    static BlockId idCounter;
+    BlockId id;
+};
+
+#endif
+

+ 15 - 0
block/BlockAir.cpp

@@ -0,0 +1,15 @@
+#include "BlockAir.h"
+
+BlockAir::BlockAir()
+{
+}
+
+BlockAir::~BlockAir()
+{
+}
+
+bool BlockAir::isEmpty() const
+{
+    return true;
+}
+

+ 18 - 0
block/BlockAir.h

@@ -0,0 +1,18 @@
+#ifndef BLOCKAIR_H
+#define BLOCKAIR_H
+
+#include "Block.h"
+
+class BlockAir : public Block
+{
+public:
+    BlockAir();
+    virtual ~BlockAir();
+    
+    bool isEmpty() const override;
+private:
+
+};
+
+#endif
+

+ 42 - 0
block/Blocks.cpp

@@ -0,0 +1,42 @@
+#include "Blocks.h"
+
+const int BlockRegistry::BLOCK_AMOUNT = 2;
+const Block* BlockRegistry::BLOCKS[BLOCK_AMOUNT];
+
+const BlockAir Blocks::AIR;
+const Block Blocks::GRASS;
+
+BlockRegistry::BlockRegistry()
+{
+}
+
+void BlockRegistry::registerBlock(const Block& block)
+{
+    BlockId id = block.getId();
+    if(id >= 0 && id < BLOCK_AMOUNT && BLOCKS[id] == nullptr)
+    {
+        BLOCKS[id] = &block;
+    }
+}
+
+const Block& BlockRegistry::getBlockFromId(BlockId id)
+{
+    return *BLOCKS[(id >= 0 && id < BLOCK_AMOUNT && BLOCKS[id] != nullptr) * id];
+}
+
+void BlockRegistry::init()
+{
+    for(int i = 0; i < BLOCK_AMOUNT; i++)
+    {
+        BLOCKS[i] = nullptr;
+    }
+}
+
+void BlockRegistry::registerBlocks()
+{
+    init();
+    
+    registerBlock(Blocks::AIR);
+    registerBlock(Blocks::GRASS);
+}
+

+ 29 - 0
block/Blocks.h

@@ -0,0 +1,29 @@
+#ifndef BLOCKS_H
+#define BLOCKS_H
+
+#include "Block.h"
+#include "BlockAir.h"
+
+class BlockRegistry
+{
+public:
+    static const Block& getBlockFromId(BlockId id);
+    static void registerBlocks();
+    
+private:
+    BlockRegistry();
+    static void init();
+    static void registerBlock(const Block& block);
+    
+    static const int BLOCK_AMOUNT;
+    static const Block* BLOCKS[];
+};
+
+namespace Blocks
+{
+    extern const BlockAir AIR;
+    extern const Block GRASS;
+};
+
+#endif
+

+ 8 - 0
client/Client.cpp

@@ -1,10 +1,18 @@
 #include "Client.h"
 #include <iostream>
+#include "../block/Blocks.h"
 
 using namespace std;
 
 Client::Client() : world(&chunkProvider)
 {    
+    BlockRegistry::registerBlocks();
+    
+    cout << "HI" << endl;
+    //cout << (Blocks::AIR.getId() == Blocks::AIR.getId()) << endl;
+    cout << Blocks::AIR.getId() << endl;
+    //cout << Blocks::GRASS.getId() << endl;
+
     position.set(16, 50, -5);
     lengthAngle = -15;
     widthAngle = -20;

+ 13 - 13
client/rendering/ChunkRenderer.cpp

@@ -79,10 +79,10 @@ void ChunkRenderer::buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east
         {
             for(int z = 0; z < Chunk::DEPTH; z++)
             {
-                if(c.getBlock(x, y, z) == 1)
+                if(!c.getBlock(x, y, z).isEmpty())
                 {
                     // bottom
-                    if(y <= 0 || c.getBlock(x, y - 1, z) != 1)
+                    if(y <= 0 || !c.getBlock(x, y - 1, z).isBlockingFace(Face::UP))
                     {
                         for(int i = 0; i < 6; i++)
                         {
@@ -110,7 +110,7 @@ void ChunkRenderer::buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east
                     }
 
                     // top
-                    if(y + 1 >= Chunk::HEIGHT || c.getBlock(x, y + 1, z) != 1)
+                    if(y + 1 >= Chunk::HEIGHT || !c.getBlock(x, y + 1, z).isBlockingFace(Face::DOWN))
                     {
                         for(int i = 0; i < 6; i++)
                         {
@@ -136,10 +136,10 @@ void ChunkRenderer::buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east
                         m.addPosition(x + 0.0f, y + 1.0f, z + 1.0f);
                         m.addPosition(x + 1.0f, y + 1.0f, z + 1.0f);
                     }
-
+                    
                     // right
-                    if((x + 1 < Chunk::WIDTH && c.getBlock(x + 1, y, z) != 1) ||
-                        (x + 1 >= Chunk::WIDTH && (north == nullptr || north->getBlock(x + 1 - Chunk::WIDTH, y, z) != 1)))
+                    if((x + 1 < Chunk::WIDTH && !c.getBlock(x + 1, y, z).isBlockingFace(Face::SOUTH)) ||
+                        (x + 1 >= Chunk::WIDTH && (north == nullptr || !north->getBlock(x + 1 - Chunk::WIDTH, y, z).isBlockingFace(Face::SOUTH))))
                     {
                         for(int i = 0; i < 6; i++)
                         {
@@ -165,10 +165,10 @@ void ChunkRenderer::buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east
                         m.addPosition(x + 1.0f, y + 1.0f, z + 0.0f);
                         m.addPosition(x + 1.0f, y + 1.0f, z + 1.0f);
                     }
-
+                     
                     // left
-                    if((x - 1 >= 0 && c.getBlock(x - 1, y, z) != 1) ||
-                        (x - 1 < 0 && (south == nullptr || south->getBlock(x - 1 + Chunk::WIDTH, y, z) != 1)))
+                    if((x - 1 >= 0 && !c.getBlock(x - 1, y, z).isBlockingFace(Face::NORTH)) ||
+                        (x - 1 < 0 && (south == nullptr || !south->getBlock(x - 1 + Chunk::WIDTH, y, z).isBlockingFace(Face::NORTH))))
                     {
                         for(int i = 0; i < 6; i++)
                         {
@@ -196,8 +196,8 @@ void ChunkRenderer::buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east
                     }
 
                     // back
-                    if((z + 1 < Chunk::DEPTH && c.getBlock(x, y, z + 1) != 1) ||
-                        (z + 1 >= Chunk::DEPTH && (east == nullptr || east->getBlock(x, y, z + 1 - Chunk::DEPTH) != 1)))
+                    if((z + 1 < Chunk::DEPTH && !c.getBlock(x, y, z + 1).isBlockingFace(Face::WEST)) ||
+                        (z + 1 >= Chunk::DEPTH && (east == nullptr || !east->getBlock(x, y, z + 1 - Chunk::DEPTH).isBlockingFace(Face::WEST))))
                     {
                         for(int i = 0; i < 6; i++)
                         {
@@ -225,8 +225,8 @@ void ChunkRenderer::buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east
                     }
 
                     // front
-                    if((z - 1 >= 0 && c.getBlock(x, y, z - 1) != 1) ||
-                        (z - 1 < 0 && (west == nullptr || west->getBlock(x, y, z - 1 + Chunk::DEPTH) != 1)))
+                    if((z - 1 >= 0 && !c.getBlock(x, y, z - 1).isBlockingFace(Face::EAST)) ||
+                        (z - 1 < 0 && (west == nullptr || !west->getBlock(x, y, z - 1 + Chunk::DEPTH).isBlockingFace(Face::EAST))))
                     {
                         for(int i = 0; i < 6; i++)
                         {

+ 2 - 2
client/rendering/ChunkRenderer.h

@@ -18,8 +18,8 @@ public:
 private:
     void buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east, Chunk* south, Chunk* west);
     
-    const int chunkX = 16;
-    const int chunkZ = 16;
+    const int chunkX = 2;
+    const int chunkZ = 2;
     ChunkMesh* mesh;
 };
 

+ 2 - 2
client/rendering/ClientChunkProvider.h

@@ -14,8 +14,8 @@ public:
     void forEachLoadedChunk(void* data, void (*fun) (Chunk&, void*)) const override;
     
 private:
-    const int chunkX = 16;
-    const int chunkZ = 16;
+    const int chunkX = 2;
+    const int chunkZ = 2;
     Chunk** chunks;
 };
 

+ 74 - 0
utils/Face.cpp

@@ -0,0 +1,74 @@
+#include "Face.h"
+
+Face Face::FACES[6] =
+{
+    Face(0,  0,  1,  0, "Up"),
+    Face(1,  1,  0,  0, "North"),
+    Face(2,  0,  0,  1, "East"),
+    Face(3,  0, -1,  0, "Down"),
+    Face(4, -1,  0,  0, "South"),
+    Face(5,  0,  0, -1, "West")
+};
+
+Face& Face::UP = FACES[0];
+Face& Face::DOWN = FACES[3];
+
+Face& Face::NORTH = FACES[1];
+Face& Face::SOUTH = FACES[4];
+
+Face& Face::EAST = FACES[2];
+Face& Face::WEST = FACES[5];
+
+Face::Face(int index, int offsetX, int offsetY, int offsetZ, const char* name) : 
+    index(index), offsetX(offsetX), offsetY(offsetY), offsetZ(offsetZ), name(name)
+{
+}
+
+int Face::getX() const
+{
+    return offsetX;
+}
+
+int Face::getY() const
+{
+    return offsetY;
+}
+
+int Face::getZ() const
+{
+    return offsetZ;
+}
+
+Face& Face::getOpposite() const
+{
+    return FACES[(index + 3) % 6];
+}
+
+const char* Face::getName() const
+{
+    return name;
+}
+
+void Face::forEach(void* data, void (*fun) (Face&, void*))
+{
+    for(int i = 0; i < 6; i++)
+    {
+        fun(FACES[i], data);
+    }
+}
+
+bool operator==(const Face& l, const Face& r)
+{
+    return &l == &r;
+}
+
+bool operator!=(const Face& l, const Face& r)
+{
+    return &l != &r;
+}
+
+std::ostream& operator<<(std::ostream& os, const Face& f)
+{
+    os << f.getName();
+    return os;
+}

+ 43 - 0
utils/Face.h

@@ -0,0 +1,43 @@
+#ifndef FACE_H
+#define FACE_H
+
+#include <iostream>
+
+class Face
+{
+public:
+    int getX() const;
+    int getY() const;
+    int getZ() const;
+    Face& getOpposite() const;
+    const char* getName() const;
+    
+    static void forEach(void* data, void (*fun) (Face&, void*));
+    
+    static Face& UP;
+    static Face& DOWN;
+    static Face& NORTH;
+    static Face& SOUTH;
+    static Face& EAST;
+    static Face& WEST;
+
+private:
+    Face(int index, int offsetX, int offsetY, int offsetZ, const char* name);
+    
+    static Face FACES[6];
+    
+    int offsetX;
+    int offsetY;
+    int offsetZ;
+    
+    int index;
+    
+    const char* name;
+};
+
+bool operator==(const Face& l, const Face& r);
+bool operator!=(const Face& l, const Face& r);
+std::ostream& operator<<(std::ostream& os, const Face& f);
+
+#endif
+

+ 11 - 6
world/Chunk.cpp

@@ -1,6 +1,11 @@
 #include "Chunk.h"
 #include <cstdlib>
 #include <cmath>
+#include "../block/Blocks.h"
+
+#include <iostream>
+
+using namespace std;
 
 Chunk::Chunk(int chunkX, int chunkZ) : chunkX(chunkX), chunkZ(chunkZ)
 {
@@ -21,11 +26,11 @@ Chunk::Chunk(int chunkX, int chunkZ) : chunkX(chunkX), chunkZ(chunkZ)
             
             for(int y = 0; y < maxY; y++)
             {
-                blocks[y][x][z] = 1;
+                setBlock(x, y, z, Blocks::GRASS);
             }
             for(int y = maxY; y < HEIGHT; y++)
             {
-                blocks[y][x][z] = 0;
+                setBlock(x, y, z, Blocks::AIR);
             }
         }
     }
@@ -35,14 +40,14 @@ Chunk::~Chunk()
 {
 }
 
-void Chunk::setBlock(int x, int y, int z, unsigned short block)
+void Chunk::setBlock(int x, int y, int z, const Block& block)
 {
-    blocks[y & BITMASK_HEIGHT][x & BITMASK_WIDTH][z & BITMASK_DEPTH] = block;
+    blocks[y & BITMASK_HEIGHT][x & BITMASK_WIDTH][z & BITMASK_DEPTH] = block.getId();
 }
 
-unsigned short Chunk::getBlock(int x, int y, int z)
+const Block& Chunk::getBlock(int x, int y, int z)
 {
-    return blocks[y & BITMASK_HEIGHT][x & BITMASK_WIDTH][z & BITMASK_DEPTH];
+    return BlockRegistry::getBlockFromId(blocks[y & BITMASK_HEIGHT][x & BITMASK_WIDTH][z & BITMASK_DEPTH]);
 }
 
 int Chunk::getChunkX() const

+ 5 - 3
world/Chunk.h

@@ -1,14 +1,16 @@
 #ifndef CHUNK_H
 #define CHUNK_H
 
+#include "../block/Block.h"
+
 class Chunk
 {
 public:
     Chunk(int chunkX, int chunkZ);
     virtual ~Chunk();
     
-    void setBlock(int x, int y, int z, unsigned short block);
-    unsigned short getBlock(int x, int y, int z);
+    void setBlock(int x, int y, int z, const Block& block);
+    const Block& getBlock(int x, int y, int z);
     
     int getChunkX() const;
     int getChunkZ() const;
@@ -32,7 +34,7 @@ private:
     int chunkX;
     int chunkZ;
     
-    unsigned short blocks[HEIGHT][WIDTH][DEPTH];
+    BlockId blocks[HEIGHT][WIDTH][DEPTH];
     bool dirty[HEIGHT_PARTIONS];
 };