diff --git a/examples/d3d/d3d-msvc.visualdproj b/examples/d3d/d3d-msvc.visualdproj
index 7a816e91..72b19e55 100644
--- a/examples/d3d/d3d-msvc.visualdproj
+++ b/examples/d3d/d3d-msvc.visualdproj
@@ -337,7 +337,7 @@
0
0
0
- 0
+ 1
0
0
1
diff --git a/examples/d3d/src/d3d.d b/examples/d3d/src/d3d.d
index f4e8f429..51e51c14 100644
--- a/examples/d3d/src/d3d.d
+++ b/examples/d3d/src/d3d.d
@@ -34,7 +34,7 @@ extern (C) int UIAppMain(string[] args) {
return Platform.instance.enterMessageLoop();
}
-class UiWidget : VerticalLayout {
+class UiWidget : VerticalLayout, CellVisitor {
this() {
super("OpenGLView");
layoutWidth = FILL_PARENT;
@@ -121,22 +121,38 @@ class UiWidget : VerticalLayout {
_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));
}
- World w = new World();
+ _minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
+ World _world = new World();
for (int x = -1000; x < 1000; x++)
for (int z = -1000; z < 1000; z++)
- w.setCell(x, 10, z, 1);
- w.setCell(0, 11, 10, 2);
- w.setCell(5, 11, 15, 2);
- Position position = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
+ _world.setCell(x, 10, z, 1);
+ _world.setCell(0, 11, 10, 2);
+ _world.setCell(5, 11, 15, 2);
+ _world.camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
CellVisitor visitor = new TestVisitor();
Log.d("Testing cell visitor");
long ts = currentTimeMillis;
- w.visitVisibleCells(position, visitor);
+ _world.visitVisibleCells(_world.camPosition, visitor);
long duration = currentTimeMillis - ts;
Log.d("DiamondVisitor finished in ", duration, " ms");
- destroy(w);
+ //destroy(w);
}
+ void visit(World world, ref Position camPosition, Vector3d pos, cell_t cell, int visibleFaces) {
+ BlockDef def = BLOCK_DEFS[cell];
+ def.createFaces(world, world.camPosition, pos, visibleFaces, _minerMesh);
+ }
+
+ void updateMinerMesh() {
+ _minerMesh.reset();
+ long ts = currentTimeMillis;
+ _world.visitVisibleCells(_world.camPosition, this);
+ long duration = currentTimeMillis - ts;
+ Log.d("DiamondVisitor finished in ", duration, " ms");
+ }
+
+ World _world;
+
/// returns true is widget is being animated - need to call animate() and redraw
@property override bool animating() { return true; }
/// animates window; interval is time left from previous draw, in hnsecs (1/10000000 of second)
@@ -153,6 +169,7 @@ class UiWidget : VerticalLayout {
Scene3d _scene;
Camera _cam;
Mesh _mesh;
+ Mesh _minerMesh;
GLTexture _tx;
@@ -212,6 +229,7 @@ class UiWidget : VerticalLayout {
destroy(_program);
if (_tx)
destroy(_tx);
+ destroy(_world);
}
}
diff --git a/examples/d3d/src/dminer/core/blocks.d b/examples/d3d/src/dminer/core/blocks.d
index 4e51add2..052ef691 100644
--- a/examples/d3d/src/dminer/core/blocks.d
+++ b/examples/d3d/src/dminer/core/blocks.d
@@ -1,6 +1,8 @@
module dminer.core.blocks;
import dminer.core.minetypes;
+import dminer.core.world;
+import dlangui.graphics.scene.mesh;
immutable string BLOCK_TEXTURE_FILENAME = "blocks";
immutable int BLOCK_TEXTURE_DX = 1024;
@@ -9,6 +11,7 @@ immutable int BLOCK_SPRITE_SIZE = 16;
immutable int BLOCK_SPRITE_STEP = 20;
immutable int BLOCK_SPRITE_OFFSET = 21;
immutable int BLOCK_TEXTURE_SPRITES_PER_LINE = 50;
+immutable int VERTEX_COMPONENTS = 12;
enum BlockVisibility {
INVISIBLE,
@@ -57,13 +60,149 @@ public:
}
/// create cube face
- //void createFace(World * world, Position & camPosition, Vector3d pos, Dir face, FloatArray & vertices, IntArray & indexes) {
- //}
+ void createFace(World world, ref Position camPosition, Vector3d pos, Dir face, Mesh mesh) {
+ // default implementation
+ ushort startVertexIndex = cast(ushort)mesh.vertexCount;
+ float[VERTEX_COMPONENTS * 4] vptr;
+ ushort[6] iptr;
+ createFaceMesh(vptr.ptr, face, pos.x + 0.5f, pos.y + 0.5f, pos.z + 0.5f, txIndex);
+ for (int i = 0; i < 6; i++)
+ iptr[i] = cast(ushort)(startVertexIndex + face_indexes[i]);
+ //if (HIGHLIGHT_GRID && ((pos.x & 7) == 0 || (pos.z & 7) == 0)) {
+ // for (int i = 0; i < 4; i++) {
+ // vptr[11 * i + 6 + 0] = 1.4f;
+ // vptr[11 * i + 6 + 1] = 1.4f;
+ // vptr[11 * i + 6 + 2] = 1.4f;
+ // }
+ //}
+ mesh.addVertexes(vptr);
+ mesh.addPart(PrimitiveType.triangles, iptr);
+ }
/// create faces
- //void createFaces(World * world, Position & camPosition, Vector3d pos, int visibleFaces, FloatArray & vertices, IntArray & indexes) {
- //}
+ void createFaces(World world, ref Position camPosition, Vector3d pos, int visibleFaces, Mesh mesh) {
+ for (int i = 0; i < 6; i++)
+ if (visibleFaces & (1 << i))
+ createFace(world, camPosition, pos, cast(Dir)i, mesh);
+ }
}
+// pos, normal, color, tx
+static const float[VERTEX_COMPONENTS * 4] face_vertices_north =
+[
+ -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+ 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+ -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
+ 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+];
+
+static const float[VERTEX_COMPONENTS * 4] face_vertices_south =
+[
+ -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+ 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+ -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
+ 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+];
+
+static const float[VERTEX_COMPONENTS * 4] face_vertices_west =
+[
+ -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+ -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+ -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
+ -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
+];
+
+static const float[VERTEX_COMPONENTS * 4] face_vertices_east =
+[
+ 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+ 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+ 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
+ 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+];
+
+static const float[VERTEX_COMPONENTS * 4] face_vertices_up =
+[
+ -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+ 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+ -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
+ 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+];
+
+static const float[VERTEX_COMPONENTS * 4] face_vertices_down =
+[
+ -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+ 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+ -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
+ 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+];
+
+static const ushort[6] face_indexes =
+[
+ 0, 1, 2, 2, 1, 3
+];
+
+static const ushort[6] face_indexes_back =
+[
+ 0, 2, 1, 2, 3, 1
+];
+
+static void fillFaceMesh(float * data, const float * src, float x0, float y0, float z0, int tileX, int tileY) {
+ for (int i = 0; i < 4; i++) {
+ const float * srcvertex = src + i * VERTEX_COMPONENTS;
+ float * dstvertex = data + i * VERTEX_COMPONENTS;
+ for (int j = 0; j < 11; j++) {
+ float v = srcvertex[j];
+ switch (j) {
+ default:
+ case 0: // x
+ v += x0;
+ break;
+ case 1: // y
+ v += y0;
+ break;
+ case 2: // z
+ v += z0;
+ break;
+ case 9: // tx.u
+ v = ((tileX + v * BLOCK_SPRITE_SIZE)) / cast(float)BLOCK_TEXTURE_DX;
+ break;
+ case 10: // tx.v
+ v = (BLOCK_TEXTURE_DY - (tileY + v * BLOCK_SPRITE_SIZE)) / cast(float)BLOCK_TEXTURE_DY;
+ break;
+ }
+ dstvertex[j] = v;
+ }
+ }
+}
+
+static void createFaceMesh(float * data, Dir face, float x0, float y0, float z0, int tileIndex) {
+
+ int tileX = (tileIndex % BLOCK_TEXTURE_SPRITES_PER_LINE) * BLOCK_SPRITE_STEP + BLOCK_SPRITE_OFFSET;
+ int tileY = (tileIndex / BLOCK_TEXTURE_SPRITES_PER_LINE) * BLOCK_SPRITE_STEP + BLOCK_SPRITE_OFFSET;
+ // data is 11 comp * 4 vert floats
+ switch (face) {
+ default:
+ case NORTH:
+ fillFaceMesh(data, face_vertices_north.ptr, x0, y0, z0, tileX, tileY);
+ break;
+ case SOUTH:
+ fillFaceMesh(data, face_vertices_south.ptr, x0, y0, z0, tileX, tileY);
+ break;
+ case WEST:
+ fillFaceMesh(data, face_vertices_west.ptr, x0, y0, z0, tileX, tileY);
+ break;
+ case EAST:
+ fillFaceMesh(data, face_vertices_east.ptr, x0, y0, z0, tileX, tileY);
+ break;
+ case UP:
+ fillFaceMesh(data, face_vertices_up.ptr, x0, y0, z0, tileX, tileY);
+ break;
+ case DOWN:
+ fillFaceMesh(data, face_vertices_down.ptr, x0, y0, z0, tileX, tileY);
+ break;
+ }
+}
+
+
// block type definitions
__gshared BlockDef[256] BLOCK_DEFS;
diff --git a/examples/d3d/src/dminer/core/world.d b/examples/d3d/src/dminer/core/world.d
index fcb94c1d..41d7e6f2 100644
--- a/examples/d3d/src/dminer/core/world.d
+++ b/examples/d3d/src/dminer/core/world.d
@@ -11,7 +11,8 @@ immutable int CHUNK_DX_SHIFT = 4;
immutable int CHUNK_DX = (1<= CHUNK_DY)
+ return BOUND_SKY;
int chunkx = x >> CHUNK_DX_SHIFT;
int chunkz = z >> CHUNK_DX_SHIFT;
Chunk * p;
@@ -145,11 +148,11 @@ public:
return NO_CELL;
return p.get(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK);
}
- bool isOpaque(Vector3d v) {
+ final bool isOpaque(Vector3d v) {
cell_t cell = getCell(v);
- return BLOCK_TYPE_OPAQUE[cell] && cell != BOUND_SKY;
+ return BLOCK_TYPE_OPAQUE.ptr[cell] && cell != BOUND_SKY;
}
- void setCell(int x, int y, int z, cell_t value) {
+ final 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;
@@ -172,7 +175,7 @@ public:
}
//bool canPass(Vector3d pos, Vector3d size) {
//}
- void visitVisibleCells(ref Position position, CellVisitor visitor) {
+ final void visitVisibleCells(ref Position position, CellVisitor visitor) {
visitorHelper.init(this, &position,
visitor);
visitorHelper.visitAll(MAX_VIEW_DISTANCE);
@@ -228,24 +231,24 @@ struct DiamondVisitor {
cell_t cell = world.getCell(pos);
// read cell from world
- if (BLOCK_TYPE_VISIBLE[cell]) {
+ if (BLOCK_TYPE_VISIBLE.ptr[cell]) {
int visibleFaces = 0;
- if (v.y <= 0 && v * DIRECTION_VECTORS[DIR_UP] <= 0 &&
+ if (v.y <= 0 && v * DIRECTION_VECTORS.ptr[DIR_UP] <= 0 &&
!world.isOpaque(pos.move(DIR_UP)))
visibleFaces |= MASK_UP;
- if (v.y >= 0 && v * DIRECTION_VECTORS[DIR_DOWN] <= 0 &&
+ if (v.y >= 0 && v * DIRECTION_VECTORS.ptr[DIR_DOWN] <= 0 &&
!world.isOpaque(pos.move(DIR_DOWN)))
visibleFaces |= MASK_DOWN;
- if (v.x <= 0 && v * DIRECTION_VECTORS[DIR_EAST] <= 0 &&
+ if (v.x <= 0 && v * DIRECTION_VECTORS.ptr[DIR_EAST] <= 0 &&
!world.isOpaque(pos.move(DIR_EAST)))
visibleFaces |= MASK_EAST;
- if (v.x >= 0 && v * DIRECTION_VECTORS[DIR_WEST] <= 0 &&
+ if (v.x >= 0 && v * DIRECTION_VECTORS.ptr[DIR_WEST] <= 0 &&
!world.isOpaque(pos.move(DIR_WEST)))
visibleFaces |= MASK_WEST;
- if (v.z <= 0 && v * DIRECTION_VECTORS[DIR_SOUTH] <= 0 &&
+ if (v.z <= 0 && v * DIRECTION_VECTORS.ptr[DIR_SOUTH] <= 0 &&
!world.isOpaque(pos.move(DIR_SOUTH)))
visibleFaces |= MASK_SOUTH;
- if (v.z >= 0 && v * DIRECTION_VECTORS[DIR_NORTH] <= 0 &&
+ if (v.z >= 0 && v * DIRECTION_VECTORS.ptr[DIR_NORTH] <= 0 &&
!world.isOpaque(pos.move(DIR_NORTH)))
visibleFaces |= MASK_NORTH;
visitor.visit(world, *position, pos, cell, visibleFaces);
diff --git a/src/dlangui/graphics/scene/mesh.d b/src/dlangui/graphics/scene/mesh.d
index 952fc072..a4a56bd3 100644
--- a/src/dlangui/graphics/scene/mesh.d
+++ b/src/dlangui/graphics/scene/mesh.d
@@ -174,6 +174,17 @@ class Mesh {
_dirtyVertexBuffer = true;
}
+ void reset() {
+ _vertexCount = 0;
+ _vertexData.length = 0;
+ _dirtyVertexBuffer = true;
+ if (_parts.length) {
+ foreach(p; _parts)
+ destroy(p);
+ _parts.length = 0;
+ }
+ }
+
/// returns vertex count
@property int vertexCount() const { return _vertexCount; }