diff --git a/dlangui-msvc.sln b/dlangui-msvc.sln
index c5a5adc3..0e98eea9 100644
--- a/dlangui-msvc.sln
+++ b/dlangui-msvc.sln
@@ -170,7 +170,7 @@ Global
{29CF2CAC-2C0C-4F17-9292-E1706AC7EBBF}.Unittest|x64.Build.0 = Release|x64
{20722E6B-CA27-467F-8BB8-07F80106B478}.Debug|Win32.ActiveCfg = Debug|Win32
{20722E6B-CA27-467F-8BB8-07F80106B478}.Debug|Win32.Build.0 = Debug|Win32
- {20722E6B-CA27-467F-8BB8-07F80106B478}.Debug|x64.ActiveCfg = Debug|Win32
+ {20722E6B-CA27-467F-8BB8-07F80106B478}.Debug|x64.ActiveCfg = Debug|x64
{20722E6B-CA27-467F-8BB8-07F80106B478}.Release|Win32.ActiveCfg = Release|Win32
{20722E6B-CA27-467F-8BB8-07F80106B478}.Release|Win32.Build.0 = Release|Win32
{20722E6B-CA27-467F-8BB8-07F80106B478}.Release|x64.ActiveCfg = Release|Win32
@@ -180,7 +180,7 @@ Global
{20722E6B-CA27-467F-8BB8-07F80106B478}.Unittest|x64.Build.0 = Release|Win32
{5F443F6A-6612-4404-B89E-D0D0205DC8E5}.Debug|Win32.ActiveCfg = Debug|Win32
{5F443F6A-6612-4404-B89E-D0D0205DC8E5}.Debug|Win32.Build.0 = Debug|Win32
- {5F443F6A-6612-4404-B89E-D0D0205DC8E5}.Debug|x64.ActiveCfg = Debug|Win32
+ {5F443F6A-6612-4404-B89E-D0D0205DC8E5}.Debug|x64.ActiveCfg = Debug|x64
{5F443F6A-6612-4404-B89E-D0D0205DC8E5}.Release|Win32.ActiveCfg = Release|Win32
{5F443F6A-6612-4404-B89E-D0D0205DC8E5}.Release|Win32.Build.0 = Release|Win32
{5F443F6A-6612-4404-B89E-D0D0205DC8E5}.Release|x64.ActiveCfg = Release|Win32
diff --git a/dlangui-msvc.visualdproj b/dlangui-msvc.visualdproj
index 51c2858b..de7058e1 100644
--- a/dlangui-msvc.visualdproj
+++ b/dlangui-msvc.visualdproj
@@ -337,10 +337,10 @@
0
0
0
- 1
+ 0
0
1
- 1
+ 0
0
0
1
@@ -772,8 +772,8 @@
-
+
diff --git a/examples/dminer/dminer.visualdproj b/examples/dminer/dminer.visualdproj
index 9921eae0..ce139006 100644
--- a/examples/dminer/dminer.visualdproj
+++ b/examples/dminer/dminer.visualdproj
@@ -204,6 +204,210 @@
*.obj;*.cmd;*.build;*.json;*.dep
+
+ 0
+ 0
+ 0
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 3
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 2.043
+ 0
+ 0
+ 0
+ 0
+ 0
+ $(CC) -c
+ 1
+ $(DMDInstallDir)windows\bin\dmd.exe
+ $(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/deps/DerelictGL3/source $(SolutionDir)/deps/DerelictUtil/source $(SolutionDir)/deps/DerelictFT/source $(SolutionDir)/deps/DerelictSDL2/source
+ views views/res views/res/i18n views/res/mdpi views/res/hdpi
+ $(ConfigurationName)
+ $(OutDir)
+
+
+ 0
+
+
+
+
+ 0
+
+
+ 1
+ $(IntDir)\$(TargetName).json
+ 0
+
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+ 0
+
+ 1
+ $(VisualDInstallDir)cv2pdb\cv2pdb.exe
+ 0
+ 0
+ 0
+
+
+
+ ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib
+
+
+
+ $(OutDir)\$(ProjectName).exe
+ 1
+ 2
+ 0
+
+
+
+ *.obj;*.cmd;*.build;*.json;*.dep
+
+
+ 0
+ 0
+ 0
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 2.043
+ 0
+ 0
+ 0
+ 0
+ 0
+ $(CC) -c
+ 1
+ $(DMDInstallDir)windows\bin\dmd.exe
+ $(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/deps/DerelictGL3/source $(SolutionDir)/deps/DerelictUtil/source $(SolutionDir)/deps/DerelictFT/source $(SolutionDir)/deps/DerelictSDL2/source
+ views views/res views/res/i18n views/res/mdpi views/res/hdpi
+ $(ConfigurationName)
+ $(OutDir)
+
+
+ 0
+
+
+
+
+ 0
+
+
+ 1
+ $(IntDir)\$(TargetName).json
+ 0
+
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+ 0
+
+ 0
+ $(VisualDInstallDir)cv2pdb\cv2pdb.exe
+ 0
+ 0
+ 0
+
+
+
+ ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib
+
+
+
+ $(OutDir)\$(ProjectName).exe
+ 1
+ 1
+ 0
+
+
+
+ *.obj;*.cmd;*.build;*.json;*.dep
+
diff --git a/examples/dminer/src/dminer/core/chunk.d b/examples/dminer/src/dminer/core/chunk.d
index 36566d00..2aed7442 100644
--- a/examples/dminer/src/dminer/core/chunk.d
+++ b/examples/dminer/src/dminer/core/chunk.d
@@ -17,6 +17,8 @@ immutable int CHUNKS_Z = (1 << CHUNKS_BITS_Z); // Z range: -CHUNKS_Z*8 .. CHUNKS
immutable int CHUNKS_X_MASK = (CHUNKS_X << 1) - 1;
immutable int CHUNKS_Z_MASK = (CHUNKS_Z << 1) - 1;
+version = SmallChunksGC;
+
interface CellVisitor {
//void newDirection(ref Position camPosition);
//void visitFace(World world, ref Position camPosition, Vector3d pos, cell_t cell, Dir face);
@@ -27,7 +29,11 @@ interface CellVisitor {
struct ChunkStack {
protected int _minChunkY;
protected int _chunkCount;
- protected SmallChunk ** _chunks;
+ version (SmallChunksGC) {
+ protected SmallChunk * [] _chunks;
+ } else {
+ protected SmallChunk ** _chunks;
+ }
/// get chunk from stack by chunk Y index
SmallChunk * get(int chunkY) {
int idx = chunkY - _minChunkY;
@@ -67,7 +73,7 @@ struct ChunkStack {
newMinY = _minChunkY;
newChunkCount = chunkY - _minChunkY + 1;
}
- SmallChunk ** newChunks = allocChunks(newChunkCount);
+ SmallChunk *[] newChunks = allocChunks(newChunkCount);
// copy old data
for(int i = 0; i < _chunkCount; i++)
newChunks[i + _minChunkY - newMinY] = _chunks[i];
@@ -78,20 +84,35 @@ struct ChunkStack {
_chunks = newChunks;
}
}
- private SmallChunk ** allocChunks(int len) {
- if (len <= 0)
- return null;
- import core.stdc.stdlib : malloc;
- SmallChunk ** res = cast(SmallChunk **) malloc(len * (SmallChunk *).sizeof);
- for(int i = 0; i < len; i++)
- res[i] = null;
- return res;
- }
- private void freeChunks(ref SmallChunk ** chunks) {
- if (chunks) {
- import core.stdc.stdlib : free;
- free(chunks);
- chunks = null;
+ version (SmallChunksGC) {
+ private SmallChunk* [] allocChunks(int len) {
+ if (len <= 0)
+ return null;
+ SmallChunk* [] res = new SmallChunk* [len];
+ return res;
+ }
+ private void freeChunks(ref SmallChunk *[] chunks) {
+ if (chunks) {
+ destroy(chunks);
+ chunks = null;
+ }
+ }
+ } else {
+ private SmallChunk ** allocChunks(int len) {
+ if (len <= 0)
+ return null;
+ import core.stdc.stdlib : malloc;
+ SmallChunk ** res = cast(SmallChunk **) malloc(len * (SmallChunk *).sizeof);
+ for(int i = 0; i < len; i++)
+ res[i] = null;
+ return res;
+ }
+ private void freeChunks(ref SmallChunk ** chunks) {
+ if (chunks) {
+ import core.stdc.stdlib : free;
+ free(chunks);
+ chunks = null;
+ }
}
}
void clear() {
@@ -128,21 +149,42 @@ struct SmallChunk {
protected Vector3d _pos;
private Mesh _minerMesh;
protected bool dirty;
- protected bool dirtyMesh;
+ protected bool dirtyMesh = true;
protected bool empty;
protected bool visible;
protected bool dirtyVisible;
+ version (SmallChunksGC) {
+ static SmallChunk * alloc(int x, int y, int z) {
+ SmallChunk * res = new SmallChunk();
+ res._pos.x = x & (~7);
+ res._pos.y = y & (~7);
+ res._pos.z = z & (~7);
+ return res;
+ }
+ void release() {
+ destroy(this);
+ }
+
+ } else {
+ static SmallChunk * alloc(int x, int y, int z) nothrow @nogc {
+ import core.stdc.stdlib : malloc;
+ SmallChunk * res = cast(SmallChunk *)malloc(SmallChunk.sizeof);
+ *res = SmallChunk.init;
+ res._pos.x = x & (~7);
+ res._pos.y = y & (~7);
+ res._pos.z = z & (~7);
+ return res;
+ }
+ void release() {
+ if (!(&this))
+ return;
+ compact();
+ import core.stdc.stdlib : free;
+ free(&this);
+ }
- static SmallChunk * alloc(int x, int y, int z) nothrow @nogc {
- import core.stdc.stdlib : malloc;
- SmallChunk * res = cast(SmallChunk *)malloc(SmallChunk.sizeof);
- *res = SmallChunk.init;
- res._pos.x = x & (~7);
- res._pos.y = y & (~7);
- res._pos.z = z & (~7);
- return res;
}
/// return chunk position in world (aligned to chunk origin)
@@ -156,20 +198,12 @@ struct SmallChunk {
generateMasks();
if (dirtyVisible) {
dirtyVisible = false;
- ubyte[64] visibleFaceFlags;
+ ubyte[64*8] visibleFaceFlags;
visible = findVisibleFaces(visibleFaceFlags) > 0;
}
return visible;
}
- void release() {
- if (!(&this))
- return;
- compact();
- import core.stdc.stdlib : free;
- free(&this);
- }
-
/// destroys mesh
void compact() {
if (_minerMesh) {
@@ -224,7 +258,7 @@ struct SmallChunk {
generateMasks();
if (empty)
return;
- ubyte[64] visibleFaceFlags;
+ ubyte[64*8] visibleFaceFlags;
findVisibleFaces(visibleFaceFlags);
int index = 0;
for (int y = 0; y < 8; y++) {
@@ -246,13 +280,15 @@ struct SmallChunk {
generateMasks();
if (empty)
return null;
- if (!_minerMesh) {
- _minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
- dirtyMesh = true;
- }
+ //if (!_minerMesh) {
+ // _minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
+ // dirtyMesh = true;
+ //}
+ Mesh oldMesh = _minerMesh;
if (dirtyMesh) {
- _minerMesh.reset();
- ubyte[64] visibleFaceFlags;
+ if (_minerMesh)
+ _minerMesh.reset();
+ ubyte[64*8] visibleFaceFlags;
findVisibleFaces(visibleFaceFlags);
int index = 0;
for (int y = 0; y < 8; y++) {
@@ -260,6 +296,13 @@ struct SmallChunk {
for (int x = 0; x < 8; x++) {
int visibleFaces = visibleFaceFlags[index];
if (visibleFaces) {
+
+ if (!_minerMesh) {
+ _minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
+ import dlangui.core.logger;
+ //Log.d("Created mesh: ", cast(void*)_minerMesh);
+ }
+
BlockDef def = BLOCK_DEFS[cells[index]];
def.createFaces(world, world.camPosition, Vector3d(_pos.x + x, _pos.y + y, _pos.z + z), visibleFaces, _minerMesh);
}
@@ -267,13 +310,24 @@ struct SmallChunk {
}
}
}
+ dirtyMesh = false;
+ }
+ if (_minerMesh) {
+ if (_minerMesh.vertexFormat.length > 10) {
+ import dlangui.core.logger;
+ Log.d("Corrupted mesh: ", oldMesh);
+ }
+ if (oldMesh && (oldMesh !is _minerMesh)) {
+ import dlangui.core.logger;
+ Log.d("Corrupted mesh: ", oldMesh);
+ }
+ if (!_minerMesh.vertexCount)
+ return null;
}
- if (!_minerMesh.vertexCount)
- return null;
return _minerMesh;
}
- private int findVisibleFaces(ref ubyte[64] visibleFaceFlags) {
+ private int findVisibleFaces(ref ubyte[64*8] visibleFaceFlags) {
int count = 0;
ulong[8] visibleFacesNorth;
ulong canPass = getSideCanPassFromMask(Dir.NORTH);
diff --git a/examples/dminer/src/minermain.d b/examples/dminer/src/minermain.d
index 2d377a2f..cfbf4332 100644
--- a/examples/dminer/src/minermain.d
+++ b/examples/dminer/src/minermain.d
@@ -61,14 +61,20 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
Vector3d _pos;
private Node3d _node;
- this(World world) {
+ this(World world, Material material) {
+ super(material);
_world = world;
}
override void draw(Node3d node, bool wireframe) {
/// override it
_node = node;
+ //Log.d("drawing Miner scene");
_chunkVisitor.init(_world, 128, this);
+ _pos = _world.camPosition.pos;
+ long ts = currentTimeMillis();
_chunkVisitor.visitChunks(_pos);
+ long duration = currentTimeMillis() - ts;
+ Log.d("drawing of Miner scene finished in ", duration, " ms");
}
void visit(World world, SmallChunk * chunk) {
if (chunk) {
@@ -82,7 +88,7 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
}
}
-class UiWidget : VerticalLayout, CellVisitor {
+class UiWidget : VerticalLayout { //, CellVisitor
this() {
super("OpenGLView");
layoutWidth = FILL_PARENT;
@@ -178,20 +184,23 @@ class UiWidget : VerticalLayout, CellVisitor {
//_world.setCellRange(Vector3d(-7, 11, 3), Vector3d(1, 100, 1), 8);
updateCamPosition(false);
- updateMinerMesh();
+ //updateMinerMesh();
Material minerMaterial = new Material(EffectId("textured.vert", "textured.frag", null), "blocks");
minerMaterial.ambientColor = vec3(0.1,0.1,0.1);
minerMaterial.textureLinear = false;
//minerMaterial.specular = 10;
- Model minerDrawable = new Model(minerMaterial, _minerMesh);
- Node3d minerNode = new Node3d("miner", minerDrawable);
+ _minerDrawable = new MinerDrawable(_world, minerMaterial);
+ //Model minerDrawable = new Model(minerMaterial, _minerMesh);
+ Node3d minerNode = new Node3d("miner", _minerDrawable);
_scene.addChild(minerNode);
focusable = true;
}
+ MinerDrawable _minerDrawable;
+
/// process key event, return true if event is processed.
override bool onMouseEvent(MouseEvent event) {
if (event.action == MouseAction.ButtonDown) {
@@ -317,10 +326,10 @@ class UiWidget : VerticalLayout, CellVisitor {
Node3d dirLightNode;
- 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 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);
+ //}
bool flying = false;
bool enableMeshUpdate = true;
@@ -371,8 +380,8 @@ class UiWidget : VerticalLayout, CellVisitor {
dstring s = format("pos(%d,%d) h=%d %s [F]lying: %s [U]pdateMesh: %s", _world.camPosition.pos.x, _world.camPosition.pos.z, _world.camPosition.pos.y, dir,
flying, enableMeshUpdate).toUTF32;
w.text = s;
- if (enableMeshUpdate)
- updateMinerMesh();
+ //if (enableMeshUpdate)
+ // updateMinerMesh();
}
void startMoveAnimation(Vector3d direction) {
@@ -385,17 +394,17 @@ class UiWidget : VerticalLayout, CellVisitor {
updateCamPosition();
}
- void updateMinerMesh() {
- _minerMesh.reset();
- long ts = currentTimeMillis;
- _world.visitVisibleCells(_world.camPosition, this);
- long duration = currentTimeMillis - ts;
- Log.d("DiamondVisitor finished in ", duration, " ms ", "Vertex count: ", _minerMesh.vertexCount);
-
- invalidate();
- //for (int i = 0; i < 20; i++)
- // Log.d("vertex: ", _minerMesh.vertex(i));
- }
+ //void updateMinerMesh() {
+ // _minerMesh.reset();
+ // long ts = currentTimeMillis;
+ // _world.visitVisibleCells(_world.camPosition, this);
+ // long duration = currentTimeMillis - ts;
+ // Log.d("DiamondVisitor finished in ", duration, " ms ", "Vertex count: ", _minerMesh.vertexCount);
+ //
+ // invalidate();
+ // //for (int i = 0; i < 20; i++)
+ // // Log.d("vertex: ", _minerMesh.vertex(i));
+ //}
World _world;
vec3 _position;
@@ -488,6 +497,8 @@ class UiWidget : VerticalLayout, CellVisitor {
//checkgl!glDisable(GL_CULL_FACE);
checkgl!glEnable(GL_DEPTH_TEST);
checkgl!glCullFace(GL_BACK);
+
+ Log.d("Drawing position ", _animatingPosition, " angle ", _animatingAngle);
_scene.drawScene(false);
diff --git a/examples/ircclient/ircclient.visualdproj b/examples/ircclient/ircclient.visualdproj
index 734b14a9..e19ceca6 100644
--- a/examples/ircclient/ircclient.visualdproj
+++ b/examples/ircclient/ircclient.visualdproj
@@ -204,6 +204,210 @@
*.obj;*.cmd;*.build;*.json;*.dep
+
+ 0
+ 0
+ 0
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 3
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ $(CC) -c
+ 1
+ $(DMDInstallDir)windows\bin\dmd.exe
+ $(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/deps/DerelictGL3/source $(SolutionDir)/deps/DerelictUtil/source $(SolutionDir)/deps/DerelictFT/source $(SolutionDir)/deps/DerelictSDL2/source
+ views views/res views/res/i18n views/res/mdpi views/res/hdpi
+ $(ConfigurationName)
+ $(OutDir)
+
+
+ 0
+
+
+
+
+ 0
+
+
+ 1
+ $(IntDir)\$(TargetName).json
+ 0
+
+ 0
+ USE_OPENGL EmbedStandardResources ForceLogs
+ 0
+ 0
+ 0
+
+
+
+ 0
+
+ 1
+ $(VisualDInstallDir)cv2pdb\cv2pdb.exe
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ $(OutDir)\$(ProjectName).exe
+ 1
+ 2
+ 0
+
+
+
+ *.obj;*.cmd;*.build;*.json;*.dep
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 2.043
+ 0
+ 0
+ 0
+ 0
+ 0
+ $(CC) -c
+ 1
+ $(DMDInstallDir)windows\bin\dmd.exe
+
+
+ $(ConfigurationName)
+ $(OutDir)
+
+
+ 0
+
+
+
+
+ 0
+
+
+ 1
+ $(IntDir)\$(TargetName).json
+ 0
+
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+ 0
+
+ 0
+ $(VisualDInstallDir)cv2pdb\cv2pdb.exe
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ $(OutDir)\$(ProjectName).exe
+ 1
+ 1
+ 0
+
+
+
+ *.obj;*.cmd;*.build;*.json;*.dep
+
diff --git a/src/dlangui/graphics/scene/mesh.d b/src/dlangui/graphics/scene/mesh.d
index b3046882..c848a45e 100644
--- a/src/dlangui/graphics/scene/mesh.d
+++ b/src/dlangui/graphics/scene/mesh.d
@@ -348,6 +348,10 @@ class Mesh : RefCountedObject {
_vertexCount = 0;
_vertexData.length = 0;
_dirtyVertexBuffer = true;
+ if (_vertexBuffer) {
+ destroy(_vertexBuffer);
+ _vertexBuffer = null;
+ }
if (_parts.length) {
foreach(p; _parts)
destroy(p);