d3d example: continue porting dminer - minecraft like engine

This commit is contained in:
Vadim Lopatin 2016-03-21 15:48:01 +03:00
parent a7f485555a
commit 944d5158c5
6 changed files with 188 additions and 0 deletions

View File

@ -411,6 +411,7 @@
<Folder name="d3d">
<Folder name="dminer">
<Folder name="core">
<File path="src\dminer\core\blocks.d" />
<File path="src\dminer\core\minetypes.d" />
<File path="src\dminer\core\world.d" />
</Folder>

View File

@ -116,6 +116,12 @@ class UiWidget : VerticalLayout {
_mesh.addCubeMesh(vec3( i * 2 + 1.0f, -i * 2 + 1.0f, i * 2 + 1.0f), 0.2f, vec4(i / 12, 1 - i / 12, i / 12, 1));
_mesh.addCubeMesh(vec3(-i * 2 - 1.0f, -i * 2 - 1.0f, -i * 2 - 1.0f), 0.2f, vec4(1 - i / 12, i / 12, i / 12, 1));
}
import dminer.core.world;
World w = new World();
for (int x = -100; x < 100; x++)
for (int z = -100; z < 100; z++)
w.setCell(x, 10, z, 1);
}
/// returns true is widget is being animated - need to call animate() and redraw

View File

@ -0,0 +1,109 @@
module dminer.core.blocks;
import dminer.core.minetypes;
/*
#define BLOCK_TEXTURE_FILENAME "res/png/blocks.png"
#define BLOCK_TEXTURE_DX 1024
#define BLOCK_TEXTURE_DY 1024
#define BLOCK_SPRITE_SIZE 16
#define BLOCK_SPRITE_STEP 20
#define BLOCK_SPRITE_OFFSET 21
#define BLOCK_TEXTURE_SPRITES_PER_LINE 50
*/
enum BlockVisibility {
INVISIBLE,
OPAQUE, // completely opaque (cells covered by this block are invisible)
OPAQUE_SEPARATE_TX,
HALF_OPAQUE, // partially paque, cells covered by this block can be visible, render as normal block
HALF_OPAQUE_SEPARATE_TX,
HALF_TRANSPARENT, // should be rendered last (semi transparent texture)
};
class BlockDef {
public:
cell_t id;
string name;
BlockVisibility visibility = BlockVisibility.INVISIBLE;
int txIndex;
this() {
}
this(cell_t blockId, string blockName, BlockVisibility v, int tx) {
id = blockId;
name = blockName;
visibility = v;
txIndex = tx;
}
~this() {
}
// blocks behind this block can be visible
@property bool canPass() {
return visibility == BlockVisibility.INVISIBLE
|| visibility == BlockVisibility.HALF_OPAQUE
|| visibility == BlockVisibility.HALF_OPAQUE_SEPARATE_TX
|| visibility == BlockVisibility.HALF_TRANSPARENT;
}
// block is fully opaque (all blocks behind are invisible)
@property bool isOpaque() {
return visibility == BlockVisibility.OPAQUE
|| visibility == BlockVisibility.OPAQUE_SEPARATE_TX;
}
// block is visible
@property bool isVisible() {
return visibility != BlockVisibility.INVISIBLE;
}
@property bool terrainSmoothing() {
return false;
}
/// create cube face
//void createFace(World * world, Position & camPosition, Vector3d pos, Dir face, FloatArray & vertices, IntArray & indexes) {
//}
/// create faces
//void createFaces(World * world, Position & camPosition, Vector3d pos, int visibleFaces, FloatArray & vertices, IntArray & indexes) {
//}
}
// block type definitions
__gshared BlockDef BLOCK_DEFS[256];
// faster check for block->canPass()
__gshared bool BLOCK_TYPE_CAN_PASS[256];
// faster check for block->isOpaque()
__gshared bool BLOCK_TYPE_OPAQUE[256];
// faster check for block->isVisible()
__gshared bool BLOCK_TYPE_VISIBLE[256];
// faster check for block->isVisible()
__gshared bool BLOCK_TERRAIN_SMOOTHING[256];
/// registers new block type
void registerBlockType(BlockDef def) {
if (BLOCK_DEFS[def.id]) {
if (BLOCK_DEFS[def.id] is def)
return;
destroy(BLOCK_DEFS[def.id]);
}
BLOCK_DEFS[def.id] = def;
// init property shortcuts
BLOCK_TYPE_CAN_PASS[def.id] = def.canPass;
BLOCK_TYPE_OPAQUE[def.id] = def.isOpaque;
BLOCK_TYPE_VISIBLE[def.id] = def.isVisible;
BLOCK_TERRAIN_SMOOTHING[def.id] = def.terrainSmoothing;
}
/// init block types array
__gshared static this() {
import std.string;
for (int i = 0; i < 256; i++) {
if (!BLOCK_DEFS[i]) {
registerBlockType(new BlockDef(cast(cell_t)i, "undef%d".format(i), BlockVisibility.INVISIBLE, 0));
}
}
BLOCK_TYPE_CAN_PASS[BOUND_SKY] = false;
BLOCK_TYPE_VISIBLE[BOUND_SKY] = false;
BLOCK_TYPE_CAN_PASS[BOUND_BOTTOM] = false;
BLOCK_TYPE_VISIBLE[BOUND_BOTTOM] = true;
}

View File

@ -1,6 +1,7 @@
module dminer.core.world;
import dminer.core.minetypes;
import dminer.core.blocks;
const int MAX_VIEW_DISTANCE_BITS = 7;
const int MAX_VIEW_DISTANCE = (1 << MAX_VIEW_DISTANCE_BITS);
@ -104,3 +105,73 @@ public:
maxx = x + 1;
}
}
/// Voxel World
class World {
private:
//Position camPosition;
int maxVisibleRange = MAX_VIEW_DISTANCE;
int lastChunkX = 1000000;
int lastChunkZ = 1000000;
Chunk * lastChunk;
ChunkMatrix chunks;
//DiamondVisitor visitorHelper;
public:
this()
{
}
~this() {
}
//void visitVisibleCellsAllDirectionsFast(Position & position, CellVisitor * visitor);
//Position & getCamPosition() { return camPosition; }
cell_t getCell(Vector3d v) {
return getCell(v.x, v.y, v.z);
}
cell_t getCell(int x, int y, int z) {
if (y < 0)
return 3;
int chunkx = x >> CHUNK_DX_SHIFT;
int chunkz = z >> CHUNK_DX_SHIFT;
Chunk * p;
if (lastChunkX == chunkx && lastChunkZ == chunkz) {
p = lastChunk;
} else {
p = chunks.get(chunkx, chunkz);
lastChunkX = chunkx;
lastChunkZ = chunkz;
lastChunk = p;
}
if (!p)
return NO_CELL;
return p.get(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK);
}
bool isOpaque(Vector3d v) {
cell_t cell = getCell(v);
return BLOCK_TYPE_OPAQUE[cell] && cell != BOUND_SKY;
}
void setCell(int x, int y, int z, cell_t value) {
int chunkx = x >> CHUNK_DX_SHIFT;
int chunkz = z >> CHUNK_DX_SHIFT;
Chunk * p;
if (lastChunkX == chunkx && lastChunkZ == chunkz) {
p = lastChunk;
}
else {
p = chunks.get(chunkx, chunkz);
lastChunkX = chunkx;
lastChunkZ = chunkz;
lastChunk = p;
}
if (!p) {
p = new Chunk();
chunks.set(chunkx, chunkz, p);
lastChunkX = chunkx;
lastChunkZ = chunkz;
lastChunk = p;
}
p.set(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK, value);
}
//bool canPass(Vector3d pos, Vector3d size) {
//}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -16,3 +16,4 @@ res/mdpi/edit-undo.png
res/mdpi/edit-unindent.png
res/mdpi/tx_fabric.jpg
res/theme_custom1.xml
res/blocks.png