#183 OpenGL shaders code refactoring; compatibility with GamePlay SDK

This commit is contained in:
Vadim Lopatin 2016-04-04 11:04:22 +03:00
parent f9e50f6bcb
commit b01f90c7c2
15 changed files with 1057 additions and 82 deletions

View File

@ -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));

View File

@ -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
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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;
}
}