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);