From b01f90c7c2a590e40fe3066722e4380e337c1f61 Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Mon, 4 Apr 2016 11:04:22 +0300 Subject: [PATCH] #183 OpenGL shaders code refactoring; compatibility with GamePlay SDK --- examples/d3d/src/d3d.d | 2 +- examples/d3d/views/res/shaders/colored.frag | 147 +++++++++++++- examples/d3d/views/res/shaders/colored.vert | 154 +++++++++++++- examples/d3d/views/res/shaders/lighting.frag | 92 +++++++++ examples/d3d/views/res/shaders/lighting.vert | 67 +++++++ .../d3d/views/res/shaders/skinning-none.vert | 25 +++ examples/d3d/views/res/shaders/skinning.vert | 84 ++++++++ examples/d3d/views/res/shaders/textured.frag | 159 ++++++++++++++- examples/d3d/views/res/shaders/textured.vert | 188 +++++++++++++++++- examples/d3d/views/resources.list | 4 + src/dlangui/graphics/glsupport.d | 105 +++++++--- src/dlangui/graphics/scene/effect.d | 54 +++-- src/dlangui/graphics/scene/material.d | 2 +- src/dlangui/graphics/scene/mesh.d | 50 ++++- src/dlangui/graphics/scene/node.d | 6 +- 15 files changed, 1057 insertions(+), 82 deletions(-) create mode 100644 examples/d3d/views/res/shaders/lighting.frag create mode 100644 examples/d3d/views/res/shaders/lighting.vert create mode 100644 examples/d3d/views/res/shaders/skinning-none.vert create mode 100644 examples/d3d/views/res/shaders/skinning.vert diff --git a/examples/d3d/src/d3d.d b/examples/d3d/src/d3d.d index 5ca52f2b..2d7ceea0 100644 --- a/examples/d3d/src/d3d.d +++ b/examples/d3d/src/d3d.d @@ -138,7 +138,7 @@ class UiWidget : VerticalLayout, CellVisitor { string src = loadTextResource("suzanne.obj"); importer.parse(src); Log.d("suzanne mesh:", importer.mesh.dumpVertexes(20)); - Material suzanneMaterial = new Material(EffectId("colored.vert", "colored.frag", null), "DIRECTIONAL_LIGHT_COUNT 1"); + Material suzanneMaterial = new Material(EffectId("colored.vert", "colored.frag", "DIRECTIONAL_LIGHT_COUNT 1"), null); Model suzanneDrawable = new Model(suzanneMaterial, importer.mesh); Node3d suzanneNode = new Node3d("suzanne", suzanneDrawable); //suzanneNode.translate(vec3(3, 4, 5)); diff --git a/examples/d3d/views/res/shaders/colored.frag b/examples/d3d/views/res/shaders/colored.frag index 05fd8f04..d07d3e3d 100644 --- a/examples/d3d/views/res/shaders/colored.frag +++ b/examples/d3d/views/res/shaders/colored.frag @@ -1,7 +1,144 @@ -uniform sampler2D tex; -in vec4 col; -out vec4 outColor; -void main(void) +#ifdef OPENGL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + +#ifndef DIRECTIONAL_LIGHT_COUNT +#define DIRECTIONAL_LIGHT_COUNT 0 +#endif +#ifndef SPOT_LIGHT_COUNT +#define SPOT_LIGHT_COUNT 0 +#endif +#ifndef POINT_LIGHT_COUNT +#define POINT_LIGHT_COUNT 0 +#endif +#if (DIRECTIONAL_LIGHT_COUNT > 0) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) +#define LIGHTING +#endif + +/////////////////////////////////////////////////////////// +// Uniforms +uniform vec3 u_ambientColor; +uniform vec4 u_diffuseColor; + +#if defined(LIGHTMAP) +uniform sampler2D u_lightmapTexture; +#endif + +#if defined(LIGHTING) + +#if (DIRECTIONAL_LIGHT_COUNT > 0) +uniform vec3 u_directionalLightColor[DIRECTIONAL_LIGHT_COUNT]; +uniform vec3 u_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; +#endif + +#if (POINT_LIGHT_COUNT > 0) +uniform vec3 u_pointLightColor[POINT_LIGHT_COUNT]; +uniform vec3 u_pointLightPosition[POINT_LIGHT_COUNT]; +uniform float u_pointLightRangeInverse[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +uniform vec3 u_spotLightColor[SPOT_LIGHT_COUNT]; +uniform vec3 u_spotLightDirection[SPOT_LIGHT_COUNT]; +uniform float u_spotLightRangeInverse[SPOT_LIGHT_COUNT]; +uniform float u_spotLightInnerAngleCos[SPOT_LIGHT_COUNT]; +uniform float u_spotLightOuterAngleCos[SPOT_LIGHT_COUNT]; +#endif + +#if defined(SPECULAR) +uniform float u_specularExponent; +#endif + +#endif + +#if defined(MODULATE_COLOR) +uniform vec4 u_modulateColor; +#endif + +#if defined(MODULATE_ALPHA) +uniform float u_modulateAlpha; +#endif + +/////////////////////////////////////////////////////////// +// Variables +vec4 _baseColor; + +/////////////////////////////////////////////////////////// +// Varyings +#if defined(VERTEX_COLOR) +varying vec3 v_color; +#endif + +#if defined(LIGHTMAP) +varying vec2 v_texCoord1; +#endif + +#if defined(LIGHTING) + +varying vec3 v_normalVector; + +#if (POINT_LIGHT_COUNT > 0) +varying vec3 v_vertexToPointLightDirection[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +varying vec3 v_vertexToSpotLightDirection[SPOT_LIGHT_COUNT]; +#endif + +#if defined(SPECULAR) +varying vec3 v_cameraDirection; +#endif + +#include "lighting.frag" + +#endif + +#if defined(CLIP_PLANE) +varying float v_clipDistance; +#endif + +void main() { - outColor = col; + #if defined(CLIP_PLANE) + if(v_clipDistance < 0.0) discard; + #endif + + #if defined(LIGHTING) + + #if defined(VERTEX_COLOR) + _baseColor.rgb = v_color; + #else + _baseColor = u_diffuseColor; + #endif + + gl_FragColor.a = _baseColor.a; + gl_FragColor.rgb = getLitPixel(); + + #else + + #if defined(VERTEX_COLOR) + gl_FragColor.rgb = v_color; + gl_FragColor.a = 1.0; + #else + gl_FragColor = u_diffuseColor; + #endif + + #endif + + #if defined(LIGHTMAP) + vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord1); + gl_FragColor.rgb *= lightColor.rgb; + #endif + + #if defined(MODULATE_COLOR) + gl_FragColor *= u_modulateColor; + #endif + + #if defined(MODULATE_ALPHA) + gl_FragColor.a *= u_modulateAlpha; + #endif } diff --git a/examples/d3d/views/res/shaders/colored.vert b/examples/d3d/views/res/shaders/colored.vert index 4ee0d2ab..f334f84c 100644 --- a/examples/d3d/views/res/shaders/colored.vert +++ b/examples/d3d/views/res/shaders/colored.vert @@ -1,9 +1,149 @@ -in vec4 vertex; -in vec4 colAttr; -out vec4 col; -uniform mat4 matrix; -void main(void) +#ifndef DIRECTIONAL_LIGHT_COUNT +#define DIRECTIONAL_LIGHT_COUNT 0 +#endif +#ifndef SPOT_LIGHT_COUNT +#define SPOT_LIGHT_COUNT 0 +#endif +#ifndef POINT_LIGHT_COUNT +#define POINT_LIGHT_COUNT 0 +#endif +#if (DIRECTIONAL_LIGHT_COUNT > 0) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) +#define LIGHTING +#endif + +/////////////////////////////////////////////////////////// +// Attributes +attribute vec4 a_position; + +#if defined(SKINNING) +attribute vec4 a_blendWeights; +attribute vec4 a_blendIndices; +#endif + +#if defined(LIGHTMAP) +attribute vec2 a_texCoord1; +#endif + +#if defined(LIGHTING) +attribute vec3 a_normal; +#endif + +#if defined(VERTEX_COLOR) +attribute vec3 a_color; +#endif + +/////////////////////////////////////////////////////////// +// Uniforms +uniform mat4 u_worldViewProjectionMatrix; + +#if defined(SKINNING) +uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; +#endif + +#if defined(LIGHTING) +uniform mat4 u_inverseTransposeWorldViewMatrix; + +#if (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) || defined(SPECULAR) +uniform mat4 u_worldViewMatrix; +#endif + +#if (DIRECTIONAL_LIGHT_COUNT > 0) +uniform vec3 u_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; +#endif + +#if (POINT_LIGHT_COUNT > 0) +uniform vec3 u_pointLightPosition[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +uniform vec3 u_spotLightPosition[SPOT_LIGHT_COUNT]; +uniform vec3 u_spotLightDirection[SPOT_LIGHT_COUNT]; +#endif + +#if defined(SPECULAR) +uniform vec3 u_cameraPosition; +#endif + +#endif + +#if defined(CLIP_PLANE) +uniform mat4 u_worldMatrix; +uniform vec4 u_clipPlane; +#endif + +/////////////////////////////////////////////////////////// +// Varyings +#if defined(LIGHTMAP) +varying vec2 v_texCoord1; +#endif + +#if defined(VERTEX_COLOR) +varying vec3 v_color; +#endif + +#if defined(LIGHTING) + +varying vec3 v_normalVector; + +#if (DIRECTIONAL_LIGHT_COUNT > 0) +varying vec3 v_lightDirection[DIRECTIONAL_LIGHT_COUNT]; +#endif + +#if (POINT_LIGHT_COUNT > 0) +varying vec3 v_vertexToPointLightDirection[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +varying vec3 v_vertexToSpotLightDirection[SPOT_LIGHT_COUNT]; +#endif + +#if defined(SPECULAR) +varying vec3 v_cameraDirection; +#endif + +#include "lighting.vert" + +#endif + +#if defined(SKINNING) +#include "skinning.vert" +#else +#include "skinning-none.vert" +#endif + +#if defined(CLIP_PLANE) +varying float v_clipDistance; +#endif + +void main() { - gl_Position = matrix * vertex; - col = colAttr; + vec4 position = getPosition(); + gl_Position = u_worldViewProjectionMatrix * position; + + #if defined (LIGHTING) + + vec3 normal = getNormal(); + + // Transform normal to view space. + mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz); + v_normalVector = inverseTransposeWorldViewMatrix * normal; + + // Apply light. + applyLight(position); + + #endif + + // Pass the lightmap texture coordinate + #if defined(LIGHTMAP) + v_texCoord1 = a_texCoord1; + #endif + + // Pass the vertex color + #if defined(VERTEX_COLOR) + v_color = a_color; + #endif + + #if defined(CLIP_PLANE) + v_clipDistance = dot(u_worldMatrix * position, u_clipPlane); + #endif } diff --git a/examples/d3d/views/res/shaders/lighting.frag b/examples/d3d/views/res/shaders/lighting.frag new file mode 100644 index 00000000..aa07bb01 --- /dev/null +++ b/examples/d3d/views/res/shaders/lighting.frag @@ -0,0 +1,92 @@ + +vec3 computeLighting(vec3 normalVector, vec3 lightDirection, vec3 lightColor, float attenuation) +{ + float diffuse = max(dot(normalVector, lightDirection), 0.0); + vec3 diffuseColor = lightColor * _baseColor.rgb * diffuse * attenuation; + + #if defined(SPECULAR) + + // Phong shading + //vec3 vertexToEye = normalize(v_cameraDirection); + //vec3 specularAngle = normalize(normalVector * diffuse * 2.0 - lightDirection); + //vec3 specularColor = vec3(pow(clamp(dot(specularAngle, vertexToEye), 0.0, 1.0), u_specularExponent)); + + // Blinn-Phong shading + vec3 vertexToEye = normalize(v_cameraDirection); + vec3 halfVector = normalize(lightDirection + vertexToEye); + float specularAngle = clamp(dot(normalVector, halfVector), 0.0, 1.0); + vec3 specularColor = vec3(pow(specularAngle, u_specularExponent)) * attenuation; + + return diffuseColor + specularColor; + + #else + + return diffuseColor; + + #endif +} + +vec3 getLitPixel() +{ + #if defined(BUMPED) + + vec3 normalVector = normalize(texture2D(u_normalmapTexture, v_texCoord).rgb * 2.0 - 1.0); + + #else + + vec3 normalVector = normalize(v_normalVector); + + #endif + + vec3 ambientColor = _baseColor.rgb * u_ambientColor; + vec3 combinedColor = ambientColor; + + // Directional light contribution + #if (DIRECTIONAL_LIGHT_COUNT > 0) + for (int i = 0; i < DIRECTIONAL_LIGHT_COUNT; ++i) + { + #if defined(BUMPED) + vec3 lightDirection = normalize(v_directionalLightDirection[i] * 2.0); + #else + vec3 lightDirection = normalize(u_directionalLightDirection[i] * 2.0); + #endif + combinedColor += computeLighting(normalVector, -lightDirection, u_directionalLightColor[i], 1.0); + } + #endif + + // Point light contribution + #if (POINT_LIGHT_COUNT > 0) + for (int i = 0; i < POINT_LIGHT_COUNT; ++i) + { + vec3 ldir = v_vertexToPointLightDirection[i] * u_pointLightRangeInverse[i]; + float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); + combinedColor += computeLighting(normalVector, normalize(v_vertexToPointLightDirection[i]), u_pointLightColor[i], attenuation); + } + #endif + + // Spot light contribution + #if (SPOT_LIGHT_COUNT > 0) + for (int i = 0; i < SPOT_LIGHT_COUNT; ++i) + { + // Compute range attenuation + vec3 ldir = v_vertexToSpotLightDirection[i] * u_spotLightRangeInverse[i]; + float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); + vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection[i]); + + #if defined(BUMPED) + vec3 spotLightDirection = normalize(v_spotLightDirection[i] * 2.0); + #else + vec3 spotLightDirection = normalize(u_spotLightDirection[i] * 2.0); + #endif + + // "-lightDirection" is used because light direction points in opposite direction to spot direction. + float spotCurrentAngleCos = dot(spotLightDirection, -vertexToSpotLightDirection); + + // Apply spot attenuation + attenuation *= smoothstep(u_spotLightOuterAngleCos[i], u_spotLightInnerAngleCos[i], spotCurrentAngleCos); + combinedColor += computeLighting(normalVector, vertexToSpotLightDirection, u_spotLightColor[i], attenuation); + } + #endif + + return combinedColor; +} diff --git a/examples/d3d/views/res/shaders/lighting.vert b/examples/d3d/views/res/shaders/lighting.vert new file mode 100644 index 00000000..965d4cdf --- /dev/null +++ b/examples/d3d/views/res/shaders/lighting.vert @@ -0,0 +1,67 @@ + +#if defined(BUMPED) +void applyLight(vec4 position, mat3 tangentSpaceTransformMatrix) +{ + #if (defined(SPECULAR) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0)) + vec4 positionWorldViewSpace = u_worldViewMatrix * position; + #endif + + #if (DIRECTIONAL_LIGHT_COUNT > 0) + for (int i = 0; i < DIRECTIONAL_LIGHT_COUNT; ++i) + { + // Transform light direction to tangent space + v_directionalLightDirection[i] = tangentSpaceTransformMatrix * u_directionalLightDirection[i]; + } + #endif + + #if (POINT_LIGHT_COUNT > 0) + for (int i = 0; i < POINT_LIGHT_COUNT; ++i) + { + // Compute the vertex to light direction, in tangent space + v_vertexToPointLightDirection[i] = tangentSpaceTransformMatrix * (u_pointLightPosition[i] - positionWorldViewSpace.xyz); + } + #endif + + #if (SPOT_LIGHT_COUNT > 0) + for (int i = 0; i < SPOT_LIGHT_COUNT; ++i) + { + // Compute the vertex to light direction, in tangent space + v_vertexToSpotLightDirection[i] = tangentSpaceTransformMatrix * (u_spotLightPosition[i] - positionWorldViewSpace.xyz); + v_spotLightDirection[i] = tangentSpaceTransformMatrix * u_spotLightDirection[i]; + } + #endif + + #if defined(SPECULAR) + // Compute camera direction and transform it to tangent space. + v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz); + #endif +} +#else +void applyLight(vec4 position) +{ + #if defined(SPECULAR) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) + vec4 positionWorldViewSpace = u_worldViewMatrix * position; + #endif + + #if (POINT_LIGHT_COUNT > 0) + for (int i = 0; i < POINT_LIGHT_COUNT; ++i) + { + // Compute the light direction with light position and the vertex position. + v_vertexToPointLightDirection[i] = u_pointLightPosition[i] - positionWorldViewSpace.xyz; + } + #endif + + #if (SPOT_LIGHT_COUNT > 0) + for (int i = 0; i < SPOT_LIGHT_COUNT; ++i) + { + // Compute the light direction with light position and the vertex position. + v_vertexToSpotLightDirection[i] = u_spotLightPosition[i] - positionWorldViewSpace.xyz; + } + #endif + + #if defined(SPECULAR) + v_cameraDirection = u_cameraPosition - positionWorldViewSpace.xyz; + #endif +} + +#endif diff --git a/examples/d3d/views/res/shaders/skinning-none.vert b/examples/d3d/views/res/shaders/skinning-none.vert new file mode 100644 index 00000000..4f10127d --- /dev/null +++ b/examples/d3d/views/res/shaders/skinning-none.vert @@ -0,0 +1,25 @@ +vec4 getPosition() +{ + return a_position; +} + +#if defined(LIGHTING) + +vec3 getNormal() +{ + return a_normal; +} + +#if defined(BUMPED) +vec3 getTangent() +{ + return a_tangent; +} + +vec3 getBinormal() +{ + return a_binormal; +} +#endif + +#endif \ No newline at end of file diff --git a/examples/d3d/views/res/shaders/skinning.vert b/examples/d3d/views/res/shaders/skinning.vert new file mode 100644 index 00000000..df536e5d --- /dev/null +++ b/examples/d3d/views/res/shaders/skinning.vert @@ -0,0 +1,84 @@ + +vec4 _skinnedPosition; + +void skinPosition(float blendWeight, int matrixIndex) +{ + vec4 tmp; + tmp.x = dot(a_position, u_matrixPalette[matrixIndex]); + tmp.y = dot(a_position, u_matrixPalette[matrixIndex + 1]); + tmp.z = dot(a_position, u_matrixPalette[matrixIndex + 2]); + tmp.w = a_position.w; + _skinnedPosition += blendWeight * tmp; +} + +vec4 getPosition() +{ + _skinnedPosition = vec4(0.0); + float blendWeight = a_blendWeights[0]; + int matrixIndex = int (a_blendIndices[0]) * 3; + skinPosition(blendWeight, matrixIndex); + blendWeight = a_blendWeights[1]; + matrixIndex = int(a_blendIndices[1]) * 3; + skinPosition(blendWeight, matrixIndex); + blendWeight = a_blendWeights[2]; + matrixIndex = int(a_blendIndices[2]) * 3; + skinPosition(blendWeight, matrixIndex); + blendWeight = a_blendWeights[3]; + matrixIndex = int(a_blendIndices[3]) * 3; + skinPosition(blendWeight, matrixIndex); + return _skinnedPosition; +} + +#if defined(LIGHTING) + +vec3 _skinnedNormal; + +void skinTangentSpaceVector(vec3 vector, float blendWeight, int matrixIndex) +{ + vec3 tmp; + tmp.x = dot(vector, u_matrixPalette[matrixIndex].xyz); + tmp.y = dot(vector, u_matrixPalette[matrixIndex + 1].xyz); + tmp.z = dot(vector, u_matrixPalette[matrixIndex + 2].xyz); + _skinnedNormal += blendWeight * tmp; +} + +vec3 getTangentSpaceVector(vec3 vector) +{ + _skinnedNormal = vec3(0.0); + // Transform normal to view space using matrix palette with four matrices used to transform a vertex. + float blendWeight = a_blendWeights[0]; + int matrixIndex = int (a_blendIndices[0]) * 3; + skinTangentSpaceVector(vector, blendWeight, matrixIndex); + blendWeight = a_blendWeights[1]; + matrixIndex = int(a_blendIndices[1]) * 3; + skinTangentSpaceVector(vector, blendWeight, matrixIndex); + blendWeight = a_blendWeights[2]; + matrixIndex = int(a_blendIndices[2]) * 3; + skinTangentSpaceVector(vector, blendWeight, matrixIndex); + blendWeight = a_blendWeights[3]; + matrixIndex = int(a_blendIndices[3]) * 3; + skinTangentSpaceVector(vector, blendWeight, matrixIndex); + return _skinnedNormal; +} + +vec3 getNormal() +{ + return getTangentSpaceVector(a_normal); +} + +#if defined(BUMPED) + +vec3 getTangent() +{ + return getTangentSpaceVector(a_tangent); +} + +vec3 getBinormal() +{ + return getTangentSpaceVector(a_binormal); +} + +#endif + +#endif + diff --git a/examples/d3d/views/res/shaders/textured.frag b/examples/d3d/views/res/shaders/textured.frag index 062696ae..cd137922 100644 --- a/examples/d3d/views/res/shaders/textured.frag +++ b/examples/d3d/views/res/shaders/textured.frag @@ -1,8 +1,155 @@ -uniform sampler2D tex; -in vec4 col; -in vec4 texc; -out vec4 outColor; -void main(void) +#ifdef OPENGL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + +#ifndef DIRECTIONAL_LIGHT_COUNT +#define DIRECTIONAL_LIGHT_COUNT 0 +#endif +#ifndef SPOT_LIGHT_COUNT +#define SPOT_LIGHT_COUNT 0 +#endif +#ifndef POINT_LIGHT_COUNT +#define POINT_LIGHT_COUNT 0 +#endif +#if (DIRECTIONAL_LIGHT_COUNT > 0) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) +#define LIGHTING +#endif + +/////////////////////////////////////////////////////////// +// Uniforms +uniform vec3 u_ambientColor; + +uniform sampler2D u_diffuseTexture; + +#if defined(LIGHTMAP) +uniform sampler2D u_lightmapTexture; +#endif + +#if defined(LIGHTING) + +#if defined(BUMPED) +uniform sampler2D u_normalmapTexture; +#endif + +#if (DIRECTIONAL_LIGHT_COUNT > 0) +uniform vec3 u_directionalLightColor[DIRECTIONAL_LIGHT_COUNT]; +#if !defined(BUMPED) +uniform vec3 u_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; +#endif +#endif + +#if (POINT_LIGHT_COUNT > 0) +uniform vec3 u_pointLightColor[POINT_LIGHT_COUNT]; +uniform vec3 u_pointLightPosition[POINT_LIGHT_COUNT]; +uniform float u_pointLightRangeInverse[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +uniform vec3 u_spotLightColor[SPOT_LIGHT_COUNT]; +uniform float u_spotLightRangeInverse[SPOT_LIGHT_COUNT]; +uniform float u_spotLightInnerAngleCos[SPOT_LIGHT_COUNT]; +uniform float u_spotLightOuterAngleCos[SPOT_LIGHT_COUNT]; +#if !defined(BUMPED) +uniform vec3 u_spotLightDirection[SPOT_LIGHT_COUNT]; +#endif +#endif + +#if defined(SPECULAR) +uniform float u_specularExponent; +#endif + +#endif + +#if defined(MODULATE_COLOR) +uniform vec4 u_modulateColor; +#endif + +#if defined(MODULATE_ALPHA) +uniform float u_modulateAlpha; +#endif + +/////////////////////////////////////////////////////////// +// Variables +vec4 _baseColor; + +/////////////////////////////////////////////////////////// +// Varyings +varying vec2 v_texCoord; + +#if defined(LIGHTMAP) +varying vec2 v_texCoord1; +#endif + +#if defined(LIGHTING) + +#if !defined(BUMPED) +varying vec3 v_normalVector; +#endif + +#if defined(BUMPED) && (DIRECTIONAL_LIGHT_COUNT > 0) +varying vec3 v_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; +#endif + +#if (POINT_LIGHT_COUNT > 0) +varying vec3 v_vertexToPointLightDirection[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +varying vec3 v_vertexToSpotLightDirection[SPOT_LIGHT_COUNT]; +#if defined(BUMPED) +varying vec3 v_spotLightDirection[SPOT_LIGHT_COUNT]; +#endif +#endif + +#if defined(SPECULAR) +varying vec3 v_cameraDirection; +#endif + +#include "lighting.frag" + +#endif + +#if defined(CLIP_PLANE) +varying float v_clipDistance; +#endif + + +void main() { - outColor = texture(tex, texc.st) * col; + #if defined(CLIP_PLANE) + if(v_clipDistance < 0.0) discard; + #endif + + _baseColor = texture2D(u_diffuseTexture, v_texCoord); + + gl_FragColor.a = _baseColor.a; + + #if defined(TEXTURE_DISCARD_ALPHA) + if (gl_FragColor.a < 0.5) + discard; + #endif + + #if defined(LIGHTING) + + gl_FragColor.rgb = getLitPixel(); + #else + gl_FragColor.rgb = _baseColor.rgb; + #endif + + #if defined(LIGHTMAP) + vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord1); + gl_FragColor.rgb *= lightColor.rgb; + #endif + + #if defined(MODULATE_COLOR) + gl_FragColor *= u_modulateColor; + #endif + + #if defined(MODULATE_ALPHA) + gl_FragColor.a *= u_modulateAlpha; + #endif } diff --git a/examples/d3d/views/res/shaders/textured.vert b/examples/d3d/views/res/shaders/textured.vert index 9fa0dad6..00d72c9c 100644 --- a/examples/d3d/views/res/shaders/textured.vert +++ b/examples/d3d/views/res/shaders/textured.vert @@ -1,12 +1,180 @@ -in vec4 vertex; -in vec4 colAttr; -in vec4 texCoord; -out vec4 col; -out vec4 texc; -uniform mat4 matrix; -void main(void) +#ifndef DIRECTIONAL_LIGHT_COUNT +#define DIRECTIONAL_LIGHT_COUNT 0 +#endif +#ifndef SPOT_LIGHT_COUNT +#define SPOT_LIGHT_COUNT 0 +#endif +#ifndef POINT_LIGHT_COUNT +#define POINT_LIGHT_COUNT 0 +#endif +#if (DIRECTIONAL_LIGHT_COUNT > 0) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) +#define LIGHTING +#endif + +/////////////////////////////////////////////////////////// +// Atributes +attribute vec4 a_position; + +#if defined(SKINNING) +attribute vec4 a_blendWeights; +attribute vec4 a_blendIndices; +#endif + +attribute vec2 a_texCoord; + +#if defined(LIGHTMAP) +attribute vec2 a_texCoord1; +#endif + +#if defined(LIGHTING) +attribute vec3 a_normal; + +#if defined(BUMPED) +attribute vec3 a_tangent; +attribute vec3 a_binormal; +#endif + +#endif + +/////////////////////////////////////////////////////////// +// Uniforms +uniform mat4 u_worldViewProjectionMatrix; +#if defined(SKINNING) +uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; +#endif + +#if defined(LIGHTING) +uniform mat4 u_inverseTransposeWorldViewMatrix; + +#if defined(SPECULAR) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) +uniform mat4 u_worldViewMatrix; +#endif + +#if defined(BUMPED) && (DIRECTIONAL_LIGHT_COUNT > 0) +uniform vec3 u_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; +#endif + +#if (POINT_LIGHT_COUNT > 0) +uniform vec3 u_pointLightPosition[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +uniform vec3 u_spotLightPosition[SPOT_LIGHT_COUNT]; +#if defined(BUMPED) +uniform vec3 u_spotLightDirection[SPOT_LIGHT_COUNT]; +#endif +#endif + +#if defined(SPECULAR) +uniform vec3 u_cameraPosition; +#endif + +#endif + +#if defined(TEXTURE_REPEAT) +uniform vec2 u_textureRepeat; +#endif + +#if defined(TEXTURE_OFFSET) +uniform vec2 u_textureOffset; +#endif + +#if defined(CLIP_PLANE) +uniform mat4 u_worldMatrix; +uniform vec4 u_clipPlane; +#endif + +/////////////////////////////////////////////////////////// +// Varyings +varying vec2 v_texCoord; + +#if defined(LIGHTMAP) +varying vec2 v_texCoord1; +#endif + +#if defined(LIGHTING) + +#if !defined(BUMPED) +varying vec3 v_normalVector; +#endif + +#if defined(BUMPED) && (DIRECTIONAL_LIGHT_COUNT > 0) +varying vec3 v_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; +#endif + +#if (POINT_LIGHT_COUNT > 0) +varying vec3 v_vertexToPointLightDirection[POINT_LIGHT_COUNT]; +#endif + +#if (SPOT_LIGHT_COUNT > 0) +varying vec3 v_vertexToSpotLightDirection[SPOT_LIGHT_COUNT]; +#if defined(BUMPED) +varying vec3 v_spotLightDirection[SPOT_LIGHT_COUNT]; +#endif +#endif + +#if defined(SPECULAR) +varying vec3 v_cameraDirection; +#endif + +#include "lighting.vert" + +#endif + +#if defined(SKINNING) +#include "skinning.vert" +#else +#include "skinning-none.vert" +#endif + +#if defined(CLIP_PLANE) +varying float v_clipDistance; +#endif + +void main() { - gl_Position = matrix * vertex; - col = colAttr; - texc = texCoord; + vec4 position = getPosition(); + gl_Position = u_worldViewProjectionMatrix * position; + + #if defined(LIGHTING) + vec3 normal = getNormal(); + // Transform the normal, tangent and binormals to view space. + mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz); + vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * normal); + + #if defined(BUMPED) + + vec3 tangent = getTangent(); + vec3 binormal = getBinormal(); + vec3 tangentVector = normalize(inverseTransposeWorldViewMatrix * tangent); + vec3 binormalVector = normalize(inverseTransposeWorldViewMatrix * binormal); + mat3 tangentSpaceTransformMatrix = mat3(tangentVector.x, binormalVector.x, normalVector.x, tangentVector.y, binormalVector.y, normalVector.y, tangentVector.z, binormalVector.z, normalVector.z); + applyLight(position, tangentSpaceTransformMatrix); + + #else + + v_normalVector = normalVector; + applyLight(position); + + #endif + + #endif + + v_texCoord = a_texCoord; + + #if defined(TEXTURE_REPEAT) + v_texCoord *= u_textureRepeat; + #endif + + #if defined(TEXTURE_OFFSET) + v_texCoord += u_textureOffset; + #endif + + #if defined(LIGHTMAP) + v_texCoord1 = a_texCoord1; + #endif + + #if defined(CLIP_PLANE) + v_clipDistance = dot(u_worldMatrix * position, u_clipPlane); + #endif } diff --git a/examples/d3d/views/resources.list b/examples/d3d/views/resources.list index ea3fbba9..cb29742c 100644 --- a/examples/d3d/views/resources.list +++ b/examples/d3d/views/resources.list @@ -7,5 +7,9 @@ res/mdpi/blocks.png res/models/suzanne.obj res/shaders/colored.vert res/shaders/colored.frag +res/shaders/lighting.vert +res/shaders/lighting.frag +res/shaders/skinning.vert +res/shaders/skinning-none.vert res/shaders/textured.vert res/shaders/textured.frag diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index a4252b45..19c84e16 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -117,7 +117,6 @@ string glerrorToString(in GLenum err) pure nothrow { } } - class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { @property abstract string vertexSource(); @property abstract string fragmentSource(); @@ -135,12 +134,10 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { if (glslversionInt < 150) code = replace(code, " texture(", " texture2D("); if (glslversionInt < 140) { - if(type == GL_VERTEX_SHADER) - { + if(type == GL_VERTEX_SHADER) { code = replace(code, "in ", "attribute "); code = replace(code, "out ", "varying "); - } else - { + } else { code = replace(code, "in ", "varying "); code = replace(code, "out vec4 outColor;", ""); code = replace(code, "outColor", "gl_FragColor"); @@ -217,7 +214,8 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { return false; } Log.d("Program linked successfully"); - + + initStandardLocations(); if (!initLocations()) { Log.e("some of locations were not found"); error = true; @@ -227,6 +225,16 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { return !error; } + + void initStandardLocations() { + for(DefaultUniform id = DefaultUniform.min; id <= DefaultUniform.max; id++) { + _uniformIdLocations[id] = getUniformLocation(to!string(id)); + } + for(DefaultAttribute id = DefaultAttribute.min; id <= DefaultAttribute.max; id++) { + _attribIdLocations[id] = getAttribLocation(to!string(id)); + } + } + /// override to init shader code locations abstract bool initLocations(); @@ -270,50 +278,80 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { protected int[string] _uniformLocations; protected int[string] _attribLocations; + protected int[DefaultUniform.max + 1] _uniformIdLocations; + protected int[DefaultAttribute.max + 1] _attribIdLocations; /// get location for vertex attribute override int getVertexElementLocation(VertexElementType type) { return VERTEX_ELEMENT_NOT_FOUND; } + + /// get uniform location from program by uniform id, returns -1 if location is not found + int getUniformLocation(DefaultUniform uniform) { + return _uniformIdLocations[uniform]; + } + /// get uniform location from program, returns -1 if location is not found int getUniformLocation(string variableName) { if (auto p = variableName in _uniformLocations) return *p; int res = checkgl!glGetUniformLocation(program, variableName.toStringz); - if (res == -1) - Log.e("glGetUniformLocation failed for " ~ variableName); + //if (res == -1) + // Log.e("glGetUniformLocation failed for " ~ variableName); _uniformLocations[variableName] = res; return res; } + /// get attribute location from program by uniform id, returns -1 if location is not found + int getAttribLocation(DefaultAttribute id) { + return _attribIdLocations[id]; + } + /// get attribute location from program, returns -1 if location is not found int getAttribLocation(string variableName) { if (auto p = variableName in _attribLocations) return *p; int res = checkgl!glGetAttribLocation(program, variableName.toStringz); - if (res == -1) - Log.e("glGetAttribLocation failed for " ~ variableName); + //if (res == -1) + // Log.e("glGetAttribLocation failed for " ~ variableName); _attribLocations[variableName] = res; return res; } - override void setUniform(string uniformName, mat4 matrix) { - checkgl!glUniformMatrix4fv(getUniformLocation(uniformName), 1, false, matrix.m.ptr); + override void setUniform(string uniformName, vec2 vec) { + checkgl!glUniform2fv(getUniformLocation(uniformName), 1, vec.vec.ptr); } - override void setUniform(string uniformName, vec2 vec) { - checkgl!glUniform2fv(getAttribLocation(uniformName), 1, vec.vec.ptr); + override void setUniform(DefaultUniform id, vec2 vec) { + checkgl!glUniform2fv(getUniformLocation(id), 1, vec.vec.ptr); } override void setUniform(string uniformName, vec3 vec) { - checkgl!glUniform3fv(getAttribLocation(uniformName), 1, vec.vec.ptr); + checkgl!glUniform3fv(getUniformLocation(uniformName), 1, vec.vec.ptr); + } + + override void setUniform(DefaultUniform id, vec3 vec) { + checkgl!glUniform3fv(getUniformLocation(id), 1, vec.vec.ptr); } override void setUniform(string uniformName, vec4 vec) { - checkgl!glUniform4fv(getAttribLocation(uniformName), 1, vec.vec.ptr); + checkgl!glUniform4fv(getUniformLocation(uniformName), 1, vec.vec.ptr); } + override void setUniform(DefaultUniform id, vec4 vec) { + checkgl!glUniform4fv(getUniformLocation(id), 1, vec.vec.ptr); + } + + override void setUniform(string uniformName, ref const(mat4) matrix) { + checkgl!glUniformMatrix4fv(getUniformLocation(uniformName), 1, false, matrix.m.ptr); + } + + override void setUniform(DefaultUniform id, ref const(mat4) matrix) { + checkgl!glUniformMatrix4fv(getUniformLocation(id), 1, false, matrix.m.ptr); + } + + /// draw mesh using this program (program should be bound by this time and all uniforms should be set) override void draw(Mesh mesh) { VertexBuffer vb = mesh.vertexBuffer; @@ -328,14 +366,14 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { class SolidFillProgram : GLProgram { @property override string vertexSource() { return q{ - in vec3 vertex_position; - in vec4 vertex_color; + in vec3 a_position; + in vec4 a_color; out vec4 col; - uniform mat4 matrix; + uniform mat4 u_worldViewProjectionMatrix; void main(void) { - gl_Position = matrix * vec4(vertex_position, 1); - col = vertex_color; + gl_Position = u_worldViewProjectionMatrix * vec4(a_position, 1); + col = a_color; } }; } @@ -355,9 +393,9 @@ class SolidFillProgram : GLProgram { protected GLint vertexLocation; protected GLint colAttrLocation; override bool initLocations() { - matrixLocation = getUniformLocation("matrix"); - vertexLocation = getAttribLocation("vertex_position"); - colAttrLocation = getAttribLocation("vertex_color"); + matrixLocation = getUniformLocation(DefaultUniform.u_worldViewProjectionMatrix); + vertexLocation = getAttribLocation(DefaultAttribute.a_position); + colAttrLocation = getAttribLocation(DefaultAttribute.a_color); return matrixLocation >= 0 && vertexLocation >= 0 && colAttrLocation >= 0; } /// get location for vertex attribute @@ -393,7 +431,8 @@ class SolidFillProgram : GLProgram { checkgl!glDisable(GL_CULL_FACE); checkgl!glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); bind(); - checkgl!glUniformMatrix4fv(matrixLocation, 1, false, glSupport.projectionMatrix.m.ptr); + setUniform(DefaultUniform.u_worldViewProjectionMatrix, glSupport.projectionMatrix); + //checkgl!glUniformMatrix4fv(matrixLocation, 1, false, glSupport.projectionMatrix.m.ptr); } bool execute(float[] vertices, float[] colors) { @@ -444,17 +483,17 @@ class LineProgram : SolidFillProgram { class TextureProgram : SolidFillProgram { @property override string vertexSource() { return q{ - in vec3 vertex_position; - in vec4 vertex_color; - in vec2 vertex_UV; + in vec3 a_position; + in vec4 a_color; + in vec2 a_texCoord; out vec4 col; out vec2 UV; - uniform mat4 matrix; + uniform mat4 u_worldViewProjectionMatrix; void main(void) { - gl_Position = matrix * vec4(vertex_position, 1); - col = vertex_color; - UV = vertex_UV; + gl_Position = u_worldViewProjectionMatrix * vec4(a_position, 1); + col = a_color; + UV = a_texCoord; } }; } @@ -474,7 +513,7 @@ class TextureProgram : SolidFillProgram { GLint texCoordLocation; override bool initLocations() { bool res = super.initLocations(); - texCoordLocation = getAttribLocation("vertex_UV"); + texCoordLocation = getAttribLocation(DefaultAttribute.a_texCoord); return res && texCoordLocation >= 0; } /// get location for vertex attribute diff --git a/src/dlangui/graphics/scene/effect.d b/src/dlangui/graphics/scene/effect.d index 7fdc0a03..a9a4247a 100644 --- a/src/dlangui/graphics/scene/effect.d +++ b/src/dlangui/graphics/scene/effect.d @@ -58,9 +58,37 @@ class Effect : GLProgram { } } + protected bool[string] _visitedIncludes; + protected void preProcessIncludes(ref char[] buf, string src) { + import std.string : strip, startsWith, endsWith; + import dlangui.graphics.resources : splitLines; + foreach(line; src.splitLines) { + string s = line.strip; + if (s.startsWith("#include ")) { + s = s[9 .. $].strip; // remove #include + if (s.startsWith("\"") && s.endsWith("\"")) { + s = s[1 .. $-1]; // remove "" + if (!(s in _visitedIncludes)) { // protect from duplicate include + _visitedIncludes[s] = true; // mark as included + string includedSrc = loadVertexSource(s); + preProcessIncludes(buf, includedSrc); + } + } + } else { + buf ~= line; + buf ~= "\n"; + } + } + } + protected string preProcessSource(string src) { - // prepend definitions - return _defText ~ src; + char[] buf; + buf.assumeSafeAppend; + // append definitions + buf ~= _defText; + // append source body + preProcessIncludes(buf, src); + return buf.dup; } protected string loadVertexSource(string resourceId) { @@ -85,36 +113,30 @@ class Effect : GLProgram { } @property override string vertexSource() { + _visitedIncludes = null; + _visitedIncludes[_id.vertexShaderName] = true; // mark as included return preProcessSource(loadVertexSource(_id.vertexShaderName)); } @property override string fragmentSource() { + _visitedIncludes = null; + _visitedIncludes[_id.fragmentShaderName] = true; // mark as included 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 + return getUniformLocation(DefaultUniform.u_worldViewProjectionMatrix) >= 0 && getAttribLocation(DefaultAttribute.a_position) >= 0; // && colAttrLocation >= 0 && texCoordLocation >= 0 } /// get location for vertex attribute override int getVertexElementLocation(VertexElementType type) { switch(type) with(VertexElementType) { case POSITION: - return vertexLocation; + return getAttribLocation(DefaultAttribute.a_position); case COLOR: - return colAttrLocation; + return getAttribLocation(DefaultAttribute.a_color); case TEXCOORD0: - return texCoordLocation; + return getAttribLocation(DefaultAttribute.a_texCoord); default: return super.getVertexElementLocation(type); } diff --git a/src/dlangui/graphics/scene/material.d b/src/dlangui/graphics/scene/material.d index f9c6e525..85ffe249 100644 --- a/src/dlangui/graphics/scene/material.d +++ b/src/dlangui/graphics/scene/material.d @@ -75,7 +75,7 @@ class Material : RefCountedObject { texture.texture.setSamplerParams(true); } // TODO: more uniforms - _effect.setUniform("matrix", node.projectionViewModelMatrix); + _effect.setUniform(DefaultUniform.u_worldViewProjectionMatrix, node.projectionViewModelMatrix); } void drawMesh(Mesh mesh) { diff --git a/src/dlangui/graphics/scene/mesh.d b/src/dlangui/graphics/scene/mesh.d index 0c10fb27..120223d3 100644 --- a/src/dlangui/graphics/scene/mesh.d +++ b/src/dlangui/graphics/scene/mesh.d @@ -13,7 +13,7 @@ abstract class GraphicsEffect : RefCountedObject { /// get location for vertex attribute int getVertexElementLocation(VertexElementType type); - void setUniform(string uniformName, mat4 matrix); + void setUniform(string uniformName, ref const(mat4) matrix); void setUniform(string uniformName, vec2 vec); @@ -21,9 +21,57 @@ abstract class GraphicsEffect : RefCountedObject { void setUniform(string uniformName, vec4 vec); + void setUniform(DefaultUniform id, ref const(mat4) matrix); + + void setUniform(DefaultUniform id, vec2 vec); + + void setUniform(DefaultUniform id, vec3 vec); + + void setUniform(DefaultUniform id, vec4 vec); + void draw(Mesh mesh); } +enum DefaultUniform : int { + u_ambientColor, // vec3 + u_diffuseColor, // vec4 + u_lightmapTexture, // sampler2D + u_directionalLightColor, //uniform vec3 u_directionalLightColor[DIRECTIONAL_LIGHT_COUNT]; + u_directionalLightDirection, //uniform vec3 u_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; + u_pointLightColor, //uniform vec3 u_pointLightColor[POINT_LIGHT_COUNT]; + u_pointLightPosition, //uniform vec3 u_pointLightPosition[POINT_LIGHT_COUNT]; + u_pointLightRangeInverse, //uniform float u_pointLightRangeInverse[POINT_LIGHT_COUNT]; + u_spotLightColor, //uniform vec3 u_spotLightColor[SPOT_LIGHT_COUNT]; + u_spotLightRangeInverse, //uniform float u_spotLightRangeInverse[SPOT_LIGHT_COUNT]; + u_spotLightInnerAngleCos, //uniform float u_spotLightInnerAngleCos[SPOT_LIGHT_COUNT]; + u_spotLightOuterAngleCos, //uniform float u_spotLightOuterAngleCos[SPOT_LIGHT_COUNT]; + u_spotLightDirection, //uniform vec3 u_spotLightDirection[SPOT_LIGHT_COUNT]; + u_specularExponent, //uniform float u_specularExponent; + u_modulateColor, //uniform vec4 u_modulateColor; + u_modulateAlpha, //uniform float u_modulateAlpha; + + u_worldViewProjectionMatrix, //uniform mat4 u_worldViewProjectionMatrix; + u_matrixPalette, //uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; + u_inverseTransposeWorldViewMatrix, //uniform mat4 u_inverseTransposeWorldViewMatrix; + u_worldViewMatrix, //uniform mat4 u_worldViewMatrix; + u_cameraPosition, //uniform vec3 u_cameraPosition; + u_worldMatrix, //uniform mat4 u_worldMatrix; + u_clipPlane, //uniform vec4 u_clipPlane; +} + +enum DefaultAttribute : int { + a_position, //attribute vec4 a_position; + + a_blendWeights, //attribute vec4 a_blendWeights; + a_blendIndices, //attribute vec4 a_blendIndices; + + a_texCoord, //attribute vec2 a_texCoord; + a_texCoord1, //attribute vec2 a_texCoord1; + a_normal, //attribute vec3 a_normal; + a_color, //attribute vec3 a_color; + a_tangent, //attribute vec3 a_tangent; + a_binormal, //attribute vec3 a_binormal; +} /// vertex element type enum VertexElementType : ubyte { diff --git a/src/dlangui/graphics/scene/node.d b/src/dlangui/graphics/scene/node.d index 5ce43dba..ce0f72f2 100644 --- a/src/dlangui/graphics/scene/node.d +++ b/src/dlangui/graphics/scene/node.d @@ -97,8 +97,10 @@ class Node3d : Transform { return this; } + protected mat4 _projectionViewModelMatrix; /// returns projectionMatrix * viewMatrix * modelMatrix - @property mat4 projectionViewModelMatrix() { - return _scene.projectionViewMatrix * matrix; + @property ref const(mat4) projectionViewModelMatrix() { + _projectionViewModelMatrix = _scene.projectionViewMatrix * matrix; + return _projectionViewModelMatrix; } }