mirror of https://github.com/buggins/dlangui.git
optimize dminer example; fix win32 opengl support; enable wireframe mode for drawing of meshes
This commit is contained in:
parent
388bc94cf7
commit
4c1e97c952
|
@ -96,7 +96,7 @@ X<-----x-----
|
|||
|
||||
private immutable float CCC = 0.5; // cell cube coordinates
|
||||
private immutable float TC0 = 0.0;
|
||||
private immutable float TC1 = 1.0;
|
||||
private immutable float TC1 = 0.99;
|
||||
|
||||
__gshared static const float[VERTEX_COMPONENTS * 4] face_vertices_north =
|
||||
[
|
||||
|
@ -184,7 +184,7 @@ __gshared static const float[VERTEX_COMPONENTS * 4] face_vertices_down =
|
|||
|
||||
__gshared static const ushort[6] face_indexes =
|
||||
[
|
||||
2, 1, 0, 0, 3, 2 // CCW
|
||||
2, 1, 0, 0, 3, 2 // CCW
|
||||
];
|
||||
|
||||
__gshared static const ushort[6] face_indexes_back =
|
||||
|
|
|
@ -6,7 +6,7 @@ import dminer.core.world;
|
|||
import dlangui.graphics.scene.mesh;
|
||||
|
||||
|
||||
version = FAST_VISIBILITY_PATH;
|
||||
//version = FAST_VISIBILITY_PATH;
|
||||
|
||||
// Y range: 0..CHUNK_DY-1
|
||||
immutable int CHUNK_DY = 128;
|
||||
|
@ -29,7 +29,7 @@ interface CellVisitor {
|
|||
}
|
||||
|
||||
interface ChunkVisitor {
|
||||
void visit(World world, SmallChunk * chunk);
|
||||
bool visit(World world, SmallChunk * chunk);
|
||||
}
|
||||
|
||||
// vertical stack of chunks with same X, Z, and different Y
|
||||
|
@ -1550,13 +1550,18 @@ struct VisibilityCheckIterator {
|
|||
if (!mask)
|
||||
return;
|
||||
// distance test
|
||||
Vector3d diff = p - camPos;
|
||||
Vector3d diff = (p + Vector3d(4,4,4)) - camPos;
|
||||
if (diff.squaredLength() > maxDistanceSquared)
|
||||
return;
|
||||
// direction test (TODO)
|
||||
int dot = diff.dot(cameraDirection);
|
||||
if (dot < 8000)
|
||||
return;
|
||||
int distance = diff.squaredLength;
|
||||
if (distance > 10*10) {
|
||||
diff = (diff * 256 + cameraDirection * 16) / 256;
|
||||
//diff += cameraDirection;
|
||||
// direction test (TODO)
|
||||
int dot = diff.dot(cameraDirection);
|
||||
if (dot < 12000)
|
||||
return;
|
||||
}
|
||||
//....
|
||||
// plan visiting
|
||||
VisibilityCheckChunk * plan = getOrAddPlannedChunk(p);
|
||||
|
@ -1571,7 +1576,8 @@ struct VisibilityCheckIterator {
|
|||
swap(visitedChunks, plannedChunks);
|
||||
plannedChunks.length = 0;
|
||||
foreach (ref p; visitedChunks) {
|
||||
visitor.visit(world, p.chunk);
|
||||
if (!visitor.visit(world, p.chunk))
|
||||
continue;
|
||||
/// set mask of spread directions
|
||||
p.spreadToDirMask = calcSpreadMask(p.pos, startPos);
|
||||
p.tracePaths();
|
||||
|
|
|
@ -120,6 +120,10 @@ struct Vector3d {
|
|||
Vector3d opBinary(string op : "*")(int n) const {
|
||||
return Vector3d(x * n, y * n, z * n);
|
||||
}
|
||||
/// divide vector elements by constant
|
||||
Vector3d opBinary(string op : "/")(int n) const {
|
||||
return Vector3d(x / n, y / n, z / n);
|
||||
}
|
||||
|
||||
///
|
||||
ref Vector3d opOpAssign(string op : "+")(const Vector3d v) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import dminer.core.chunk;
|
|||
version (Android) {
|
||||
const int MAX_VIEW_DISTANCE = 60;
|
||||
} else {
|
||||
const int MAX_VIEW_DISTANCE = 120;
|
||||
const int MAX_VIEW_DISTANCE = 180;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ import dlangui.graphics.scene.effect;
|
|||
import dlangui.graphics.glsupport;
|
||||
import dlangui.graphics.gldrawbuf;
|
||||
|
||||
//version = TEST_VISITOR_PERFORMANCE;
|
||||
|
||||
/*
|
||||
version (Android) {
|
||||
//enum SUPPORT_LEGACY_OPENGL = false;
|
||||
|
@ -62,8 +64,9 @@ extern (C) int UIAppMain(string[] args) {
|
|||
|
||||
class ChunkVisitCounter : ChunkVisitor {
|
||||
int count;
|
||||
void visit(World world, SmallChunk * chunk) {
|
||||
bool visit(World world, SmallChunk * chunk) {
|
||||
count++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,6 +81,10 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
|
|||
private Camera _cam;
|
||||
private vec3 _camPosition;
|
||||
private vec3 _camForwardVector;
|
||||
private bool _wireframe;
|
||||
|
||||
@property bool wireframe() { return _wireframe; }
|
||||
@property void wireframe(bool flgWireframe) { _wireframe = flgWireframe; }
|
||||
|
||||
this(World world, Material material, Camera cam) {
|
||||
super(material);
|
||||
|
@ -94,7 +101,7 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
|
|||
_pos = _world.camPosition.pos;
|
||||
_camPosition = _cam.translation;
|
||||
_camForwardVector = _cam.forwardVectorWorld;
|
||||
_camPosition -= _camForwardVector * 8;
|
||||
//_camPosition -= _camForwardVector * 8;
|
||||
_skippedCount = _drawnCount = 0;
|
||||
long ts = currentTimeMillis();
|
||||
//_chunkVisitor.visitChunks(_pos);
|
||||
|
@ -102,34 +109,48 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
|
|||
camVector.x = cast(int)(_camForwardVector.x * 256);
|
||||
camVector.y = cast(int)(_camForwardVector.y * 256);
|
||||
camVector.z = cast(int)(_camForwardVector.z * 256);
|
||||
ChunkVisitCounter countVisitor = new ChunkVisitCounter();
|
||||
_chunkIterator.start(_world, _world.camPosition.pos, MAX_VIEW_DISTANCE);
|
||||
_chunkIterator.visitVisibleChunks(countVisitor, camVector);
|
||||
long durationNoDraw = currentTimeMillis() - ts;
|
||||
_chunkIterator.start(_world, _world.camPosition.pos, MAX_VIEW_DISTANCE);
|
||||
_chunkIterator.visitVisibleChunks(this, camVector);
|
||||
long duration = currentTimeMillis() - ts;
|
||||
Log.d("drawing of Miner scene finished in ", duration, " ms skipped:", _skippedCount, " drawn:", _drawnCount, " duration(noDraw)=", durationNoDraw);
|
||||
version (TEST_VISITOR_PERFORMANCE) {
|
||||
ChunkVisitCounter countVisitor = new ChunkVisitCounter();
|
||||
_chunkIterator.start(_world, _world.camPosition.pos, MAX_VIEW_DISTANCE);
|
||||
_chunkIterator.visitVisibleChunks(countVisitor, camVector);
|
||||
long durationNoDraw = currentTimeMillis() - ts;
|
||||
_chunkIterator.start(_world, _world.camPosition.pos, MAX_VIEW_DISTANCE);
|
||||
_chunkIterator.visitVisibleChunks(this, camVector);
|
||||
long duration = currentTimeMillis() - ts;
|
||||
Log.d("drawing of Miner scene finished in ", duration, " ms skipped:", _skippedCount, " drawn:", _drawnCount, " duration(noDraw)=", durationNoDraw);
|
||||
} else {
|
||||
_chunkIterator.start(_world, _world.camPosition.pos, MAX_VIEW_DISTANCE);
|
||||
_chunkIterator.visitVisibleChunks(this, camVector);
|
||||
long duration = currentTimeMillis() - ts;
|
||||
Log.d("drawing of Miner scene finished in ", duration, " ms skipped:", _skippedCount, " drawn:", _drawnCount);
|
||||
}
|
||||
}
|
||||
void visit(World world, SmallChunk * chunk) {
|
||||
bool visit(World world, SmallChunk * chunk) {
|
||||
if (chunk) {
|
||||
Vector3d p = chunk.position;
|
||||
vec3 chunkPos = vec3(p.x + 4, p.y + 4, p.z + 4);
|
||||
vec3 chunkDirection = (chunkPos - _camPosition).normalized;
|
||||
float camDist = (_camPosition - chunkPos).length;
|
||||
vec3 chunkDirection = (chunkPos - (_camPosition - (_camForwardVector * 12))).normalized;
|
||||
float dot = _camForwardVector.dot(chunkDirection);
|
||||
//Log.d("visit() chunkPos ", chunkPos, " chunkDir ", chunkDirection, " camDir ");
|
||||
if (dot < 0.7) { // cos(45)
|
||||
float threshold = 0.87;
|
||||
if (camDist < 12)
|
||||
threshold = 0.5;
|
||||
//Log.d("visit() chunkPos ", chunkPos, " chunkDir ", chunkDirection, " camDir ", " dot ", dot, " threshold ", threshold);
|
||||
|
||||
if (dot < threshold) { // cos(45)
|
||||
_skippedCount++;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
Mesh mesh = chunk.getMesh(world);
|
||||
if (mesh) {
|
||||
_material.bind(_node, mesh, lights(_node));
|
||||
_material.drawMesh(mesh);
|
||||
_material.drawMesh(mesh, _wireframe);
|
||||
_material.unbind();
|
||||
_drawnCount++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,7 +253,8 @@ class UiWidget : VerticalLayout { //, CellVisitor
|
|||
//updateMinerMesh();
|
||||
|
||||
Material minerMaterial = new Material(EffectId("textured.vert", "textured.frag", null), "blocks");
|
||||
minerMaterial.ambientColor = vec3(0.05,0.05,0.05);
|
||||
//Material minerMaterial = new Material(EffectId("colored.vert", "colored.frag", null), "blocks");
|
||||
minerMaterial.ambientColor = vec3(0.25,0.25,0.25);
|
||||
minerMaterial.textureLinear = false;
|
||||
minerMaterial.fogParams = new FogParams(vec4(0.01, 0.01, 0.01, 1), 12, 80);
|
||||
//minerMaterial.specular = 10;
|
||||
|
@ -240,6 +262,7 @@ class UiWidget : VerticalLayout { //, CellVisitor
|
|||
//_minerDrawable.autobindLights = false;
|
||||
//Model minerDrawable = new Model(minerMaterial, _minerMesh);
|
||||
Node3d minerNode = new Node3d("miner", _minerDrawable);
|
||||
//_minerDrawable.wireframe = true;
|
||||
_scene.addChild(minerNode);
|
||||
|
||||
|
||||
|
@ -342,6 +365,9 @@ class UiWidget : VerticalLayout { //, CellVisitor
|
|||
override bool onKeyEvent(KeyEvent event) {
|
||||
if (event.action == KeyAction.KeyDown) {
|
||||
switch(event.keyCode) with(KeyCode) {
|
||||
case F1:
|
||||
_minerDrawable.wireframe = !_minerDrawable.wireframe;
|
||||
return true;
|
||||
case KEY_W:
|
||||
case UP:
|
||||
_world.camPosition.forward(1);
|
||||
|
@ -455,11 +481,13 @@ class UiWidget : VerticalLayout { //, CellVisitor
|
|||
import std.string : format;
|
||||
Widget w = childById("lblPosition");
|
||||
string dir = _world.camPosition.direction.dir.to!string;
|
||||
dstring s = format("pos(%d,%d) h=%d fps:%d %s [F]lying: %s [U]pdateMesh: %s", _world.camPosition.pos.x, _world.camPosition.pos.z, _world.camPosition.pos.y,
|
||||
dstring s = format("pos(%d,%d) h=%d fps:%d %s [F]lying: %s [U]pdateMesh: %s [F1] wireframe: %s", _world.camPosition.pos.x, _world.camPosition.pos.z, _world.camPosition.pos.y,
|
||||
_fps,
|
||||
dir,
|
||||
flying,
|
||||
enableMeshUpdate).toUTF32;
|
||||
enableMeshUpdate,
|
||||
_minerDrawable ? _minerDrawable.wireframe : false
|
||||
).toUTF32;
|
||||
w.text = s;
|
||||
}
|
||||
|
||||
|
|
|
@ -435,13 +435,13 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect {
|
|||
}
|
||||
|
||||
/// draw mesh using this program (program should be bound by this time and all uniforms should be set)
|
||||
override void draw(Mesh mesh) {
|
||||
override void draw(Mesh mesh, bool wireframe) {
|
||||
VertexBuffer vb = mesh.vertexBuffer;
|
||||
if (!vb) {
|
||||
vb = new GLVertexBuffer();
|
||||
mesh.vertexBuffer = vb;
|
||||
}
|
||||
vb.draw(this);
|
||||
vb.draw(this, wireframe);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1310,16 +1310,39 @@ class GLVertexBuffer : VertexBuffer {
|
|||
}
|
||||
|
||||
/// draw mesh using specified effect
|
||||
override void draw(GraphicsEffect effect) {
|
||||
override void draw(GraphicsEffect effect, bool wireframe) {
|
||||
//bind();
|
||||
enableAttributes(effect);
|
||||
foreach (fragment; _indexFragments) {
|
||||
checkgl!glDrawRangeElements(primitiveTypeToGL(fragment.type),
|
||||
0, _vertexCount - 1, // The first to last vertex
|
||||
fragment.end - fragment.start, // count of indexes used to draw elements
|
||||
GL_UNSIGNED_SHORT,
|
||||
cast(char*)(fragment.start * short.sizeof) // offset from index buffer beginning to fragment start
|
||||
);
|
||||
if (wireframe && fragment.type == PrimitiveType.triangles) {
|
||||
// TODO: support wireframe not only for triangles
|
||||
int triangleCount = fragment.end - fragment.start;
|
||||
//triangleCount /= 3;
|
||||
//checkgl!glDisable(GL_CULL_FACE);
|
||||
for (int i = 0; i < triangleCount; i += 3) {
|
||||
// GL line loop works strange; use GL_LINES instead
|
||||
checkgl!glDrawRangeElements(GL_LINE_LOOP, //GL_TRIANGLES,
|
||||
0, _vertexCount - 1, // The first to last vertex start, end
|
||||
3, // count of indexes used to draw elements
|
||||
GL_UNSIGNED_SHORT,
|
||||
cast(char*)((fragment.start + i) * short.sizeof) // offset from index buffer beginning to fragment start
|
||||
);
|
||||
//checkgl!glDrawRangeElements(GL_LINES, //GL_TRIANGLES,
|
||||
// 0, _vertexCount - 1, // The first to last vertex start, end
|
||||
// 2, // count of indexes used to draw elements
|
||||
// GL_UNSIGNED_SHORT,
|
||||
// cast(char*)((fragment.start + i + 1) * short.sizeof) // offset from index buffer beginning to fragment start
|
||||
// );
|
||||
}
|
||||
//checkgl!glEnable(GL_CULL_FACE);
|
||||
} else {
|
||||
checkgl!glDrawRangeElements(primitiveTypeToGL(fragment.type),
|
||||
0, _vertexCount - 1, // The first to last vertex
|
||||
fragment.end - fragment.start, // count of indexes used to draw elements
|
||||
GL_UNSIGNED_SHORT,
|
||||
cast(char*)(fragment.start * short.sizeof) // offset from index buffer beginning to fragment start
|
||||
);
|
||||
}
|
||||
}
|
||||
disableAttributes(effect);
|
||||
//unbind();
|
||||
|
@ -1381,10 +1404,11 @@ class DummyVertexBuffer : VertexBuffer {
|
|||
}
|
||||
|
||||
/// draw mesh using specified effect
|
||||
override void draw(GraphicsEffect effect) {
|
||||
override void draw(GraphicsEffect effect, bool wireframe) {
|
||||
//bind();
|
||||
enableAttributes(effect);
|
||||
foreach (fragment; _indexFragments) {
|
||||
// TODO: support wireframe
|
||||
checkgl!glDrawRangeElements(primitiveTypeToGL(fragment.type),
|
||||
0, _vertexCount,
|
||||
fragment.end - fragment.start,
|
||||
|
|
|
@ -230,8 +230,8 @@ class Material : RefCountedObject {
|
|||
}
|
||||
}
|
||||
|
||||
void drawMesh(Mesh mesh) {
|
||||
effect.draw(mesh);
|
||||
void drawMesh(Mesh mesh, bool wireframe) {
|
||||
effect.draw(mesh, wireframe);
|
||||
}
|
||||
|
||||
void unbind() {
|
||||
|
|
|
@ -63,7 +63,7 @@ abstract class GraphicsEffect : RefCountedObject {
|
|||
/// returns true if effect has uniform
|
||||
bool hasUniform(string uniformName);
|
||||
|
||||
void draw(Mesh mesh);
|
||||
void draw(Mesh mesh, bool wireframe);
|
||||
}
|
||||
|
||||
enum DefaultUniform : int {
|
||||
|
@ -162,7 +162,7 @@ class VertexBuffer {
|
|||
/// set or change data
|
||||
void setData(Mesh mesh) { }
|
||||
/// draw mesh using specified effect
|
||||
void draw(GraphicsEffect effect) { }
|
||||
void draw(GraphicsEffect effect, bool wireframe) { }
|
||||
}
|
||||
|
||||
/// location for element is not found
|
||||
|
|
|
@ -29,7 +29,7 @@ class Model : MaterialDrawableObject {
|
|||
override void draw(Node3d node, bool wireframe) {
|
||||
/// override it
|
||||
_material.bind(node, _mesh, lights(node));
|
||||
_material.drawMesh(_mesh);
|
||||
_material.drawMesh(_mesh, wireframe);
|
||||
_material.unbind();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1574,7 +1574,7 @@ class Platform {
|
|||
}
|
||||
|
||||
static if (ENABLE_OPENGL) {
|
||||
private __gshared bool _OPENGL_ENABLED = false;
|
||||
private __gshared bool _OPENGL_ENABLED = true;
|
||||
/// check if hardware acceleration is enabled
|
||||
@property bool openglEnabled() { return _OPENGL_ENABLED; }
|
||||
/// call on app initialization if OpenGL support is detected
|
||||
|
|
Loading…
Reference in New Issue