mirror of https://github.com/buggins/dlangui.git
Implement simple Scene3d drawing: #183
This commit is contained in:
parent
d882a203c0
commit
92a348974f
dlangui-monod-linux.dprojdlangui-monod-osx.dprojdlangui-msvc.visualdproj
examples/d3d/src
src/dlangui/graphics/scene
|
@ -280,9 +280,11 @@
|
||||||
<Compile Include="src\dlangui\graphics\images.d" />
|
<Compile Include="src\dlangui\graphics\images.d" />
|
||||||
<Compile Include="src\dlangui\graphics\resources.d" />
|
<Compile Include="src\dlangui\graphics\resources.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\camera.d" />
|
<Compile Include="src\dlangui\graphics\scene\camera.d" />
|
||||||
|
<Compile Include="src\dlangui\graphics\scene\drawableobject.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\effect.d" />
|
<Compile Include="src\dlangui\graphics\scene\effect.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\material.d" />
|
<Compile Include="src\dlangui\graphics\scene\material.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\mesh.d" />
|
<Compile Include="src\dlangui\graphics\scene\mesh.d" />
|
||||||
|
<Compile Include="src\dlangui\graphics\scene\model.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\node.d" />
|
<Compile Include="src\dlangui\graphics\scene\node.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\scene3d.d" />
|
<Compile Include="src\dlangui\graphics\scene\scene3d.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\transform.d" />
|
<Compile Include="src\dlangui\graphics\scene\transform.d" />
|
||||||
|
|
|
@ -139,9 +139,11 @@
|
||||||
<Compile Include="src\dlangui\graphics\images.d" />
|
<Compile Include="src\dlangui\graphics\images.d" />
|
||||||
<Compile Include="src\dlangui\graphics\resources.d" />
|
<Compile Include="src\dlangui\graphics\resources.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\camera.d" />
|
<Compile Include="src\dlangui\graphics\scene\camera.d" />
|
||||||
|
<Compile Include="src\dlangui\graphics\scene\drawableobject.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\effect.d" />
|
<Compile Include="src\dlangui\graphics\scene\effect.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\material.d" />
|
<Compile Include="src\dlangui\graphics\scene\material.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\mesh.d" />
|
<Compile Include="src\dlangui\graphics\scene\mesh.d" />
|
||||||
|
<Compile Include="src\dlangui\graphics\scene\model.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\node.d" />
|
<Compile Include="src\dlangui\graphics\scene\node.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\scene3d.d" />
|
<Compile Include="src\dlangui\graphics\scene\scene3d.d" />
|
||||||
<Compile Include="src\dlangui\graphics\scene\transform.d" />
|
<Compile Include="src\dlangui\graphics\scene\transform.d" />
|
||||||
|
|
|
@ -771,9 +771,11 @@
|
||||||
<Folder name="graphics">
|
<Folder name="graphics">
|
||||||
<Folder name="scene">
|
<Folder name="scene">
|
||||||
<File path="src\dlangui\graphics\scene\camera.d" />
|
<File path="src\dlangui\graphics\scene\camera.d" />
|
||||||
|
<File path="src\dlangui\graphics\scene\drawableobject.d" />
|
||||||
<File path="src\dlangui\graphics\scene\effect.d" />
|
<File path="src\dlangui\graphics\scene\effect.d" />
|
||||||
<File path="src\dlangui\graphics\scene\material.d" />
|
<File path="src\dlangui\graphics\scene\material.d" />
|
||||||
<File path="src\dlangui\graphics\scene\mesh.d" />
|
<File path="src\dlangui\graphics\scene\mesh.d" />
|
||||||
|
<File path="src\dlangui\graphics\scene\model.d" />
|
||||||
<File path="src\dlangui\graphics\scene\node.d" />
|
<File path="src\dlangui\graphics\scene\node.d" />
|
||||||
<File path="src\dlangui\graphics\scene\scene3d.d" />
|
<File path="src\dlangui\graphics\scene\scene3d.d" />
|
||||||
<File path="src\dlangui\graphics\scene\transform.d" />
|
<File path="src\dlangui\graphics\scene\transform.d" />
|
||||||
|
|
|
@ -6,6 +6,8 @@ import dlangui.graphics.scene.camera;
|
||||||
import dlangui.graphics.scene.mesh;
|
import dlangui.graphics.scene.mesh;
|
||||||
import dlangui.graphics.scene.material;
|
import dlangui.graphics.scene.material;
|
||||||
import dlangui.graphics.scene.effect;
|
import dlangui.graphics.scene.effect;
|
||||||
|
import dlangui.graphics.scene.model;
|
||||||
|
import dlangui.graphics.scene.node;
|
||||||
import dlangui.graphics.glsupport;
|
import dlangui.graphics.glsupport;
|
||||||
import dlangui.graphics.gldrawbuf;
|
import dlangui.graphics.gldrawbuf;
|
||||||
import derelict.opengl3.gl3;
|
import derelict.opengl3.gl3;
|
||||||
|
@ -114,7 +116,7 @@ class UiWidget : VerticalLayout, CellVisitor {
|
||||||
int y0 = 0;
|
int y0 = 0;
|
||||||
int z0 = 0;
|
int z0 = 0;
|
||||||
|
|
||||||
_mesh = Mesh.createCubeMesh(vec3(x0+ 0, y0 + 0, z0 + 0), 0.3f);
|
Mesh _mesh = Mesh.createCubeMesh(vec3(x0+ 0, y0 + 0, z0 + 0), 0.3f);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
_mesh.addCubeMesh(vec3(x0+ 0, y0+0, z0+ i * 2 + 1.0f), 0.2f, vec4(i / 12, 1, 1, 1));
|
_mesh.addCubeMesh(vec3(x0+ 0, y0+0, z0+ i * 2 + 1.0f), 0.2f, vec4(i / 12, 1, 1, 1));
|
||||||
_mesh.addCubeMesh(vec3(x0+ i * 2 + 1.0f, y0+0, z0+ 0), 0.2f, vec4(1, i / 12, 1, 1));
|
_mesh.addCubeMesh(vec3(x0+ i * 2 + 1.0f, y0+0, z0+ 0), 0.2f, vec4(1, i / 12, 1, 1));
|
||||||
|
@ -126,6 +128,11 @@ class UiWidget : VerticalLayout, CellVisitor {
|
||||||
_mesh.addCubeMesh(vec3(x0+ i * 2 + 1.0f, y0+-i * 2 + 1.0f, z0+ i * 2 + 1.0f), 0.2f, vec4(i / 12, 1 - i / 12, i / 12, 1));
|
_mesh.addCubeMesh(vec3(x0+ i * 2 + 1.0f, y0+-i * 2 + 1.0f, z0+ i * 2 + 1.0f), 0.2f, vec4(i / 12, 1 - i / 12, i / 12, 1));
|
||||||
_mesh.addCubeMesh(vec3(x0+ -i * 2 - 1.0f, y0+-i * 2 - 1.0f, z0+ -i * 2 - 1.0f), 0.2f, vec4(1 - i / 12, i / 12, i / 12, 1));
|
_mesh.addCubeMesh(vec3(x0+ -i * 2 - 1.0f, y0+-i * 2 - 1.0f, z0+ -i * 2 - 1.0f), 0.2f, vec4(1 - i / 12, i / 12, i / 12, 1));
|
||||||
}
|
}
|
||||||
|
Material cubeMaterial = new Material(EffectId("textured.vert", "textured.frag", null), "crate");
|
||||||
|
Model cubeDrawable = new Model(cubeMaterial, _mesh);
|
||||||
|
Node3d cubeNode = new Node3d("cubes", cubeDrawable);
|
||||||
|
_scene.addChild(cubeNode);
|
||||||
|
|
||||||
|
|
||||||
_minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
|
_minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
|
||||||
_world = new World();
|
_world = new World();
|
||||||
|
@ -146,6 +153,12 @@ class UiWidget : VerticalLayout, CellVisitor {
|
||||||
|
|
||||||
_world.camPosition = Position(Vector3d(0, 3, 0), Vector3d(0, 0, 1));
|
_world.camPosition = Position(Vector3d(0, 3, 0), Vector3d(0, 0, 1));
|
||||||
updateMinerMesh();
|
updateMinerMesh();
|
||||||
|
|
||||||
|
Material minerMaterial = new Material(EffectId("textured.vert", "textured.frag", null), "blocks");
|
||||||
|
Model minerDrawable = new Model(minerMaterial, _minerMesh);
|
||||||
|
Node3d minerNode = new Node3d("miner", minerDrawable);
|
||||||
|
_scene.addChild(minerNode);
|
||||||
|
|
||||||
//CellVisitor visitor = new TestVisitor();
|
//CellVisitor visitor = new TestVisitor();
|
||||||
//Log.d("Testing cell visitor");
|
//Log.d("Testing cell visitor");
|
||||||
//long ts = currentTimeMillis;
|
//long ts = currentTimeMillis;
|
||||||
|
@ -229,28 +242,13 @@ class UiWidget : VerticalLayout, CellVisitor {
|
||||||
}
|
}
|
||||||
float angle = 0;
|
float angle = 0;
|
||||||
|
|
||||||
EffectRef _program;
|
Scene3dRef _scene;
|
||||||
Scene3d _scene;
|
|
||||||
Camera _cam;
|
Camera _cam;
|
||||||
Mesh _mesh;
|
|
||||||
Mesh _minerMesh;
|
Mesh _minerMesh;
|
||||||
GLTexture _tx;
|
|
||||||
GLTexture _blockstx;
|
|
||||||
|
|
||||||
|
|
||||||
/// this is OpenGLDrawableDelegate implementation
|
/// this is OpenGLDrawableDelegate implementation
|
||||||
private void doDraw(Rect windowRect, Rect rc) {
|
private void doDraw(Rect windowRect, Rect rc) {
|
||||||
if (_program.isNull) {
|
|
||||||
_program = EffectCache.instance.get("textured.vert", "textured.frag");
|
|
||||||
}
|
|
||||||
if (!_tx)
|
|
||||||
_tx = new GLTexture("crate");
|
|
||||||
if (!_blockstx)
|
|
||||||
_blockstx = new GLTexture("blocks");
|
|
||||||
if (!_tx.isValid || !_blockstx.isValid) {
|
|
||||||
Log.e("Invalid texture");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cam.setPerspective(rc.width, rc.height, 45.0f, near, far);
|
_cam.setPerspective(rc.width, rc.height, 45.0f, near, far);
|
||||||
_cam.setIdentity();
|
_cam.setIdentity();
|
||||||
//_cam.translate(vec3(
|
//_cam.translate(vec3(
|
||||||
|
@ -329,33 +327,13 @@ class UiWidget : VerticalLayout, CellVisitor {
|
||||||
checkgl!glEnable(GL_DEPTH_TEST);
|
checkgl!glEnable(GL_DEPTH_TEST);
|
||||||
checkgl!glCullFace(GL_BACK);
|
checkgl!glCullFace(GL_BACK);
|
||||||
|
|
||||||
_program.bind();
|
_scene.drawScene(false);
|
||||||
_program.setUniform("matrix", projectionViewModelMatrix);
|
|
||||||
_tx.texture.setup();
|
|
||||||
_tx.texture.setSamplerParams(true);
|
|
||||||
|
|
||||||
_program.draw(_mesh);
|
|
||||||
|
|
||||||
_tx.texture.unbind();
|
|
||||||
|
|
||||||
_blockstx.texture.setup();
|
|
||||||
_blockstx.texture.setSamplerParams(false);
|
|
||||||
|
|
||||||
_program.draw(_minerMesh);
|
|
||||||
|
|
||||||
_blockstx.texture.unbind();
|
|
||||||
|
|
||||||
_program.unbind();
|
|
||||||
checkgl!glDisable(GL_DEPTH_TEST);
|
checkgl!glDisable(GL_DEPTH_TEST);
|
||||||
checkgl!glDisable(GL_CULL_FACE);
|
checkgl!glDisable(GL_CULL_FACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
~this() {
|
~this() {
|
||||||
destroy(_scene);
|
|
||||||
if (_program)
|
|
||||||
destroy(_program);
|
|
||||||
if (_tx)
|
|
||||||
destroy(_tx);
|
|
||||||
destroy(_world);
|
destroy(_world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ class Camera : Node3d {
|
||||||
|
|
||||||
protected bool _enabled;
|
protected bool _enabled;
|
||||||
|
|
||||||
this() {
|
this(string ID = null) {
|
||||||
|
super(ID);
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
setPerspective(4.0f, 3.0f, 45.0f, 0.1f, 100.0f);
|
setPerspective(4.0f, 3.0f, 45.0f, 0.1f, 100.0f);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +31,11 @@ class Camera : Node3d {
|
||||||
_enabled = v;
|
_enabled = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// returns true if some changes occured in projection or view matrix since last matrix getter call
|
||||||
|
@property bool viewChanged() {
|
||||||
|
return _dirtyTransform || _dirtyViewProjection || _dirtyView;
|
||||||
|
}
|
||||||
|
|
||||||
/// get projection matrix
|
/// get projection matrix
|
||||||
@property ref const(mat4) projectionMatrix() {
|
@property ref const(mat4) projectionMatrix() {
|
||||||
return _projectionMatrix;
|
return _projectionMatrix;
|
||||||
|
|
|
@ -12,40 +12,6 @@ import dlangui.graphics.scene.mesh;
|
||||||
/// Reference counted Effect object
|
/// Reference counted Effect object
|
||||||
alias EffectRef = Ref!Effect;
|
alias EffectRef = Ref!Effect;
|
||||||
|
|
||||||
/// Effect ID
|
|
||||||
struct EffectId {
|
|
||||||
string vertexShaderName;
|
|
||||||
string fragmentShaderName;
|
|
||||||
string definitions;
|
|
||||||
this(string vertexShader, string fragmentShader, string defs) {
|
|
||||||
vertexShaderName = vertexShader;
|
|
||||||
fragmentShaderName = fragmentShader;
|
|
||||||
definitions = defs;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t toHash() const @safe pure nothrow
|
|
||||||
{
|
|
||||||
size_t hash;
|
|
||||||
foreach (char c; vertexShaderName)
|
|
||||||
hash = (hash * 9) + c;
|
|
||||||
hash = (hash * 31) + 198237283;
|
|
||||||
foreach (char c; fragmentShaderName)
|
|
||||||
hash = (hash * 9) + c;
|
|
||||||
hash = (hash * 31) + 84574112;
|
|
||||||
foreach (char c; definitions)
|
|
||||||
hash = (hash * 9) + c;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool opEquals(ref const EffectId s) const @safe pure nothrow
|
|
||||||
{
|
|
||||||
return
|
|
||||||
std.string.cmp(this.vertexShaderName, s.vertexShaderName) == 0 &&
|
|
||||||
std.string.cmp(this.fragmentShaderName, s.fragmentShaderName) == 0 &&
|
|
||||||
std.string.cmp(this.definitions, s.definitions) == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Effect (aka OpenGL program)
|
/// Effect (aka OpenGL program)
|
||||||
class Effect : GLProgram {
|
class Effect : GLProgram {
|
||||||
EffectId _id;
|
EffectId _id;
|
||||||
|
@ -181,3 +147,43 @@ class EffectCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Effect ID
|
||||||
|
struct EffectId {
|
||||||
|
string vertexShaderName;
|
||||||
|
string fragmentShaderName;
|
||||||
|
string definitions;
|
||||||
|
this(string vertexShader, string fragmentShader, string defs) {
|
||||||
|
vertexShaderName = vertexShader;
|
||||||
|
fragmentShaderName = fragmentShader;
|
||||||
|
definitions = defs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns true if ID is not assigned
|
||||||
|
@property bool empty() {
|
||||||
|
return !vertexShaderName.length || !vertexShaderName.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t toHash() const @safe pure nothrow
|
||||||
|
{
|
||||||
|
size_t hash;
|
||||||
|
foreach (char c; vertexShaderName)
|
||||||
|
hash = (hash * 9) + c;
|
||||||
|
hash = (hash * 31) + 198237283;
|
||||||
|
foreach (char c; fragmentShaderName)
|
||||||
|
hash = (hash * 9) + c;
|
||||||
|
hash = (hash * 31) + 84574112;
|
||||||
|
foreach (char c; definitions)
|
||||||
|
hash = (hash * 9) + c;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool opEquals(ref const EffectId s) const @safe pure nothrow
|
||||||
|
{
|
||||||
|
return
|
||||||
|
std.string.cmp(this.vertexShaderName, s.vertexShaderName) == 0 &&
|
||||||
|
std.string.cmp(this.fragmentShaderName, s.fragmentShaderName) == 0 &&
|
||||||
|
std.string.cmp(this.definitions, s.definitions) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,32 @@ import dlangui.core.logger;
|
||||||
import dlangui.graphics.glsupport;
|
import dlangui.graphics.glsupport;
|
||||||
import dlangui.graphics.gldrawbuf;
|
import dlangui.graphics.gldrawbuf;
|
||||||
import dlangui.graphics.scene.effect;
|
import dlangui.graphics.scene.effect;
|
||||||
|
import dlangui.graphics.scene.node;
|
||||||
|
import dlangui.graphics.scene.mesh;
|
||||||
|
|
||||||
/// Reference counted Material object
|
/// Reference counted Material object
|
||||||
alias MaterialRef = Ref!Material;
|
alias MaterialRef = Ref!Material;
|
||||||
|
|
||||||
class Material : RefCountedObject {
|
class Material : RefCountedObject {
|
||||||
protected EffectRef _effect;
|
protected EffectRef _effect;
|
||||||
|
protected EffectId _effectId;
|
||||||
protected TextureRef _texture;
|
protected TextureRef _texture;
|
||||||
|
protected string _textureId;
|
||||||
// TODO: more material properties
|
// TODO: more material properties
|
||||||
|
|
||||||
@property EffectRef effect() { return _effect; }
|
this() {
|
||||||
|
}
|
||||||
|
|
||||||
|
this(EffectId effectId, string textureId) {
|
||||||
|
_effectId = effectId;
|
||||||
|
_textureId = textureId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property EffectRef effect() {
|
||||||
|
if (_effect.isNull && !_effectId.empty)
|
||||||
|
_effect = EffectCache.instance.get(_effectId);
|
||||||
|
return _effect;
|
||||||
|
}
|
||||||
/// set as effect instance
|
/// set as effect instance
|
||||||
@property Material effect(EffectRef e) {
|
@property Material effect(EffectRef e) {
|
||||||
_effect = e;
|
_effect = e;
|
||||||
|
@ -24,11 +40,19 @@ class Material : RefCountedObject {
|
||||||
}
|
}
|
||||||
/// set as effect id
|
/// set as effect id
|
||||||
@property Material effect(EffectId effectId) {
|
@property Material effect(EffectId effectId) {
|
||||||
_effect = EffectCache.instance.get(effectId);
|
if (_effectId == effectId)
|
||||||
|
return this; // no change
|
||||||
|
_effectId = effectId;
|
||||||
|
_effect.clear();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property TextureRef texture() { return _texture; }
|
@property TextureRef texture() {
|
||||||
|
if (_texture.isNull && _textureId.length) {
|
||||||
|
_texture = GLTextureCache.instance.get(_textureId);
|
||||||
|
}
|
||||||
|
return _texture;
|
||||||
|
}
|
||||||
/// set texture
|
/// set texture
|
||||||
@property Material texture(TextureRef e) {
|
@property Material texture(TextureRef e) {
|
||||||
_texture = e;
|
_texture = e;
|
||||||
|
@ -36,7 +60,32 @@ class Material : RefCountedObject {
|
||||||
}
|
}
|
||||||
/// set texture from resourceId
|
/// set texture from resourceId
|
||||||
@property Material texture(string resourceId) {
|
@property Material texture(string resourceId) {
|
||||||
_texture = GLTextureCache.instance.get(resourceId);
|
if (_textureId == resourceId)
|
||||||
|
return this; // no change
|
||||||
|
_texture.clear();
|
||||||
|
_textureId = resourceId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bind(Node3d node) {
|
||||||
|
assert(!effect.isNull);
|
||||||
|
effect.bind();
|
||||||
|
if (!texture.isNull) {
|
||||||
|
texture.texture.setup();
|
||||||
|
texture.texture.setSamplerParams(true);
|
||||||
|
}
|
||||||
|
// TODO: more uniforms
|
||||||
|
_effect.setUniform("matrix", node.projectionViewModelMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawMesh(Mesh mesh) {
|
||||||
|
effect.draw(mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unbind() {
|
||||||
|
if (!texture.isNull) {
|
||||||
|
texture.texture.unbind();
|
||||||
|
}
|
||||||
|
effect.unbind();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,21 +5,33 @@ import dlangui.core.math3d;
|
||||||
import dlangui.graphics.scene.transform;
|
import dlangui.graphics.scene.transform;
|
||||||
import dlangui.core.collections;
|
import dlangui.core.collections;
|
||||||
import dlangui.graphics.scene.scene3d;
|
import dlangui.graphics.scene.scene3d;
|
||||||
|
import dlangui.graphics.scene.drawableobject;
|
||||||
|
|
||||||
/// 3D scene node
|
/// 3D scene node
|
||||||
class Node3d : Transform {
|
class Node3d : Transform {
|
||||||
protected Node3d _parent;
|
protected Node3d _parent;
|
||||||
protected Scene3d _scene;
|
protected Scene3d _scene;
|
||||||
protected string _id;
|
protected string _id;
|
||||||
|
protected DrawableObjectRef _drawable;
|
||||||
|
|
||||||
protected mat4 _worldMatrix;
|
protected mat4 _worldMatrix;
|
||||||
|
|
||||||
protected ObjectList!Node3d _children;
|
protected ObjectList!Node3d _children;
|
||||||
|
|
||||||
this() {
|
this(string id = null) {
|
||||||
super();
|
super();
|
||||||
|
_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this(string id, DrawableObject drawable) {
|
||||||
|
super();
|
||||||
|
_id = id;
|
||||||
|
_drawable = drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// drawable attached to node
|
||||||
|
@property ref DrawableObjectRef drawable() { return _drawable; }
|
||||||
|
|
||||||
/// returns scene for node
|
/// returns scene for node
|
||||||
@property Scene3d scene() {
|
@property Scene3d scene() {
|
||||||
if (_scene)
|
if (_scene)
|
||||||
|
@ -41,11 +53,12 @@ class Node3d : Transform {
|
||||||
return _children[index];
|
return _children[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add child node
|
/// add child node, return current node
|
||||||
void addChild(Node3d node) {
|
Node3d addChild(Node3d node) {
|
||||||
_children.add(node);
|
_children.add(node);
|
||||||
node.parent = this;
|
node.parent = this;
|
||||||
node.scene = scene;
|
node.scene = scene;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// removes and destroys child node by index
|
/// removes and destroys child node by index
|
||||||
|
@ -53,6 +66,8 @@ class Node3d : Transform {
|
||||||
destroy(_children.remove(index));
|
destroy(_children.remove(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property ref ObjectList!Node3d children() { return _children; }
|
||||||
|
|
||||||
/// parent node
|
/// parent node
|
||||||
@property Node3d parent() {
|
@property Node3d parent() {
|
||||||
return _parent;
|
return _parent;
|
||||||
|
@ -60,6 +75,7 @@ class Node3d : Transform {
|
||||||
|
|
||||||
@property Node3d parent(Node3d v) {
|
@property Node3d parent(Node3d v) {
|
||||||
_parent = v;
|
_parent = v;
|
||||||
|
_scene = v.scene;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/// id of node
|
/// id of node
|
||||||
|
@ -71,4 +87,9 @@ class Node3d : Transform {
|
||||||
_id = v;
|
_id = v;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// returns projectionMatrix * viewMatrix * modelMatrix
|
||||||
|
@property mat4 projectionViewModelMatrix() {
|
||||||
|
return _scene.projectionViewMatrix * matrix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
module dlangui.graphics.scene.scene3d;
|
module dlangui.graphics.scene.scene3d;
|
||||||
|
|
||||||
|
import dlangui.core.types;
|
||||||
import dlangui.graphics.scene.node;
|
import dlangui.graphics.scene.node;
|
||||||
import dlangui.graphics.scene.camera;
|
import dlangui.graphics.scene.camera;
|
||||||
|
|
||||||
public import dlangui.core.math3d;
|
public import dlangui.core.math3d;
|
||||||
|
|
||||||
|
/// Reference counted Scene3d object
|
||||||
|
alias Scene3dRef = Ref!Scene3d;
|
||||||
|
|
||||||
/// 3D scene
|
/// 3D scene
|
||||||
class Scene3d : Node3d {
|
class Scene3d : Node3d {
|
||||||
|
|
||||||
|
@ -47,6 +51,29 @@ class Scene3d : Node3d {
|
||||||
static mat4 dummyIdentityMatrix;
|
static mat4 dummyIdentityMatrix;
|
||||||
return dummyIdentityMatrix;
|
return dummyIdentityMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool _wireframe;
|
||||||
|
void drawScene(bool wireframe) {
|
||||||
|
_wireframe = wireframe;
|
||||||
|
visit(this, &sceneDrawVisitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool sceneDrawVisitor(Node3d node) {
|
||||||
|
if (!node.drawable.isNull)
|
||||||
|
node.drawable.draw(node, _wireframe);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// depth-first recursive node traversion, stops if visitor returns true
|
||||||
|
bool visit(Node3d node, bool delegate(Node3d node) visitor) {
|
||||||
|
bool res = visitor(node);
|
||||||
|
if (res)
|
||||||
|
return true;
|
||||||
|
foreach(child; node.children) {
|
||||||
|
bool res = visit(child, visitor);
|
||||||
|
if (res)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
module dlangui.graphics.scene.transform;
|
module dlangui.graphics.scene.transform;
|
||||||
|
|
||||||
import dlangui.core.math3d;
|
import dlangui.core.math3d;
|
||||||
|
import dlangui.core.types;
|
||||||
|
|
||||||
/// 3d transform: scale + translation + rotation
|
/// 3d transform: scale + translation + rotation
|
||||||
class Transform {
|
class Transform : RefCountedObject {
|
||||||
// transform flags
|
// transform flags
|
||||||
protected bool _dirtyTransform = true;
|
protected bool _dirtyTransform = true;
|
||||||
protected bool _hasScale = false;
|
protected bool _hasScale = false;
|
||||||
|
|
Loading…
Reference in New Issue