3d scene - effect; for #183

This commit is contained in:
Vadim Lopatin 2016-03-29 14:50:33 +03:00
parent 59c6df1c06
commit b3da543c8c
15 changed files with 234 additions and 84 deletions

View File

@ -280,12 +280,13 @@
<Compile Include="src\dlangui\graphics\images.d" />
<Compile Include="src\dlangui\graphics\resources.d" />
<Compile Include="src\dlangui\graphics\scene\camera.d" />
<Compile Include="src\dlangui\graphics\scene\effect.d" />
<Compile Include="src\dlangui\graphics\scene\material.d" />
<Compile Include="src\dlangui\graphics\scene\mesh.d" />
<Compile Include="src\dlangui\graphics\scene\node.d" />
<Compile Include="src\dlangui\graphics\scene\scene3d.d" />
<Compile Include="src\dlangui\graphics\scene\transform.d" />
<Compile Include="src\dlangui\graphics\xpm\colors.d" />
<Compile Include="src\dlangui\graphics\xpm\xpmcolors.d" />
<Compile Include="src\dlangui\graphics\xpm\reader.d" />
<Compile Include="src\dlangui\platforms\common\platform.d" />
<Compile Include="src\dlangui\platforms\sdl\sdlapp.d" />

View File

@ -139,6 +139,7 @@
<Compile Include="src\dlangui\graphics\images.d" />
<Compile Include="src\dlangui\graphics\resources.d" />
<Compile Include="src\dlangui\graphics\scene\camera.d" />
<Compile Include="src\dlangui\graphics\scene\effect.d" />
<Compile Include="src\dlangui\graphics\scene\material.d" />
<Compile Include="src\dlangui\graphics\scene\mesh.d" />
<Compile Include="src\dlangui\graphics\scene\node.d" />
@ -198,7 +199,7 @@
<Compile Include="deps\DerelictFT\source\derelict\freetype\ft.d" />
<Compile Include="deps\DerelictFT\source\derelict\freetype\functions.d" />
<Compile Include="deps\DerelictFT\source\derelict\freetype\types.d" />
<Compile Include="src\dlangui\graphics\xpm\colors.d" />
<Compile Include="src\dlangui\graphics\xpm\xpmcolors.d" />
<Compile Include="3rdparty\fontconfig\functions.d" />
<Compile Include="3rdparty\fontconfig\package.d" />
<Compile Include="3rdparty\fontconfig\types.d" />

View File

@ -117,7 +117,7 @@
<Compile Include="src\dlangui\graphics\scene\node.d" />
<Compile Include="src\dlangui\graphics\scene\scene3d.d" />
<Compile Include="src\dlangui\graphics\scene\transform.d" />
<Compile Include="src\dlangui\graphics\xpm\colors.d" />
<Compile Include="src\dlangui\graphics\xpm\xpmcolors.d" />
<Compile Include="src\dlangui\graphics\xpm\reader.d" />
<Compile Include="src\dlangui\platforms\common\platform.d" />
<Compile Include="src\dlangui\platforms\common\startup.d" />

View File

@ -771,6 +771,7 @@
<Folder name="graphics">
<Folder name="scene">
<File path="src\dlangui\graphics\scene\camera.d" />
<File path="src\dlangui\graphics\scene\effect.d" />
<File path="src\dlangui\graphics\scene\material.d" />
<File path="src\dlangui\graphics\scene\mesh.d" />
<File path="src\dlangui\graphics\scene\node.d" />
@ -778,7 +779,7 @@
<File path="src\dlangui\graphics\scene\transform.d" />
</Folder>
<Folder name="xpm">
<File path="src\dlangui\graphics\xpm\colors.d" />
<File path="src\dlangui\graphics\xpm\xpmcolors.d" />
<File path="src\dlangui\graphics\xpm\reader.d" />
</Folder>
<File path="src\dlangui\graphics\colors.d" />

View File

@ -53,8 +53,8 @@
<cccmd>$(CC) -c</cccmd>
<ccTransOpt>1</ccTransOpt>
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
<imppath>$(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/deps/DerelictGL3/source $(SolutionDir)/deps/DerelictUtil/source $(SolutionDir)/deps/DerelictFT/source $(SolutionDir)/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
<imppath>$(SolutionDir)/../dlangui/src $(SolutionDir)/../dlangui/3rdparty $(SolutionDir)/../dlangui/deps/DerelictGL3/source $(SolutionDir)/../dlangui/deps/DerelictUtil/source $(SolutionDir)/../dlangui/deps/DerelictFT/source $(SolutionDir)/../dlangui/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders</fileImppath>
<outdir>$(ConfigurationName)</outdir>
<objdir>$(OutDir)</objdir>
<objname />
@ -155,8 +155,8 @@
<cccmd>$(CC) -c</cccmd>
<ccTransOpt>1</ccTransOpt>
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
<imppath>$(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/deps/DerelictGL3/source $(SolutionDir)/deps/DerelictUtil/source $(SolutionDir)/deps/DerelictFT/source $(SolutionDir)/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
<imppath>$(SolutionDir)/../dlangui/src $(SolutionDir)/../dlangui/3rdparty $(SolutionDir)/../dlangui/deps/DerelictGL3/source $(SolutionDir)/../dlangui/deps/DerelictUtil/source $(SolutionDir)/../dlangui/deps/DerelictFT/source $(SolutionDir)/../dlangui/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders</fileImppath>
<outdir>$(ConfigurationName)</outdir>
<objdir>$(OutDir)</objdir>
<objname />
@ -257,8 +257,8 @@
<cccmd>$(CC) -c</cccmd>
<ccTransOpt>1</ccTransOpt>
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
<imppath>$(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/deps/DerelictGL3/source $(SolutionDir)/deps/DerelictUtil/source $(SolutionDir)/deps/DerelictFT/source $(SolutionDir)/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
<imppath>$(SolutionDir)/../dlangui/src $(SolutionDir)/../dlangui/3rdparty $(SolutionDir)/../dlangui/deps/DerelictGL3/source $(SolutionDir)/../dlangui/deps/DerelictUtil/source $(SolutionDir)/../dlangui/deps/DerelictFT/source $(SolutionDir)/../dlangui/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders</fileImppath>
<outdir>$(ConfigurationName)</outdir>
<objdir>$(OutDir)</objdir>
<objname />
@ -359,8 +359,8 @@
<cccmd>$(CC) -c</cccmd>
<ccTransOpt>1</ccTransOpt>
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
<imppath>$(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/deps/DerelictGL3/source $(SolutionDir)/deps/DerelictUtil/source $(SolutionDir)/deps/DerelictFT/source $(SolutionDir)/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
<imppath>$(SolutionDir)/../dlangui/src $(SolutionDir)/../dlangui/3rdparty $(SolutionDir)/../dlangui/deps/DerelictGL3/source $(SolutionDir)/../dlangui/deps/DerelictUtil/source $(SolutionDir)/../dlangui/deps/DerelictFT/source $(SolutionDir)/../dlangui/deps/DerelictSDL2/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders</fileImppath>
<outdir>$(ConfigurationName)</outdir>
<objdir>$(OutDir)</objdir>
<objname />

View File

@ -5,7 +5,7 @@
"license": "Boost",
"authors": ["Vadim Lopatin"],
"stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi"],
"stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/shaders"],
"targetPath": "bin",
"targetName": "d3d",

View File

@ -5,6 +5,7 @@ import dlangui.graphics.scene.scene3d;
import dlangui.graphics.scene.camera;
import dlangui.graphics.scene.mesh;
import dlangui.graphics.scene.material;
import dlangui.graphics.scene.effect;
import dlangui.graphics.glsupport;
import dlangui.graphics.gldrawbuf;
import derelict.opengl3.gl3;
@ -228,7 +229,7 @@ class UiWidget : VerticalLayout, CellVisitor {
}
float angle = 0;
MyGLProgram _program;
EffectRef _program;
Scene3d _scene;
Camera _cam;
Mesh _mesh;
@ -239,11 +240,9 @@ class UiWidget : VerticalLayout, CellVisitor {
/// this is OpenGLDrawableDelegate implementation
private void doDraw(Rect windowRect, Rect rc) {
if (!_program) {
_program = new MyGLProgram();
if (_program.isNull) {
_program = EffectCache.instance.get("textured.vert", "textured.frag");
}
if (!_program.check())
return;
if (!_tx)
_tx = new GLTexture("crate");
if (!_blockstx)
@ -373,65 +372,3 @@ class TestVisitor : CellVisitor {
}
}
// Simple texture + color shader
class MyGLProgram : GLProgram {
@property override string vertexSource() {
return q{
in vec4 vertex;
in vec4 colAttr;
in vec4 texCoord;
out vec4 col;
out vec4 texc;
uniform mat4 matrix;
void main(void)
{
gl_Position = matrix * vertex;
col = colAttr;
texc = texCoord;
}
};
}
@property override string fragmentSource() {
return q{
uniform sampler2D tex;
in vec4 col;
in vec4 texc;
out vec4 outColor;
void main(void)
{
outColor = texture(tex, texc.st) * col;
}
};
}
// attribute locations
protected int matrixLocation;
protected int vertexLocation;
protected int colAttrLocation;
protected int texCoordLocation;
override bool initLocations() {
matrixLocation = getUniformLocation("matrix");
vertexLocation = getAttribLocation("vertex");
colAttrLocation = getAttribLocation("colAttr");
texCoordLocation = getAttribLocation("texCoord");
return matrixLocation >= 0 && vertexLocation >= 0 && colAttrLocation >= 0 && texCoordLocation >= 0;
}
/// get location for vertex attribute
override int getVertexElementLocation(VertexElementType type) {
switch(type) with(VertexElementType) {
case POSITION:
return vertexLocation;
case COLOR:
return colAttrLocation;
case TEXCOORD0:
return texCoordLocation;
default:
return super.getVertexElementLocation(type);
}
}
}

View File

@ -0,0 +1,8 @@
uniform sampler2D tex;
in vec4 col;
in vec4 texc;
out vec4 outColor;
void main(void)
{
outColor = texture(tex, texc.st) * col;
}

View File

@ -0,0 +1,12 @@
in vec4 vertex;
in vec4 colAttr;
in vec4 texCoord;
out vec4 col;
out vec4 texc;
uniform mat4 matrix;
void main(void)
{
gl_Position = matrix * vertex;
col = colAttr;
texc = texCoord;
}

View File

@ -4,3 +4,5 @@ res/mdpi/cr3_logo.png
res/mdpi/tx_fabric.jpg
res/mdpi/crate.png
res/mdpi/blocks.png
res/shaders/textured.vert
res/shaders/textured.frag

View File

@ -119,6 +119,11 @@ struct EmbeddedResourceList {
void addResources(EmbeddedResource[] resources) {
list ~= resources;
}
void dumpEmbeddedResources() {
foreach(r; list) {
Log.d("EmbeddedResource: ", r.name);
}
}
/// find by exact file name
EmbeddedResource * find(string name) {
// search backwards to allow overriding standard resources (which are added first)
@ -147,7 +152,7 @@ struct EmbeddedResourceList {
// search backwards to allow overriding standard resources (which are added first)
for (int i = cast(int)list.length - 1; i >= 0; i--) {
string s = list[i].name;
if (s.equal(xmlname) || s.equal(pngname) || s.equal(png9name)
if (s.equal(name) || s.equal(xmlname) || s.equal(pngname) || s.equal(png9name)
|| s.equal(jpgname) || s.equal(jpegname) || s.equal(xpmname))
return &list[i];
}

View File

@ -0,0 +1,182 @@
module dlangui.graphics.scene.effect;
public import dlangui.core.config;
static if (ENABLE_OPENGL):
import dlangui.core.types;
import dlangui.core.logger;
import dlangui.graphics.glsupport;
import dlangui.graphics.gldrawbuf;
import dlangui.graphics.scene.mesh;
/// Reference counted Effect object
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)
class Effect : GLProgram {
EffectId _id;
string[string] _defs;
@property ref const(EffectId) id() const { return _id; }
this(EffectId id) {
_id = id;
init();
}
this(string vertexShader, string fragmentShader, string defs) {
_id = EffectId(vertexShader, fragmentShader, defs);
init();
}
~this() {
_instance.onObjectDestroyed(_id);
}
protected void init() {
// parse defs
import std.array : split;
string[] defs = _id.definitions.split(";");
foreach(def; defs) {
assert(def.length > 0);
string[] items = def.split(" ");
if (items.length > 0) {
_defs[items[0]] = items.length > 1 ? items[1] : "";
}
}
// compile shaders
if (!check()) {
Log.e("Failed to compile shaders ", _id.vertexShaderName, " ", _id.fragmentShaderName, " ", _id.definitions);
assert(false);
}
}
protected string preProcessSource(string src) {
// TODO: preprocess source code
return src;
}
protected string loadVertexSource(string resourceId) {
import dlangui.graphics.resources;
import std.string : endsWith;
string filename;
filename = drawableCache.findResource(resourceId);
if (!filename) {
Log.e("Shader source resource file not found for resourceId ", resourceId);
assert(false);
}
if (!filename.endsWith(".vert") && !filename.endsWith(".frag")) {
Log.e("Shader source resource name should have .vert or .frag extension, but found ", filename);
assert(false);
}
string s = cast(string)loadResourceBytes(filename);
if (!s) {
Log.e("Cannot read shader source resource ", resourceId, " from file ", filename);
assert(false);
}
return s;
}
@property override string vertexSource() {
return preProcessSource(loadVertexSource(_id.vertexShaderName));
}
@property override string fragmentSource() {
return preProcessSource(loadVertexSource(_id.fragmentShaderName));
}
// attribute locations
protected int matrixLocation;
protected int vertexLocation;
protected int colAttrLocation;
protected int texCoordLocation;
override bool initLocations() {
matrixLocation = getUniformLocation("matrix");
vertexLocation = getAttribLocation("vertex");
colAttrLocation = getAttribLocation("colAttr");
texCoordLocation = getAttribLocation("texCoord");
return matrixLocation >= 0 && vertexLocation >= 0 && colAttrLocation >= 0 && texCoordLocation >= 0;
}
/// get location for vertex attribute
override int getVertexElementLocation(VertexElementType type) {
switch(type) with(VertexElementType) {
case POSITION:
return vertexLocation;
case COLOR:
return colAttrLocation;
case TEXCOORD0:
return texCoordLocation;
default:
return super.getVertexElementLocation(type);
}
}
}
/// Effects cache
class EffectCache {
private Effect[EffectId] _map;
/// returns effect cache singleton instance
static @property EffectCache instance() {
if (!_instance)
_instance = new EffectCache();
return _instance;
}
static private void onObjectDestroyed(EffectId id) {
if (id in _instance._map)
_instance._map.remove(id);
}
/// get effect from cache or create new if not exist
Effect get(string vertexShader, string fragmentShader, string defs = null) {
return get(EffectId(vertexShader, fragmentShader, defs));
}
/// get effect from cache or create new if not exist
Effect get(const EffectId id) {
if (auto p = id in _map) {
return *p;
}
Effect e = new Effect(id);
_map[id] = e;
return e;
}
}
private __gshared EffectCache _instance;

View File

@ -2,6 +2,7 @@ module dlangui.graphics.scene.mesh;
import dlangui.graphics.scene.material;
import dlangui.core.math3d;
import dlangui.core.types;
/// vertex element type
enum VertexElementType : ubyte {
@ -43,7 +44,7 @@ class VertexBuffer {
enum VERTEX_ELEMENT_NOT_FOUND = -1;
/// Base class for graphics effect / program - e.g. for OpenGL shader program
abstract class GraphicsEffect {
abstract class GraphicsEffect : RefCountedObject {
/// get location for vertex attribute
int getVertexElementLocation(VertexElementType type);

View File

@ -9,7 +9,7 @@ module dlangui.graphics.xpm.reader;
*
*/
import dlangui.graphics.xpm.colors;
import dlangui.graphics.xpm.xpmcolors;
import dlangui.graphics.colors;
import dlangui.graphics.drawbuf;

View File

@ -1,5 +1,5 @@
module dlangui.graphics.xpm.colors;
module dlangui.graphics.xpm.xpmcolors;
import std.algorithm : cmp;
///Represents for predefined xpm color