Scene3d: SkyBox support working - close #290

This commit is contained in:
Vadim Lopatin 2016-08-25 13:25:21 +03:00
parent 40dd1148dd
commit 4bca147017
12 changed files with 116 additions and 4 deletions

View File

@ -10,10 +10,12 @@ import dlangui.graphics.scene.model;
import dlangui.graphics.scene.node;
import dlangui.graphics.scene.light;
import dlangui.graphics.scene.drawableobject;
import dlangui.graphics.scene.skybox;
import dlangui.graphics.scene.effect;
import dlangui.graphics.glsupport;
import dlangui.graphics.gldrawbuf;
import dlangui.graphics.scene.effect;
/*
version (Android) {
//enum SUPPORT_LEGACY_OPENGL = false;
public import EGL.eglplatform : EGLint;
@ -25,6 +27,7 @@ version (Android) {
import derelict.opengl3.gl3;
import derelict.opengl3.gl;
}
*/
import dminer.core.minetypes;
import dminer.core.blocks;
@ -149,6 +152,13 @@ class UiWidget : VerticalLayout { //, CellVisitor
_scene.activeCamera = _cam;
_scene.skyBox.setFaceTexture(SkyBox.Face.Right, "skybox_night_right1");
_scene.skyBox.setFaceTexture(SkyBox.Face.Left, "skybox_night_left2");
_scene.skyBox.setFaceTexture(SkyBox.Face.Top, "skybox_night_top3");
_scene.skyBox.setFaceTexture(SkyBox.Face.Bottom, "skybox_night_bottom4");
_scene.skyBox.setFaceTexture(SkyBox.Face.Front, "skybox_night_front5");
_scene.skyBox.setFaceTexture(SkyBox.Face.Back, "skybox_night_back6");
dirLightNode = new Node3d();
dirLightNode.rotateY(-15);
dirLightNode.translateX(2);
@ -212,6 +222,7 @@ class UiWidget : VerticalLayout { //, CellVisitor
minerMaterial.fogParams = new FogParams(vec4(0.01, 0.01, 0.01, 1), 12, 80);
//minerMaterial.specular = 10;
_minerDrawable = new MinerDrawable(_world, minerMaterial, _cam);
//_minerDrawable.autobindLights = false;
//Model minerDrawable = new Model(minerMaterial, _minerMesh);
Node3d minerNode = new Node3d("miner", _minerDrawable);
_scene.addChild(minerNode);

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

View File

@ -2,3 +2,9 @@ res/i18n/en.ini
res/i18n/ru.ini
res/mdpi/cr3_logo.png
res/mdpi/blocks.png
res/skybox_night_right1.png
res/skybox_night_left2.png
res/skybox_night_top3.png
res/skybox_night_bottom4.png
res/skybox_night_front5.png
res/skybox_night_back6.png

View File

@ -56,6 +56,8 @@ class MaterialDrawableObject : DrawableObject {
@property protected LightParams * lights(Node3d node) {
if (!node.scene)
return null;
if (!_autobindLights)
return null; // TODO: allow manually bound lights
if (_lights.empty) {
if (node.scene.boundLights.empty)
return null;

View File

@ -170,7 +170,10 @@ class Node3d : Transform {
/// returns projectionMatrix * viewMatrix * modelMatrix
@property ref const(mat4) projectionViewModelMatrix() {
// TODO: optimize
_projectionViewModelMatrix = _scene.projectionViewMatrix * matrix;
if (_parent)
_projectionViewModelMatrix = _scene.projectionViewMatrix * _parent.matrix * matrix;
else
_projectionViewModelMatrix = _scene.projectionViewMatrix * matrix;
return _projectionViewModelMatrix;
}

View File

@ -66,11 +66,17 @@ class Scene3d : Node3d {
_wireframe = wireframe;
updateAutoboundLights();
if (_skyBox.visible) {
import dlangui.graphics.glsupport;
checkgl!glDisable(GL_DEPTH_TEST);
checkgl!glDisable(GL_CULL_FACE);
if (_activeCamera) {
_skyBox.translation = _activeCamera.translation;
_skyBox.scaling = _activeCamera.farRange * 0.8;
_skyBox.scaling = _activeCamera.farRange * 0.9;
}
sceneDrawVisitor(_skyBox);
visit(_skyBox, &sceneDrawVisitor);
checkgl!glEnable(GL_DEPTH_TEST);
checkgl!glEnable(GL_CULL_FACE);
checkgl!glClear(GL_DEPTH_BUFFER_BIT);
}
visit(this, &sceneDrawVisitor);
}

View File

@ -0,0 +1,84 @@
module dlangui.graphics.scene.skybox;
import dlangui.core.math3d;
import dlangui.graphics.scene.node;
import dlangui.graphics.scene.model;
import dlangui.graphics.scene.scene3d;
import dlangui.graphics.scene.mesh;
import dlangui.graphics.scene.material;
import dlangui.graphics.scene.effect;
class SkyBox : Node3d {
private Node3d[6] _faceNodes;
enum Face {
Back,
Front,
Left,
Right,
Top,
Bottom
}
this(Scene3d scene) {
_parent = scene;
_scene = scene;
_visible = false;
}
void removeFace(Face face) {
if (_faceNodes[face]) {
removeChild(_faceNodes[face]);
_faceNodes[face] = null;
}
}
void setFaceTexture(Face face, string textureName) {
removeFace(face);
if (!textureName)
return;
Material material = new Material(EffectId("textured.vert", "textured.frag", null), textureName);
//material.ambientColor = vec3(0.9,0.9,0.9);
material.textureLinear = true;
Mesh mesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
const float d = 1;
const vec3 pos = vec3(0,0,0);
vec4 color = vec4(1,1,1,1);
auto p000 = vec3(pos.x-d, pos.y-d, pos.z-d);
auto p100 = vec3(pos.x+d, pos.y-d, pos.z-d);
auto p010 = vec3(pos.x-d, pos.y+d, pos.z-d);
auto p110 = vec3(pos.x+d, pos.y+d, pos.z-d);
auto p001 = vec3(pos.x-d, pos.y-d, pos.z+d);
auto p101 = vec3(pos.x+d, pos.y-d, pos.z+d);
auto p011 = vec3(pos.x-d, pos.y+d, pos.z+d);
auto p111 = vec3(pos.x+d, pos.y+d, pos.z+d);
final switch(face) with(Face) {
case Front:
mesh.addQuad(p000, p010, p110, p100, color); // front face
break;
case Back:
mesh.addQuad(p101, p111, p011, p001, color); // back face
break;
case Right:
mesh.addQuad(p100, p110, p111, p101, color); // right face
break;
case Left:
mesh.addQuad(p001, p011, p010, p000, color); // left face
break;
case Top:
mesh.addQuad(p010, p011, p111, p110, color); // top face
break;
case Bottom:
mesh.addQuad(p001, p000, p100, p101, color); // bottom face
break;
}
Model model = new Model(material, mesh);
model.autobindLights = false;
Node3d node = new Node3d();
node.drawable = model;
_faceNodes[face] = node;
addChild(node);
_visible = true;
}
}