intermediate commit. Kinda works with reloading both modules

master
Martin Felis 2016-10-21 22:07:23 +02:00
parent 5748f1a944
commit 65a2767c02
37 changed files with 1850 additions and 1130 deletions

BIN
data/textures/bark1.dds Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/textures/flare.dds Normal file

Binary file not shown.

BIN
data/textures/kyoto_irr.dds Normal file

Binary file not shown.

BIN
data/textures/kyoto_lod.dds Normal file

Binary file not shown.

BIN
data/textures/leafs1.dds Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/textures/uffizi.dds Normal file

Binary file not shown.

View File

@ -0,0 +1,386 @@
/*
* Copyright 2011-2016 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#ifndef __SHADERLIB_SH__
#define __SHADERLIB_SH__
vec4 encodeRE8(float _r)
{
float exponent = ceil(log2(_r) );
return vec4(_r / exp2(exponent)
, 0.0
, 0.0
, (exponent + 128.0) / 255.0
);
}
float decodeRE8(vec4 _re8)
{
float exponent = _re8.w * 255.0 - 128.0;
return _re8.x * exp2(exponent);
}
vec4 encodeRGBE8(vec3 _rgb)
{
vec4 rgbe8;
float maxComponent = max(max(_rgb.x, _rgb.y), _rgb.z);
float exponent = ceil(log2(maxComponent) );
rgbe8.xyz = _rgb / exp2(exponent);
rgbe8.w = (exponent + 128.0) / 255.0;
return rgbe8;
}
vec3 decodeRGBE8(vec4 _rgbe8)
{
float exponent = _rgbe8.w * 255.0 - 128.0;
vec3 rgb = _rgbe8.xyz * exp2(exponent);
return rgb;
}
vec3 encodeNormalUint(vec3 _normal)
{
return _normal * 0.5 + 0.5;
}
vec3 decodeNormalUint(vec3 _encodedNormal)
{
return _encodedNormal * 2.0 - 1.0;
}
vec2 encodeNormalSphereMap(vec3 _normal)
{
return normalize(_normal.xy) * sqrt(_normal.z * 0.5 + 0.5);
}
vec3 decodeNormalSphereMap(vec2 _encodedNormal)
{
float zz = dot(_encodedNormal, _encodedNormal) * 2.0 - 1.0;
return vec3(normalize(_encodedNormal.xy) * sqrt(1.0 - zz*zz), zz);
}
vec2 octahedronWrap(vec2 _val)
{
// Reference:
// Octahedron normal vector encoding
// http://kriscg.blogspot.com/2014/04/octahedron-normal-vector-encoding.html
return (1.0 - abs(_val.yx) )
* mix(vec2_splat(-1.0), vec2_splat(1.0), vec2(greaterThanEqual(_val.xy, vec2_splat(0.0) ) ) );
}
vec2 encodeNormalOctahedron(vec3 _normal)
{
_normal /= abs(_normal.x) + abs(_normal.y) + abs(_normal.z);
_normal.xy = _normal.z >= 0.0 ? _normal.xy : octahedronWrap(_normal.xy);
_normal.xy = _normal.xy * 0.5 + 0.5;
return _normal.xy;
}
vec3 decodeNormalOctahedron(vec2 _encodedNormal)
{
_encodedNormal = _encodedNormal * 2.0 - 1.0;
vec3 normal;
normal.z = 1.0 - abs(_encodedNormal.x) - abs(_encodedNormal.y);
normal.xy = normal.z >= 0.0 ? _encodedNormal.xy : octahedronWrap(_encodedNormal.xy);
return normalize(normal);
}
vec3 convertRGB2XYZ(vec3 _rgb)
{
// Reference:
// RGB/XYZ Matrices
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
vec3 xyz;
xyz.x = dot(vec3(0.4124564, 0.3575761, 0.1804375), _rgb);
xyz.y = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb);
xyz.z = dot(vec3(0.0193339, 0.1191920, 0.9503041), _rgb);
return xyz;
}
vec3 convertXYZ2RGB(vec3 _xyz)
{
vec3 rgb;
rgb.x = dot(vec3( 3.2404542, -1.5371385, -0.4985314), _xyz);
rgb.y = dot(vec3(-0.9692660, 1.8760108, 0.0415560), _xyz);
rgb.z = dot(vec3( 0.0556434, -0.2040259, 1.0572252), _xyz);
return rgb;
}
vec3 convertXYZ2Yxy(vec3 _xyz)
{
// Reference:
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_xyY.html
float inv = 1.0/dot(_xyz, vec3(1.0, 1.0, 1.0) );
return vec3(_xyz.y, _xyz.x*inv, _xyz.y*inv);
}
vec3 convertYxy2XYZ(vec3 _Yxy)
{
// Reference:
// http://www.brucelindbloom.com/index.html?Eqn_xyY_to_XYZ.html
vec3 xyz;
xyz.x = _Yxy.x*_Yxy.y/_Yxy.z;
xyz.y = _Yxy.x;
xyz.z = _Yxy.x*(1.0 - _Yxy.y - _Yxy.z)/_Yxy.z;
return xyz;
}
vec3 convertRGB2Yxy(vec3 _rgb)
{
return convertXYZ2Yxy(convertRGB2XYZ(_rgb) );
}
vec3 convertYxy2RGB(vec3 _Yxy)
{
return convertXYZ2RGB(convertYxy2XYZ(_Yxy) );
}
vec3 convertRGB2Yuv(vec3 _rgb)
{
vec3 yuv;
yuv.x = dot(_rgb, vec3(0.299, 0.587, 0.114) );
yuv.y = (_rgb.x - yuv.x)*0.713 + 0.5;
yuv.z = (_rgb.z - yuv.x)*0.564 + 0.5;
return yuv;
}
vec3 convertYuv2RGB(vec3 _yuv)
{
vec3 rgb;
rgb.x = _yuv.x + 1.403*(_yuv.y-0.5);
rgb.y = _yuv.x - 0.344*(_yuv.y-0.5) - 0.714*(_yuv.z-0.5);
rgb.z = _yuv.x + 1.773*(_yuv.z-0.5);
return rgb;
}
vec3 convertRGB2YIQ(vec3 _rgb)
{
vec3 yiq;
yiq.x = dot(vec3(0.299, 0.587, 0.114 ), _rgb);
yiq.y = dot(vec3(0.595716, -0.274453, -0.321263), _rgb);
yiq.z = dot(vec3(0.211456, -0.522591, 0.311135), _rgb);
return yiq;
}
vec3 convertYIQ2RGB(vec3 _yiq)
{
vec3 rgb;
rgb.x = dot(vec3(1.0, 0.9563, 0.6210), _yiq);
rgb.y = dot(vec3(1.0, -0.2721, -0.6474), _yiq);
rgb.z = dot(vec3(1.0, -1.1070, 1.7046), _yiq);
return rgb;
}
vec3 toLinear(vec3 _rgb)
{
return pow(abs(_rgb), vec3_splat(2.2) );
}
vec4 toLinear(vec4 _rgba)
{
return vec4(toLinear(_rgba.xyz), _rgba.w);
}
vec3 toLinearAccurate(vec3 _rgb)
{
vec3 lo = _rgb / 12.92;
vec3 hi = pow( (_rgb + 0.055) / 1.055, vec3_splat(2.4) );
vec3 rgb = mix(hi, lo, vec3(lessThanEqual(_rgb, vec3_splat(0.04045) ) ) );
return rgb;
}
vec4 toLinearAccurate(vec4 _rgba)
{
return vec4(toLinearAccurate(_rgba.xyz), _rgba.w);
}
float toGamma(float _r)
{
return pow(abs(_r), 1.0/2.2);
}
vec3 toGamma(vec3 _rgb)
{
return pow(abs(_rgb), vec3_splat(1.0/2.2) );
}
vec4 toGamma(vec4 _rgba)
{
return vec4(toGamma(_rgba.xyz), _rgba.w);
}
vec3 toGammaAccurate(vec3 _rgb)
{
vec3 lo = _rgb * 12.92;
vec3 hi = pow(abs(_rgb), vec3_splat(1.0/2.4) ) * 1.055 - 0.055;
vec3 rgb = mix(hi, lo, vec3(lessThanEqual(_rgb, vec3_splat(0.0031308) ) ) );
return rgb;
}
vec4 toGammaAccurate(vec4 _rgba)
{
return vec4(toGammaAccurate(_rgba.xyz), _rgba.w);
}
vec3 toReinhard(vec3 _rgb)
{
return toGamma(_rgb/(_rgb+vec3_splat(1.0) ) );
}
vec4 toReinhard(vec4 _rgba)
{
return vec4(toReinhard(_rgba.xyz), _rgba.w);
}
vec3 toFilmic(vec3 _rgb)
{
_rgb = max(vec3_splat(0.0), _rgb - 0.004);
_rgb = (_rgb*(6.2*_rgb + 0.5) ) / (_rgb*(6.2*_rgb + 1.7) + 0.06);
return _rgb;
}
vec4 toFilmic(vec4 _rgba)
{
return vec4(toFilmic(_rgba.xyz), _rgba.w);
}
vec3 toAcesFilmic(vec3 _rgb)
{
// Reference:
// ACES Filmic Tone Mapping Curve
// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
float aa = 2.51f;
float bb = 0.03f;
float cc = 2.43f;
float dd = 0.59f;
float ee = 0.14f;
return saturate( (_rgb*(aa*_rgb + bb) )/(_rgb*(cc*_rgb + dd) + ee) );
}
vec4 toAcesFilmic(vec4 _rgba)
{
return vec4(toAcesFilmic(_rgba.xyz), _rgba.w);
}
vec3 luma(vec3 _rgb)
{
float yy = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb);
return vec3_splat(yy);
}
vec4 luma(vec4 _rgba)
{
return vec4(luma(_rgba.xyz), _rgba.w);
}
vec3 conSatBri(vec3 _rgb, vec3 _csb)
{
vec3 rgb = _rgb * _csb.z;
rgb = mix(luma(rgb), rgb, _csb.y);
rgb = mix(vec3_splat(0.5), rgb, _csb.x);
return rgb;
}
vec4 conSatBri(vec4 _rgba, vec3 _csb)
{
return vec4(conSatBri(_rgba.xyz, _csb), _rgba.w);
}
vec3 posterize(vec3 _rgb, float _numColors)
{
return floor(_rgb*_numColors) / _numColors;
}
vec4 posterize(vec4 _rgba, float _numColors)
{
return vec4(posterize(_rgba.xyz, _numColors), _rgba.w);
}
vec3 sepia(vec3 _rgb)
{
vec3 color;
color.x = dot(_rgb, vec3(0.393, 0.769, 0.189) );
color.y = dot(_rgb, vec3(0.349, 0.686, 0.168) );
color.z = dot(_rgb, vec3(0.272, 0.534, 0.131) );
return color;
}
vec4 sepia(vec4 _rgba)
{
return vec4(sepia(_rgba.xyz), _rgba.w);
}
vec3 blendOverlay(vec3 _base, vec3 _blend)
{
vec3 lt = 2.0 * _base * _blend;
vec3 gte = 1.0 - 2.0 * (1.0 - _base) * (1.0 - _blend);
return mix(lt, gte, step(vec3_splat(0.5), _base) );
}
vec4 blendOverlay(vec4 _base, vec4 _blend)
{
return vec4(blendOverlay(_base.xyz, _blend.xyz), _base.w);
}
vec3 adjustHue(vec3 _rgb, float _hue)
{
vec3 yiq = convertRGB2YIQ(_rgb);
float angle = _hue + atan2(yiq.z, yiq.y);
float len = length(yiq.yz);
return convertYIQ2RGB(vec3(yiq.x, len*cos(angle), len*sin(angle) ) );
}
vec4 packFloatToRgba(float _value)
{
const vec4 shift = vec4(256 * 256 * 256, 256 * 256, 256, 1.0);
const vec4 mask = vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 comp = fract(_value * shift);
comp -= comp.xxyz * mask;
return comp;
}
float unpackRgbaToFloat(vec4 _rgba)
{
const vec4 shift = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);
return dot(_rgba, shift);
}
vec2 packHalfFloat(float _value)
{
const vec2 shift = vec2(256, 1.0);
const vec2 mask = vec2(0, 1.0 / 256.0);
vec2 comp = fract(_value * shift);
comp -= comp.xx * mask;
return comp;
}
float unpackHalfFloat(vec2 _rg)
{
const vec2 shift = vec2(1.0 / 256.0, 1.0);
return dot(_rg, shift);
}
float random(vec2 _uv)
{
return fract(sin(dot(_uv.xy, vec2(12.9898, 78.233) ) ) * 43758.5453);
}
vec3 fixCubeLookup(vec3 _v, float _lod, float _topLevelCubeSize)
{
// Reference:
// Seamless cube-map filtering
// http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
float ax = abs(_v.x);
float ay = abs(_v.y);
float az = abs(_v.z);
float vmax = max(max(ax, ay), az);
float scale = 1.0 - exp2(_lod) / _topLevelCubeSize;
if (ax != vmax) { _v.x *= scale; }
if (ay != vmax) { _v.y *= scale; }
if (az != vmax) { _v.z *= scale; }
return _v;
}
#endif // __SHADERLIB_SH__

466
shaders/src/bgfx_shader.sh Normal file
View File

@ -0,0 +1,466 @@
/*
* Copyright 2011-2016 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#ifndef BGFX_SHADER_H_HEADER_GUARD
#define BGFX_SHADER_H_HEADER_GUARD
#if !defined(BGFX_CONFIG_MAX_BONES)
# define BGFX_CONFIG_MAX_BONES 32
#endif // !defined(BGFX_CONFIG_MAX_BONES)
#ifndef __cplusplus
#if BGFX_SHADER_LANGUAGE_HLSL > 3
# define BRANCH [branch]
# define LOOP [loop]
# define UNROLL [unroll]
#else
# define BRANCH
# define LOOP
# define UNROLL
#endif // BGFX_SHADER_LANGUAGE_HLSL > 3
#if BGFX_SHADER_LANGUAGE_HLSL > 3 && BGFX_SHADER_TYPE_FRAGMENT
# define EARLY_DEPTH_STENCIL [earlydepthstencil]
#else
# define EARLY_DEPTH_STENCIL
#endif // BGFX_SHADER_LANGUAGE_HLSL > 3 && BGFX_SHADER_TYPE_FRAGMENT
#if BGFX_SHADER_LANGUAGE_HLSL
# define CONST(_x) static const _x
# define dFdx(_x) ddx(_x)
# define dFdy(_y) ddy(-_y)
# define inversesqrt(_x) rsqrt(_x)
# define fract(_x) frac(_x)
# define bvec2 bool2
# define bvec3 bool3
# define bvec4 bool4
# if BGFX_SHADER_LANGUAGE_HLSL > 3
# if BGFX_SHADER_LANGUAGE_HLSL > 4
# define dFdxCoarse(_x) ddx_coarse(_x)
# define dFdxFine(_x) ddx_fine(_x)
# define dFdyCoarse(_y) ddy_coarse(-_y)
# define dFdyFine(_y) ddy_fine(-_y)
# endif // BGFX_SHADER_LANGUAGE_HLSL > 4
float intBitsToFloat(int _x) { return asfloat(_x); }
vec2 intBitsToFloat(uint2 _x) { return asfloat(_x); }
vec3 intBitsToFloat(uint3 _x) { return asfloat(_x); }
vec4 intBitsToFloat(uint4 _x) { return asfloat(_x); }
float uintBitsToFloat(uint _x) { return asfloat(_x); }
vec2 uintBitsToFloat(uint2 _x) { return asfloat(_x); }
vec3 uintBitsToFloat(uint3 _x) { return asfloat(_x); }
vec4 uintBitsToFloat(uint4 _x) { return asfloat(_x); }
uint floatBitsToUint(float _x) { return asuint(_x); }
uvec2 floatBitsToUint(vec2 _x) { return asuint(_x); }
uvec3 floatBitsToUint(vec3 _x) { return asuint(_x); }
uvec4 floatBitsToUint(vec4 _x) { return asuint(_x); }
int floatBitsToInt(float _x) { return asint(_x); }
ivec2 floatBitsToInt(vec2 _x) { return asint(_x); }
ivec3 floatBitsToInt(vec3 _x) { return asint(_x); }
ivec4 floatBitsToInt(vec4 _x) { return asint(_x); }
uint bitfieldReverse(uint _x) { return reversebits(_x); }
uint2 bitfieldReverse(uint2 _x) { return reversebits(_x); }
uint3 bitfieldReverse(uint3 _x) { return reversebits(_x); }
uint4 bitfieldReverse(uint4 _x) { return reversebits(_x); }
uint packHalf2x16(vec2 _x)
{
return (f32tof16(_x.x)<<16) | f32tof16(_x.y);
}
vec2 unpackHalf2x16(uint _x)
{
return vec2(f16tof32(_x >> 16), f16tof32(_x) );
}
struct BgfxSampler2D
{
SamplerState m_sampler;
Texture2D m_texture;
};
struct BgfxISampler2D
{
Texture2D<ivec4> m_texture;
};
struct BgfxUSampler2D
{
Texture2D<uvec4> m_texture;
};
struct BgfxSampler2DArray
{
SamplerState m_sampler;
Texture2DArray m_texture;
};
struct BgfxSampler2DShadow
{
SamplerComparisonState m_sampler;
Texture2D m_texture;
};
struct BgfxSampler3D
{
SamplerState m_sampler;
Texture3D m_texture;
};
struct BgfxISampler3D
{
Texture3D<ivec4> m_texture;
};
struct BgfxUSampler3D
{
Texture3D<uvec4> m_texture;
};
struct BgfxSamplerCube
{
SamplerState m_sampler;
TextureCube m_texture;
};
struct BgfxSampler2DMS
{
Texture2DMS<vec4> m_texture;
};
vec4 bgfxTexture2D(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture2DLod(BgfxSampler2D _sampler, vec2 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec3 _coord)
{
vec2 coord = _coord.xy * rcp(_coord.z);
return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
}
vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec4 _coord)
{
vec2 coord = _coord.xy * rcp(_coord.w);
return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
}
vec4 bgfxTexture2DArray(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture2DArrayLod(BgfxSampler2DArray _sampler, vec3 _coord, float _lod)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _lod);
}
float bgfxShadow2D(BgfxSampler2DShadow _sampler, vec3 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xy, _coord.z);
}
float bgfxShadow2DProj(BgfxSampler2DShadow _sampler, vec4 _coord)
{
vec3 coord = _coord.xyz * rcp(_coord.w);
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, coord.xy, coord.z);
}
vec4 bgfxTexture3D(BgfxSampler3D _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture3DLod(BgfxSampler3D _sampler, vec3 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
ivec4 bgfxTexture3D(BgfxISampler3D _sampler, vec3 _coord)
{
ivec3 size;
_sampler.m_texture.GetDimensions(size.x, size.y, size.z);
return _sampler.m_texture.Load(ivec4(_coord * size, 0) );
}
uvec4 bgfxTexture3D(BgfxUSampler3D _sampler, vec3 _coord)
{
uvec3 size;
_sampler.m_texture.GetDimensions(size.x, size.y, size.z);
return _sampler.m_texture.Load(uvec4(_coord * size, 0) );
}
vec4 bgfxTextureCube(BgfxSamplerCube _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
vec4 bgfxTexelFetch(BgfxSampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
ivec4 bgfxTexelFetch(BgfxISampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
uvec4 bgfxTexelFetch(BgfxUSampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
vec4 bgfxTexelFetch(BgfxSampler2DMS _sampler, ivec2 _coord, int _sampleIdx)
{
return _sampler.m_texture.Load(_coord, _sampleIdx);
}
vec4 bgfxTexelFetch(BgfxSampler3D _sampler, ivec3 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec4(_coord, _lod) );
}
# define SAMPLER2D(_name, _reg) \
uniform SamplerState _name ## Sampler : register(s[_reg]); \
uniform Texture2D _name ## Texture : register(t[_reg]); \
static BgfxSampler2D _name = { _name ## Sampler, _name ## Texture }
# define ISAMPLER2D(_name, _reg) \
uniform Texture2D<ivec4> _name ## Texture : register(t[_reg]); \
static BgfxISampler2D _name = { _name ## Texture }
# define USAMPLER2D(_name, _reg) \
uniform Texture2D<uvec4> _name ## Texture : register(t[_reg]); \
static BgfxUSampler2D _name = { _name ## Texture }
# define sampler2D BgfxSampler2D
# define texture2D(_sampler, _coord) bgfxTexture2D(_sampler, _coord)
# define texture2DLod(_sampler, _coord, _level) bgfxTexture2DLod(_sampler, _coord, _level)
# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
# define SAMPLER2DARRAY(_name, _reg) \
uniform SamplerState _name ## Sampler : register(s[_reg]); \
uniform Texture2DArray _name ## Texture : register(t[_reg]); \
static BgfxSampler2DArray _name = { _name ## Sampler, _name ## Texture }
# define sampler2DArray BgfxSampler2DArray
# define texture2DArray(_sampler, _coord) bgfxTexture2DArray(_sampler, _coord)
# define texture2DArrayLod(_sampler, _coord, _lod) bgfxTexture2DArrayLod(_sampler, _coord, _lod)
# define SAMPLER2DMS(_name, _reg) \
uniform Texture2DMS<vec4> _name ## Texture : register(t[_reg]); \
static BgfxSampler2DMS _name = { _name ## Texture }
# define sampler2DMS BgfxSampler2DMS
# define SAMPLER2DSHADOW(_name, _reg) \
uniform SamplerComparisonState _name ## Sampler : register(s[_reg]); \
uniform Texture2D _name ## Texture : register(t[_reg]); \
static BgfxSampler2DShadow _name = { _name ## Sampler, _name ## Texture }
# define sampler2DShadow BgfxSampler2DShadow
# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
# define SAMPLER3D(_name, _reg) \
uniform SamplerState _name ## Sampler : register(s[_reg]); \
uniform Texture3D _name ## Texture : register(t[_reg]); \
static BgfxSampler3D _name = { _name ## Sampler, _name ## Texture }
# define ISAMPLER3D(_name, _reg) \
uniform Texture3D<ivec4> _name ## Texture : register(t[_reg]); \
static BgfxISampler3D _name = { _name ## Texture }
# define USAMPLER3D(_name, _reg) \
uniform Texture3D<uvec4> _name ## Texture : register(t[_reg]); \
static BgfxUSampler3D _name = { _name ## Texture }
# define sampler3D BgfxSampler3D
# define texture3D(_sampler, _coord) bgfxTexture3D(_sampler, _coord)
# define texture3DLod(_sampler, _coord, _level) bgfxTexture3DLod(_sampler, _coord, _level)
# define SAMPLERCUBE(_name, _reg) \
uniform SamplerState _name ## Sampler : register(s[_reg]); \
uniform TextureCube _name ## Texture : register(t[_reg]); \
static BgfxSamplerCube _name = { _name ## Sampler, _name ## Texture }
# define samplerCube BgfxSamplerCube
# define textureCube(_sampler, _coord) bgfxTextureCube(_sampler, _coord)
# define textureCubeLod(_sampler, _coord, _level) bgfxTextureCubeLod(_sampler, _coord, _level)
# define texelFetch(_sampler, _coord, _lod) bgfxTexelFetch(_sampler, _coord, _lod)
# else
# define sampler2DShadow sampler2D
vec4 bgfxTexture2DProj(sampler2D _sampler, vec3 _coord)
{
return tex2Dproj(_sampler, vec4(_coord.xy, 0.0, _coord.z) );
}
vec4 bgfxTexture2DProj(sampler2D _sampler, vec4 _coord)
{
return tex2Dproj(_sampler, _coord);
}
float bgfxShadow2D(sampler2DShadow _sampler, vec3 _coord)
{
#if 0
float occluder = tex2D(_sampler, _coord.xy).x;
return step(_coord.z, occluder);
#else
return tex2Dproj(_sampler, vec4(_coord.xy, _coord.z, 1.0) ).x;
#endif // 0
}
float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord)
{
#if 0
vec3 coord = _coord.xyz * rcp(_coord.w);
float occluder = tex2D(_sampler, coord.xy).x;
return step(coord.z, occluder);
#else
return tex2Dproj(_sampler, _coord).x;
#endif // 0
}
# define SAMPLER2D(_name, _reg) uniform sampler2D _name : register(s ## _reg)
# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name : register(s ## _reg)
# define texture2D(_sampler, _coord) tex2D(_sampler, _coord)
# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name : register(s ## _reg)
# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
# define SAMPLER3D(_name, _reg) uniform sampler3D _name : register(s ## _reg)
# define texture3D(_sampler, _coord) tex3D(_sampler, _coord)
# define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : register(s[_reg])
# define textureCube(_sampler, _coord) texCUBE(_sampler, _coord)
# if BGFX_SHADER_LANGUAGE_HLSL == 2
# define texture2DLod(_sampler, _coord, _level) tex2D(_sampler, (_coord).xy)
# define texture3DLod(_sampler, _coord, _level) tex3D(_sampler, (_coord).xyz)
# define textureCubeLod(_sampler, _coord, _level) texCUBE(_sampler, (_coord).xyz)
# else
# define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) )
# define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) )
# define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) )
# endif // BGFX_SHADER_LANGUAGE_HLSL == 2
# endif // BGFX_SHADER_LANGUAGE_HLSL > 3
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); }
vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); }
vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_mtx, _vec); }
vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_vec, _mtx); }
bvec2 lessThan(vec2 _a, vec2 _b) { return _a < _b; }
bvec3 lessThan(vec3 _a, vec3 _b) { return _a < _b; }
bvec4 lessThan(vec4 _a, vec4 _b) { return _a < _b; }
bvec2 lessThanEqual(vec2 _a, vec2 _b) { return _a <= _b; }
bvec3 lessThanEqual(vec3 _a, vec3 _b) { return _a <= _b; }
bvec4 lessThanEqual(vec4 _a, vec4 _b) { return _a <= _b; }
bvec2 greaterThan(vec2 _a, vec2 _b) { return _a > _b; }
bvec3 greaterThan(vec3 _a, vec3 _b) { return _a > _b; }
bvec4 greaterThan(vec4 _a, vec4 _b) { return _a > _b; }
bvec2 greaterThanEqual(vec2 _a, vec2 _b) { return _a >= _b; }
bvec3 greaterThanEqual(vec3 _a, vec3 _b) { return _a >= _b; }
bvec4 greaterThanEqual(vec4 _a, vec4 _b) { return _a >= _b; }
bvec2 notEqual(vec2 _a, vec2 _b) { return _a != _b; }
bvec3 notEqual(vec3 _a, vec3 _b) { return _a != _b; }
bvec4 notEqual(vec4 _a, vec4 _b) { return _a != _b; }
bvec2 equal(vec2 _a, vec2 _b) { return _a == _b; }
bvec3 equal(vec3 _a, vec3 _b) { return _a == _b; }
bvec4 equal(vec4 _a, vec4 _b) { return _a == _b; }
float mix(float _a, float _b, float _t) { return lerp(_a, _b, _t); }
vec2 mix(vec2 _a, vec2 _b, vec2 _t) { return lerp(_a, _b, _t); }
vec3 mix(vec3 _a, vec3 _b, vec3 _t) { return lerp(_a, _b, _t); }
vec4 mix(vec4 _a, vec4 _b, vec4 _t) { return lerp(_a, _b, _t); }
float mod(float _a, float _b) { return _a - _b * floor(_a / _b); }
vec2 mod(vec2 _a, vec2 _b) { return _a - _b * floor(_a / _b); }
vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); }
vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
#else
# define CONST(_x) const _x
# define atan2(_x, _y) atan(_x, _y)
# define mul(_a, _b) ( (_a) * (_b) )
# define saturate(_x) clamp(_x, 0.0, 1.0)
# define SAMPLER2D(_name, _reg) uniform sampler2D _name
# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name
# define SAMPLER3D(_name, _reg) uniform sampler3D _name
# define SAMPLERCUBE(_name, _reg) uniform samplerCube _name
# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name
# define SAMPLER2DARRAY(_name, _reg) uniform sampler2DArray _name
# define SAMPLER2DMSARRAY(_name, _reg) uniform sampler2DMSArray _name
# define SAMPLERCUBEARRAY(_name, _reg) uniform samplerCubeArray _name
# define SAMPLER2DARRAYSHADOW(_name, _reg) uniform sampler2DArrayShadow _name
# if BGFX_SHADER_LANGUAGE_GLSL >= 130
# define ISAMPLER2D(_name, _reg) uniform isampler2D _name
# define USAMPLER2D(_name, _reg) uniform usampler2D _name
# define ISAMPLER3D(_name, _reg) uniform isampler3D _name
# define USAMPLER3D(_name, _reg) uniform usampler3D _name
# define texture2D(_sampler, _coord) texture(_sampler, _coord)
# define texture2DArray(_sampler, _coord) texture(_sampler, _coord)
# define texture3D(_sampler, _coord) texture(_sampler, _coord)
# endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }
vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_mtx, _vec); }
vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_vec, _mtx); }
vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_mtx, _vec); }
float rcp(float _a) { return 1.0/_a; }
vec2 rcp(vec2 _a) { return vec2(1.0)/_a; }
vec3 rcp(vec3 _a) { return vec3(1.0)/_a; }
vec4 rcp(vec4 _a) { return vec4(1.0)/_a; }
#endif // BGFX_SHADER_LANGUAGE_*
vec2 vec2_splat(float _x) { return vec2(_x, _x); }
vec3 vec3_splat(float _x) { return vec3(_x, _x, _x); }
vec4 vec4_splat(float _x) { return vec4(_x, _x, _x, _x); }
#if BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL
uvec2 uvec2_splat(uint _x) { return uvec2(_x, _x); }
uvec3 uvec3_splat(uint _x) { return uvec3(_x, _x, _x); }
uvec4 uvec4_splat(uint _x) { return uvec4(_x, _x, _x, _x); }
#endif // BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL
uniform vec4 u_viewRect;
uniform vec4 u_viewTexel;
uniform mat4 u_view;
uniform mat4 u_invView;
uniform mat4 u_proj;
uniform mat4 u_invProj;
uniform mat4 u_viewProj;
uniform mat4 u_invViewProj;
uniform mat4 u_model[BGFX_CONFIG_MAX_BONES];
uniform mat4 u_modelView;
uniform mat4 u_modelViewProj;
uniform vec4 u_alphaRef4;
#define u_alphaRef u_alphaRef4.x
#endif // __cplusplus
#endif // BGFX_SHADER_H_HEADER_GUARD

View File

@ -0,0 +1,33 @@
$input v_dir
/*
* Copyright 2014-2016 Dario Manesku. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "bgfx_shader.sh"
#include "shaderlib.sh"
#include "uniforms.sh"
SAMPLERCUBE(s_texCube, 0);
SAMPLERCUBE(s_texCubeIrr, 1);
void main()
{
vec3 dir = normalize(v_dir);
vec4 color;
if (u_bgType == 7.0)
{
color = toLinear(textureCube(s_texCubeIrr, dir));
}
else
{
float lod = u_bgType;
dir = fixCubeLookup(dir, lod, 256.0);
color = toLinear(textureCubeLod(s_texCube, dir, lod));
}
color *= exp2(u_exposure);
gl_FragColor = toFilmic(color);
}

386
shaders/src/shaderlib.sh Normal file
View File

@ -0,0 +1,386 @@
/*
* Copyright 2011-2016 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#ifndef __SHADERLIB_SH__
#define __SHADERLIB_SH__
vec4 encodeRE8(float _r)
{
float exponent = ceil(log2(_r) );
return vec4(_r / exp2(exponent)
, 0.0
, 0.0
, (exponent + 128.0) / 255.0
);
}
float decodeRE8(vec4 _re8)
{
float exponent = _re8.w * 255.0 - 128.0;
return _re8.x * exp2(exponent);
}
vec4 encodeRGBE8(vec3 _rgb)
{
vec4 rgbe8;
float maxComponent = max(max(_rgb.x, _rgb.y), _rgb.z);
float exponent = ceil(log2(maxComponent) );
rgbe8.xyz = _rgb / exp2(exponent);
rgbe8.w = (exponent + 128.0) / 255.0;
return rgbe8;
}
vec3 decodeRGBE8(vec4 _rgbe8)
{
float exponent = _rgbe8.w * 255.0 - 128.0;
vec3 rgb = _rgbe8.xyz * exp2(exponent);
return rgb;
}
vec3 encodeNormalUint(vec3 _normal)
{
return _normal * 0.5 + 0.5;
}
vec3 decodeNormalUint(vec3 _encodedNormal)
{
return _encodedNormal * 2.0 - 1.0;
}
vec2 encodeNormalSphereMap(vec3 _normal)
{
return normalize(_normal.xy) * sqrt(_normal.z * 0.5 + 0.5);
}
vec3 decodeNormalSphereMap(vec2 _encodedNormal)
{
float zz = dot(_encodedNormal, _encodedNormal) * 2.0 - 1.0;
return vec3(normalize(_encodedNormal.xy) * sqrt(1.0 - zz*zz), zz);
}
vec2 octahedronWrap(vec2 _val)
{
// Reference:
// Octahedron normal vector encoding
// http://kriscg.blogspot.com/2014/04/octahedron-normal-vector-encoding.html
return (1.0 - abs(_val.yx) )
* mix(vec2_splat(-1.0), vec2_splat(1.0), vec2(greaterThanEqual(_val.xy, vec2_splat(0.0) ) ) );
}
vec2 encodeNormalOctahedron(vec3 _normal)
{
_normal /= abs(_normal.x) + abs(_normal.y) + abs(_normal.z);
_normal.xy = _normal.z >= 0.0 ? _normal.xy : octahedronWrap(_normal.xy);
_normal.xy = _normal.xy * 0.5 + 0.5;
return _normal.xy;
}
vec3 decodeNormalOctahedron(vec2 _encodedNormal)
{
_encodedNormal = _encodedNormal * 2.0 - 1.0;
vec3 normal;
normal.z = 1.0 - abs(_encodedNormal.x) - abs(_encodedNormal.y);
normal.xy = normal.z >= 0.0 ? _encodedNormal.xy : octahedronWrap(_encodedNormal.xy);
return normalize(normal);
}
vec3 convertRGB2XYZ(vec3 _rgb)
{
// Reference:
// RGB/XYZ Matrices
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
vec3 xyz;
xyz.x = dot(vec3(0.4124564, 0.3575761, 0.1804375), _rgb);
xyz.y = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb);
xyz.z = dot(vec3(0.0193339, 0.1191920, 0.9503041), _rgb);
return xyz;
}
vec3 convertXYZ2RGB(vec3 _xyz)
{
vec3 rgb;
rgb.x = dot(vec3( 3.2404542, -1.5371385, -0.4985314), _xyz);
rgb.y = dot(vec3(-0.9692660, 1.8760108, 0.0415560), _xyz);
rgb.z = dot(vec3( 0.0556434, -0.2040259, 1.0572252), _xyz);
return rgb;
}
vec3 convertXYZ2Yxy(vec3 _xyz)
{
// Reference:
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_xyY.html
float inv = 1.0/dot(_xyz, vec3(1.0, 1.0, 1.0) );
return vec3(_xyz.y, _xyz.x*inv, _xyz.y*inv);
}
vec3 convertYxy2XYZ(vec3 _Yxy)
{
// Reference:
// http://www.brucelindbloom.com/index.html?Eqn_xyY_to_XYZ.html
vec3 xyz;
xyz.x = _Yxy.x*_Yxy.y/_Yxy.z;
xyz.y = _Yxy.x;
xyz.z = _Yxy.x*(1.0 - _Yxy.y - _Yxy.z)/_Yxy.z;
return xyz;
}
vec3 convertRGB2Yxy(vec3 _rgb)
{
return convertXYZ2Yxy(convertRGB2XYZ(_rgb) );
}
vec3 convertYxy2RGB(vec3 _Yxy)
{
return convertXYZ2RGB(convertYxy2XYZ(_Yxy) );
}
vec3 convertRGB2Yuv(vec3 _rgb)
{
vec3 yuv;
yuv.x = dot(_rgb, vec3(0.299, 0.587, 0.114) );
yuv.y = (_rgb.x - yuv.x)*0.713 + 0.5;
yuv.z = (_rgb.z - yuv.x)*0.564 + 0.5;
return yuv;
}
vec3 convertYuv2RGB(vec3 _yuv)
{
vec3 rgb;
rgb.x = _yuv.x + 1.403*(_yuv.y-0.5);
rgb.y = _yuv.x - 0.344*(_yuv.y-0.5) - 0.714*(_yuv.z-0.5);
rgb.z = _yuv.x + 1.773*(_yuv.z-0.5);
return rgb;
}
vec3 convertRGB2YIQ(vec3 _rgb)
{
vec3 yiq;
yiq.x = dot(vec3(0.299, 0.587, 0.114 ), _rgb);
yiq.y = dot(vec3(0.595716, -0.274453, -0.321263), _rgb);
yiq.z = dot(vec3(0.211456, -0.522591, 0.311135), _rgb);
return yiq;
}
vec3 convertYIQ2RGB(vec3 _yiq)
{
vec3 rgb;
rgb.x = dot(vec3(1.0, 0.9563, 0.6210), _yiq);
rgb.y = dot(vec3(1.0, -0.2721, -0.6474), _yiq);
rgb.z = dot(vec3(1.0, -1.1070, 1.7046), _yiq);
return rgb;
}
vec3 toLinear(vec3 _rgb)
{
return pow(abs(_rgb), vec3_splat(2.2) );
}
vec4 toLinear(vec4 _rgba)
{
return vec4(toLinear(_rgba.xyz), _rgba.w);
}
vec3 toLinearAccurate(vec3 _rgb)
{
vec3 lo = _rgb / 12.92;
vec3 hi = pow( (_rgb + 0.055) / 1.055, vec3_splat(2.4) );
vec3 rgb = mix(hi, lo, vec3(lessThanEqual(_rgb, vec3_splat(0.04045) ) ) );
return rgb;
}
vec4 toLinearAccurate(vec4 _rgba)
{
return vec4(toLinearAccurate(_rgba.xyz), _rgba.w);
}
float toGamma(float _r)
{
return pow(abs(_r), 1.0/2.2);
}
vec3 toGamma(vec3 _rgb)
{
return pow(abs(_rgb), vec3_splat(1.0/2.2) );
}
vec4 toGamma(vec4 _rgba)
{
return vec4(toGamma(_rgba.xyz), _rgba.w);
}
vec3 toGammaAccurate(vec3 _rgb)
{
vec3 lo = _rgb * 12.92;
vec3 hi = pow(abs(_rgb), vec3_splat(1.0/2.4) ) * 1.055 - 0.055;
vec3 rgb = mix(hi, lo, vec3(lessThanEqual(_rgb, vec3_splat(0.0031308) ) ) );
return rgb;
}
vec4 toGammaAccurate(vec4 _rgba)
{
return vec4(toGammaAccurate(_rgba.xyz), _rgba.w);
}
vec3 toReinhard(vec3 _rgb)
{
return toGamma(_rgb/(_rgb+vec3_splat(1.0) ) );
}
vec4 toReinhard(vec4 _rgba)
{
return vec4(toReinhard(_rgba.xyz), _rgba.w);
}
vec3 toFilmic(vec3 _rgb)
{
_rgb = max(vec3_splat(0.0), _rgb - 0.004);
_rgb = (_rgb*(6.2*_rgb + 0.5) ) / (_rgb*(6.2*_rgb + 1.7) + 0.06);
return _rgb;
}
vec4 toFilmic(vec4 _rgba)
{
return vec4(toFilmic(_rgba.xyz), _rgba.w);
}
vec3 toAcesFilmic(vec3 _rgb)
{
// Reference:
// ACES Filmic Tone Mapping Curve
// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
float aa = 2.51f;
float bb = 0.03f;
float cc = 2.43f;
float dd = 0.59f;
float ee = 0.14f;
return saturate( (_rgb*(aa*_rgb + bb) )/(_rgb*(cc*_rgb + dd) + ee) );
}
vec4 toAcesFilmic(vec4 _rgba)
{
return vec4(toAcesFilmic(_rgba.xyz), _rgba.w);
}
vec3 luma(vec3 _rgb)
{
float yy = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb);
return vec3_splat(yy);
}
vec4 luma(vec4 _rgba)
{
return vec4(luma(_rgba.xyz), _rgba.w);
}
vec3 conSatBri(vec3 _rgb, vec3 _csb)
{
vec3 rgb = _rgb * _csb.z;
rgb = mix(luma(rgb), rgb, _csb.y);
rgb = mix(vec3_splat(0.5), rgb, _csb.x);
return rgb;
}
vec4 conSatBri(vec4 _rgba, vec3 _csb)
{
return vec4(conSatBri(_rgba.xyz, _csb), _rgba.w);
}
vec3 posterize(vec3 _rgb, float _numColors)
{
return floor(_rgb*_numColors) / _numColors;
}
vec4 posterize(vec4 _rgba, float _numColors)
{
return vec4(posterize(_rgba.xyz, _numColors), _rgba.w);
}
vec3 sepia(vec3 _rgb)
{
vec3 color;
color.x = dot(_rgb, vec3(0.393, 0.769, 0.189) );
color.y = dot(_rgb, vec3(0.349, 0.686, 0.168) );
color.z = dot(_rgb, vec3(0.272, 0.534, 0.131) );
return color;
}
vec4 sepia(vec4 _rgba)
{
return vec4(sepia(_rgba.xyz), _rgba.w);
}
vec3 blendOverlay(vec3 _base, vec3 _blend)
{
vec3 lt = 2.0 * _base * _blend;
vec3 gte = 1.0 - 2.0 * (1.0 - _base) * (1.0 - _blend);
return mix(lt, gte, step(vec3_splat(0.5), _base) );
}
vec4 blendOverlay(vec4 _base, vec4 _blend)
{
return vec4(blendOverlay(_base.xyz, _blend.xyz), _base.w);
}
vec3 adjustHue(vec3 _rgb, float _hue)
{
vec3 yiq = convertRGB2YIQ(_rgb);
float angle = _hue + atan2(yiq.z, yiq.y);
float len = length(yiq.yz);
return convertYIQ2RGB(vec3(yiq.x, len*cos(angle), len*sin(angle) ) );
}
vec4 packFloatToRgba(float _value)
{
const vec4 shift = vec4(256 * 256 * 256, 256 * 256, 256, 1.0);
const vec4 mask = vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 comp = fract(_value * shift);
comp -= comp.xxyz * mask;
return comp;
}
float unpackRgbaToFloat(vec4 _rgba)
{
const vec4 shift = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);
return dot(_rgba, shift);
}
vec2 packHalfFloat(float _value)
{
const vec2 shift = vec2(256, 1.0);
const vec2 mask = vec2(0, 1.0 / 256.0);
vec2 comp = fract(_value * shift);
comp -= comp.xx * mask;
return comp;
}
float unpackHalfFloat(vec2 _rg)
{
const vec2 shift = vec2(1.0 / 256.0, 1.0);
return dot(_rg, shift);
}
float random(vec2 _uv)
{
return fract(sin(dot(_uv.xy, vec2(12.9898, 78.233) ) ) * 43758.5453);
}
vec3 fixCubeLookup(vec3 _v, float _lod, float _topLevelCubeSize)
{
// Reference:
// Seamless cube-map filtering
// http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
float ax = abs(_v.x);
float ay = abs(_v.y);
float az = abs(_v.z);
float vmax = max(max(ax, ay), az);
float scale = 1.0 - exp2(_lod) / _topLevelCubeSize;
if (ax != vmax) { _v.x *= scale; }
if (ay != vmax) { _v.y *= scale; }
if (az != vmax) { _v.z *= scale; }
return _v;
}
#endif // __SHADERLIB_SH__

28
shaders/src/uniforms.sh Normal file
View File

@ -0,0 +1,28 @@
/*
* Copyright 2016 Dario Manesku. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
uniform vec4 u_params[12];
#define u_mtx0 u_params[0]
#define u_mtx1 u_params[1]
#define u_mtx2 u_params[2]
#define u_mtx3 u_params[3]
#define u_glossiness u_params[4].x
#define u_reflectivity u_params[4].y
#define u_exposure u_params[4].z
#define u_bgType u_params[4].w
#define u_metalOrSpec u_params[5].x
#define u_unused u_params[5].yzw
#define u_doDiffuse u_params[6].x
#define u_doSpecular u_params[6].y
#define u_doDiffuseIbl u_params[6].z
#define u_doSpecularIbl u_params[6].w
#define u_camPos u_params[7].xyz
#define u_unused7 u_params[7].w
#define u_rgbDiff u_params[8]
#define u_rgbSpec u_params[9]
#define u_lightDir u_params[10].xyz
#define u_unused10 u_params[10].w
#define u_lightCol u_params[11].xyz
#define u_unused11 u_params[11].w

View File

@ -1,4 +1,5 @@
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 v_dir : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
vec3 v_view : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
vec4 v_shadowcoord : TEXCOORD2 = vec4(0.0, 0.0, 0.0, 0.0);
vec4 v_position : TEXCOORD3 = vec4(0.0, 0.0, 0.0, 0.0);

View File

@ -0,0 +1,29 @@
$input a_position, a_texcoord0
$output v_dir
/*
* Copyright 2014-2016 Dario Manesku. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "../common/common.sh"
#include "uniforms.sh"
uniform mat4 u_mtx;
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
float fov = radians(45.0);
float height = tan(fov*0.5);
float aspect = height*(u_viewRect.z / u_viewRect.w);
vec2 tex = (2.0*a_texcoord0-1.0) * vec2(aspect, height);
mat4 mtx;
mtx[0] = u_mtx0;
mtx[1] = u_mtx1;
mtx[2] = u_mtx2;
mtx[3] = u_mtx3;
v_dir = instMul(mtx, vec4(tex, 1.0, 0.0) ).xyz;
}

View File

@ -1,850 +0,0 @@
#include "Renderer.h"
#include <string>
#include <iostream>
#include <assert.h>
#include <bgfx/bgfxplatform.h>
#include <bx/thread.h>
#include <bx/timer.h>
#include <bx/fpumath.h>
#include <bx/uint32_t.h>
#include <dbg.h>
#include "imgui/imgui.h"
#define TINYOBJLOADER_IMPLEMENTATION
#include "tiny_obj_loader.h"
#include "math_types.h"
// BGFX globals
bgfx::VertexBufferHandle cube_vbh;
bgfx::IndexBufferHandle cube_ibh;
bgfx::IndexBufferHandle cube_edges_ibh;
bgfx::VertexBufferHandle plane_vbh;
bgfx::IndexBufferHandle plane_ibh;
bgfx::UniformHandle u_time;
bgfx::UniformHandle u_color;
int64_t m_timeOffset;
//
// Vertex packing utilities
//
uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w)
{
union
{
uint32_t ui32;
uint8_t arr[4];
} un;
un.arr[0] = _x;
un.arr[1] = _y;
un.arr[2] = _z;
un.arr[3] = _w;
return un.ui32;
}
uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f)
{
const uint8_t xx = uint8_t(_x*127.0f + 128.0f);
const uint8_t yy = uint8_t(_y*127.0f + 128.0f);
const uint8_t zz = uint8_t(_z*127.0f + 128.0f);
const uint8_t ww = uint8_t(_w*127.0f + 128.0f);
return packUint32(xx, yy, zz, ww);
}
//
// Render states
//
static RenderState s_renderStates[RenderState::Count] = {
{ // ShadowMap
0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
RenderState::ShadowMap
},
{ // Scene
0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
RenderState::Scene
},
{ // SceneTextured
0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
RenderState::SceneTextured
},
{ // Debug
0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_PT_LINES
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
RenderState::Debug
}
};
//
// Vertex formats
//
struct PosColorVertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_abgr;
static void init()
{
ms_decl
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
.end();
};
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosColorVertex::ms_decl;
struct PosNormalVertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_normal;
static void init()
{
ms_decl
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true)
.end();
}
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosNormalVertex::ms_decl;
struct PosNormalColorTexcoordVertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_normal;
uint32_t m_color;
float m_u;
float m_v;
static void init()
{
ms_decl
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true)
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float, false)
.end();
}
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosNormalColorTexcoordVertex::ms_decl;
//
// Static geometries
//
// Plane
static PosNormalColorTexcoordVertex s_hplaneVertices[] =
{
{ -1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), packF4u(1.0f, 1.0f, 1.0f), 0.f, 0.f },
{ 1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), packF4u(1.0f, 1.0f, 1.0f), 10.f, 0.f },
{ -1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), packF4u(1.0f, 1.0f, 1.0f), 0.f, 10.f},
{ 1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), packF4u(1.0f, 1.0f, 1.0f), 10.f, 10.f },
};
static const uint16_t s_planeIndices[] =
{
0, 1, 2,
1, 3, 2,
};
// Cube
static PosColorVertex s_cubeVertices[8] =
{
{-1.0f, 1.0f, 1.0f, 0xffffffff },
{ 1.0f, 1.0f, 1.0f, 0xffffffff },
{-1.0f, -1.0f, 1.0f, 0xffffffff },
{ 1.0f, -1.0f, 1.0f, 0xffffffff },
{-1.0f, 1.0f, -1.0f, 0xffffffff },
{ 1.0f, 1.0f, -1.0f, 0xffffffff },
{-1.0f, -1.0f, -1.0f, 0xffffffff },
{ 1.0f, -1.0f, -1.0f, 0xffffffff },
};
static const uint16_t s_cubeEdgeIndices[24] =
{
0, 1,
1, 3,
3, 2,
2, 0,
4, 5,
5, 7,
7, 6,
6, 4,
0, 4,
1, 5,
2, 6,
3, 7
};
static const uint16_t s_cubeIndices[36] =
{
0, 1, 2, // 0
1, 3, 2,
4, 6, 5, // 2
5, 6, 7,
0, 2, 4, // 4
4, 2, 6,
1, 5, 3, // 6
5, 7, 3,
0, 4, 1, // 8
4, 5, 1,
2, 3, 6, // 10
6, 3, 7,
};
bool flipV = false;
void Camera::updateMatrices() {
assert (width != -1.f && height != -1.f);
float aspect = width / height;
bx::mtxLookAt (mtxView, eye, poi, up);
if (orthographic) {
bx::mtxOrtho(mtxProj,
-width * 0.5f, width * 0.5f,
-height * 0.5f, height * 0.5f,
near, far);
} else {
bx::mtxProj(mtxProj, fov, aspect, near, far);
}
}
void Renderer::createGeometries() {
// Create vertex stream declaration.
PosColorVertex::init();
PosNormalVertex::init();
PosNormalColorTexcoordVertex::init();
// Create static vertex buffer.
cube_vbh = bgfx::createVertexBuffer(
// Static data can be passed with bgfx::makeRef
bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) )
, PosColorVertex::ms_decl
);
// Create static index buffer.
cube_ibh = bgfx::createIndexBuffer(
// Static data can be passed with bgfx::makeRef
bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) )
);
// Create static index buffer.
cube_edges_ibh = bgfx::createIndexBuffer(
// Static data can be passed with bgfx::makeRef
bgfx::makeRef(s_cubeEdgeIndices, sizeof(s_cubeEdgeIndices) )
);
plane_vbh = bgfx::createVertexBuffer(
bgfx::makeRef(s_hplaneVertices, sizeof(s_hplaneVertices) )
, PosNormalColorTexcoordVertex::ms_decl
);
plane_ibh = bgfx::createIndexBuffer(
bgfx::makeRef(s_planeIndices, sizeof(s_planeIndices) )
);
}
void Renderer::setupShaders() {
// Create uniforms
sceneDefaultTextureSampler = bgfx::createUniform("sceneDefaultTexture", bgfx::UniformType::Int1);
int grid_size = 1024;
int grid_border = 12;
uint8_t grid_color_border [4] = {255, 255, 255, 255};
uint8_t grid_color_0[4] = {192, 192, 192, 255};
uint8_t grid_color_1[4] = {96, 96, 96, 255};
uint8_t* texture_data = NULL;
texture_data = new uint8_t[grid_size * grid_size * 4];
for (int i = 0; i < grid_size; i++) {
for (int j = 0; j < grid_size; j++) {
uint8_t *texel = &texture_data[i * (grid_size * 4) + j * 4];
if ( (i < (grid_border / 2))
|| (i > grid_size - (grid_border / 2))
|| (j < (grid_border / 2))
|| (j > grid_size - (grid_border / 2)) ) {
memcpy (texel, grid_color_border, sizeof (uint8_t) * 4);
}
else {
if ( (i * 2) / grid_size + (j * 2) / grid_size == 1) {
memcpy (texel, grid_color_0, sizeof (uint8_t) * 4);
} else {
memcpy (texel, grid_color_1, sizeof (uint8_t) * 4);
}
}
}
}
sceneDefaultTexture = bgfx::createTexture2D(grid_size, grid_size, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_NONE, bgfx::copy (texture_data, grid_size * grid_size * 4));
delete[] texture_data;
// sceneDefaultTexture = bgfxutils::loadTexture("fieldstone-rgba.dds");
u_time = bgfx::createUniform("u_time", bgfx::UniformType::Vec4);
u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4);
m_timeOffset = bx::getHPCounter();
// Initialize light
lights[0].u_shadowMap = bgfx::createUniform("u_shadowMap", bgfx::UniformType::Int1);
lights[0].u_shadowMapParams = bgfx::createUniform("u_shadowMapParams", bgfx::UniformType::Vec4);
lights[0].u_lightPos = bgfx::createUniform("u_lightPos", bgfx::UniformType::Int1);
lights[0].u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Int1);
// Get renderer capabilities info.
const bgfx::Caps* caps = bgfx::getCaps();
// Shadow samplers are supported at least partially supported if texture
// compare less equal feature is supported.
bool shadowSamplerSupported = 0 != (caps->supported & BGFX_CAPS_TEXTURE_COMPARE_LEQUAL);
if (shadowSamplerSupported)
{
// Depth textures and shadow samplers are supported.
s_renderStates[RenderState::ShadowMap].m_program = bgfxutils::loadProgramFromFiles("shaders/src/vs_sms_mesh.sc", "shaders/src/fs_sms_shadow.sc");
s_renderStates[RenderState::Scene].m_program = bgfxutils::loadProgramFromFiles("shaders/src/vs_sms_mesh.sc", "shaders/src/fs_sms_mesh.sc");
s_renderStates[RenderState::SceneTextured].m_program = bgfxutils::loadProgramFromFiles("shaders/src/vs_sms_mesh_textured.sc", "shaders/src/fs_sms_mesh_textured.sc");
lights[0].shadowMapTexture= bgfx::createTexture2D(lights[0].shadowMapSize, lights[0].shadowMapSize, false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_COMPARE_LEQUAL);
bgfx::TextureHandle fbtextures[] = { lights[0].shadowMapTexture };
lights[0].shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
}
else
{
// Depth textures and shadow samplers are not supported. Use float
// depth packing into color buffer instead.
s_renderStates[RenderState::ShadowMap].m_program = bgfxutils::loadProgram("vs_sms_shadow_pd", "fs_sms_shadow_pd");
s_renderStates[RenderState::Scene].m_program = bgfxutils::loadProgram("vs_sms_mesh", "fs_sms_mesh_pd");
s_renderStates[RenderState::SceneTextured].m_program = bgfxutils::loadProgram("vs_sms_mesh_textured", "fs_sms_mesh_pd_textured");
lights[0].shadowMapTexture = bgfx::createTexture2D(lights[0].shadowMapSize, lights[0].shadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT);
bgfx::TextureHandle fbtextures[] =
{
lights[0].shadowMapTexture,
bgfx::createTexture2D(lights[0].shadowMapSize, lights[0].shadowMapSize, false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_WRITE_ONLY),
};
lights[0].shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
}
s_renderStates[RenderState::Debug].m_program = bgfxutils::loadProgramFromFiles("shaders/src/vs_debug.sc", "shaders/src/fs_debug.sc");
}
void Renderer::setupRenderPasses() {
// ShadowMap
s_renderStates[RenderState::ShadowMap].m_viewId = RenderState::ShadowMap;
// Scene
s_renderStates[RenderState::Scene].m_viewId = RenderState::Scene;
s_renderStates[RenderState::Scene].m_numTextures = 1;
// Scene: shadow map texture
s_renderStates[RenderState::Scene].m_textures[0].m_flags = UINT32_MAX;
s_renderStates[RenderState::Scene].m_textures[0].m_stage = 0;
s_renderStates[RenderState::Scene].m_textures[0].m_sampler = lights[0].u_shadowMap;
s_renderStates[RenderState::Scene].m_textures[0].m_texture = lights[0].shadowMapTexture;
// Scene: default texture
s_renderStates[RenderState::SceneTextured].m_viewId = RenderState::SceneTextured;
s_renderStates[RenderState::SceneTextured].m_numTextures = 2;
s_renderStates[RenderState::SceneTextured].m_textures[0].m_flags = UINT32_MAX;
s_renderStates[RenderState::SceneTextured].m_textures[0].m_stage = 0;
s_renderStates[RenderState::SceneTextured].m_textures[0].m_sampler = lights[0].u_shadowMap;
s_renderStates[RenderState::SceneTextured].m_textures[0].m_texture = lights[0].shadowMapTexture;
s_renderStates[RenderState::SceneTextured].m_textures[1].m_flags = UINT32_MAX;
s_renderStates[RenderState::SceneTextured].m_textures[1].m_stage = 1;
s_renderStates[RenderState::SceneTextured].m_textures[1].m_sampler = sceneDefaultTextureSampler;
s_renderStates[RenderState::SceneTextured].m_textures[1].m_texture = sceneDefaultTexture;
// Debug
s_renderStates[RenderState::Debug].m_viewId = RenderState::Debug;
}
// void Renderer::setupWindowX11 (Display* x11_display, int x11_window_id) {
// bgfx::x11SetDisplayWindow(x11_display, x11_window_id);
// }
class BGFXCallbacks: public bgfx::CallbackI {
virtual void fatal (bgfx::Fatal::Enum _code, const char *_str) {
std::cerr << "Fatal (" << _code << "): " << _str << std::endl;
}
virtual void traceVargs (const char *_filePath, uint16_t _line, const char* _format, va_list _argList) {
char output_buffer[255];
vsprintf (output_buffer, _format, _argList);
std::cerr << "Trace " << _filePath << ":" << _line << " : " << output_buffer;
}
virtual uint32_t cacheReadSize(uint64_t _id) {
return 0;
}
virtual bool cacheRead(uint64_t _id, void *_data, uint32_t _size) {
return false;
}
virtual void cacheWrite(uint64_t _id, const void *_data, uint32_t _size) {
}
virtual void screenShot(const char *_filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void *_data, uint32_t _size, bool _yflip) {
}
virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx::TextureFormat::Enum _format, bool _yflip) {
}
virtual void captureEnd() {
};
virtual void captureFrame(const void *_data, uint32_t _size) {
};
};
void Renderer::initialize(int width, int height) {
this->width = width;
this->height = height;
uint32_t debug = BGFX_DEBUG_TEXT;
uint32_t reset = BGFX_RESET_VSYNC;
reset = BGFX_RESET_VSYNC | BGFX_RESET_MAXANISOTROPY | BGFX_RESET_MSAA_X16;
bool result = bgfx::init();
if (!result) {
std::cerr << "Error: could not initialize renderer!" << std::endl;
exit (EXIT_FAILURE);
}
bgfx::reset(width, height, reset);
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
, 0x303030ff
, 1.0f
, 0
);
bgfx::setViewRect(0, 0, 0, width, height);
bgfx::RendererType::Enum renderer = bgfx::getRendererType();
flipV = false
|| renderer == bgfx::RendererType::OpenGL
|| renderer == bgfx::RendererType::OpenGLES
;
bgfx::setDebug(debug);
cameras.push_back (Camera());
activeCameraIndex = 0;
lights.push_back (Light());
// set the clear state
// for (int i = 0; i < 2; i++) {
// bgfx::setViewClear(i
// , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
// , 0x303030ff
// , 1.0f
// , 0
// );
// }
createGeometries();
setupShaders();
setupRenderPasses();
// imgui initialization.
imguiCreate();
// // Start the imgui frame such that widgets can be submitted
imguiBeginFrame (inputState.mouseX,
inputState.mouseY,
inputState.mouseButton,
inputState.mouseScroll,
width,
height);
initialized = true;
resize (width, height);
bgfx::frame();
}
void Renderer::shutdown() {
imguiDestroy();
bgfx::destroyFrameBuffer(lights[0].shadowMapFB);
bgfx::destroyUniform(lights[0].u_shadowMap);
bgfx::destroyUniform(lights[0].u_shadowMapParams);
bgfx::destroyUniform(lights[0].u_lightPos);
bgfx::destroyUniform(lights[0].u_lightMtx);
bgfx::destroyIndexBuffer(cube_ibh);
bgfx::destroyIndexBuffer(cube_edges_ibh);
bgfx::destroyVertexBuffer(cube_vbh);
bgfx::destroyIndexBuffer(plane_ibh);
bgfx::destroyVertexBuffer(plane_vbh);
bgfx::destroyUniform(u_time);
bgfx::destroyUniform(u_color);
for (size_t i = 0; i < entities.size(); i++) {
delete entities[i];
entities[i] = NULL;
}
for (size_t i = 0; i < meshes.size(); i++) {
bgfxutils::meshUnload(meshes[i]);
meshes[i] = NULL;
}
bgfx::shutdown();
}
void Renderer::resize (int width, int height) {
if (initialized) {
bgfx::reset (width, height);
this->width = width;
this->height = height;
for (uint32_t i = 0; i < cameras.size(); i++) {
cameras[i].width = static_cast<float>(width);
cameras[i].height = static_cast<float>(height);
}
}
}
void Renderer::paintGLSimple() {
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, width, height);
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
bgfx::touch(0);
int64_t now = bx::getHPCounter();
static int64_t last = now;
const int64_t frameTime = now - last;
last = now;
const double freq = double(bx::getHPFrequency() );
const double toMs = 1000.0/freq;
// Use debug font to print information about this example.
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/00-helloworld");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text.");
bgfx::dbgTextPrintf(0, 3, 0x8f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
bgfx::dbgTextClear();
}
void Renderer::paintGL() {
int64_t now = bx::getHPCounter();
static int64_t last = now;
const int64_t frameTime = now - last;
last = now;
const double freq = double(bx::getHPFrequency() );
const double toMs = 1000.0/freq;
float time = (float)( (now-m_timeOffset)/double(bx::getHPFrequency() ) );
bgfx::setUniform (u_time, &time);
// Use debug font to print information about this example.
bgfx::dbgTextClear();
bgfx::dbgTextPrintf(0, 0, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
// submit the imgui widgets
imguiEndFrame();
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
bgfx::touch(0);
// update camera matrices
for (uint32_t i = 0; i < cameras.size(); i++) {
cameras[i].updateMatrices();
}
// lights: update view and projection matrices and shadow map parameters
for (uint32_t i = 0; i < lights.size(); i++) {
bgfx::setUniform(lights[i].u_lightPos, lights[i].pos);
float shadow_map_params[4];
shadow_map_params[0] = static_cast<float>(lights[i].shadowMapSize);
shadow_map_params[1] = lights[0].shadowMapBias;
shadow_map_params[2] = 0.f;
shadow_map_params[3] = 0.f;
bgfx::setUniform(lights[i].u_shadowMapParams, &shadow_map_params);
float eye[3];
eye[0] = -lights[i].pos[0];
eye[1] = -lights[i].pos[1];
eye[2] = -lights[0].pos[2];
float at[3];
at[0] = - lights[i].pos[0] + lights[i].dir[0];
at[1] = - lights[i].pos[1] + lights[i].dir[1];
at[2] = - lights[i].pos[2] + lights[i].dir[2];
bx::mtxLookAt(lights[i].mtxView, eye, at);
lights[i].area = 2.5f;
lights[i].near = 0.f;
lights[i].far = 5.f;
// bx::mtxProj(lightProj, 20.0f, 1., 5.f, 10.0f);
bx::mtxOrtho(lights[i].mtxProj, -lights[i].area, lights[i].area, -lights[i].area, lights[i].area, lights[i].near, lights[i].far);
// lights: shadow matrix
const float sy = flipV ? 0.5f : -0.5f;
const float mtxCrop[16] =
{
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, sy, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f,
};
float mtxTmp[16];
bx::mtxMul(mtxTmp, lights[i].mtxProj, mtxCrop);
bx::mtxMul(lights[i].mtxShadow, lights[i].mtxView, mtxTmp);
}
// setup render passes
bgfx::setViewRect(RenderState::ShadowMap, 0, 0, lights[0].shadowMapSize, lights[0].shadowMapSize);
bgfx::setViewFrameBuffer(RenderState::ShadowMap, lights[0].shadowMapFB);
bgfx::setViewTransform(RenderState::ShadowMap, lights[0].mtxView, lights[0].mtxProj);
bgfx::setViewRect(RenderState::Scene, 0, 0, width, height);
bgfx::setViewTransform(RenderState::Scene, cameras[activeCameraIndex].mtxView, cameras[activeCameraIndex].mtxProj);
bgfx::setViewRect(RenderState::SceneTextured, 0, 0, width, height);
bgfx::setViewTransform(RenderState::SceneTextured, cameras[activeCameraIndex].mtxView, cameras[activeCameraIndex].mtxProj);
bgfx::setViewRect(RenderState::Debug, 0, 0, width, height);
bgfx::setViewTransform(RenderState::Debug, cameras[activeCameraIndex].mtxView, cameras[activeCameraIndex].mtxProj);
// setup floor
float mtxFloor[16];
bx::mtxSRT(mtxFloor
, 10.0f, 10.0f, 10.0f
, 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 0.0f
);
float lightMtx[16];
// Floor.
bx::mtxMul(lightMtx, mtxFloor, lights[0].mtxShadow);
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
// Clear backbuffer and shadowmap framebuffer at beginning.
bgfx::setViewClear(RenderState::ShadowMap
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x303030ff, 1.0f, 0
);
bgfx::setViewClear(RenderState::Scene
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x303030ff, 1.0f, 0
);
bgfx::touch(RenderState::Scene);
// render the plane
uint32_t cached = bgfx::setTransform(mtxFloor);
for (uint32_t pass = 0; pass < RenderState::Count; ++pass) {
// Only draw plane textured or during the shadow map passes
if (pass != RenderState::SceneTextured
&& pass != RenderState::ShadowMap)
continue;
const RenderState& st = s_renderStates[pass];
bgfx::setTransform(cached);
for (uint8_t tex = 0; tex < st.m_numTextures; ++tex)
{
const RenderState::Texture& texture = st.m_textures[tex];
bgfx::setTexture(texture.m_stage
, texture.m_sampler
, texture.m_texture
, texture.m_flags
);
}
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
bgfx::setUniform(u_color, Vector4f(1.f, 1.f, 1.f, 1.f).data(), 4);
bgfx::setIndexBuffer(plane_ibh);
bgfx::setVertexBuffer(plane_vbh);
bgfx::setState(st.m_state);
bgfx::submit(st.m_viewId, st.m_program);
}
// render entities
for (size_t i = 0; i < entities.size(); i++) {
// shadow map pass
bx::mtxMul(lightMtx, entities[i]->transform, lights[0].mtxShadow);
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
bgfx::setUniform(u_color, entities[i]->color, 4);
meshSubmit(entities[i]->mesh, &s_renderStates[RenderState::ShadowMap], 1, entities[i]->transform);
// scene pass
bx::mtxMul(lightMtx, entities[i]->transform, lights[0].mtxShadow);
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
bgfx::setUniform(u_color, entities[i]->color, 4);
meshSubmit(entities[i]->mesh, &s_renderStates[RenderState::Scene], 1, entities[i]->transform);
}
// render debug information
if (drawDebug) {
float tmp[16];
// render light frustums
for (uint32_t i = 0; i < lights.size(); i++) {
bx::mtxMul (tmp, lights[i].mtxView, lights[i].mtxProj);
float mtxLightViewProjInv[16];
bx::mtxInverse (mtxLightViewProjInv, tmp);
bgfx::setUniform(u_color, Vector4f(1.f, 1.f, 0.3f, 1.0f).data(), 4);
const RenderState& st = s_renderStates[RenderState::Debug];
bgfx::setTransform(mtxLightViewProjInv);
bgfx::setIndexBuffer(cube_edges_ibh);
bgfx::setVertexBuffer(cube_vbh);
bgfx::setState(st.m_state);
bgfx::submit(st.m_viewId, st.m_program);
}
// render camera frustums
for (uint32_t i = 0; i < cameras.size(); i++) {
bx::mtxMul (tmp, cameras[i].mtxView, cameras[i].mtxProj);
float mtxCameraViewProjInv[16];
bx::mtxInverse (mtxCameraViewProjInv, tmp);
bgfx::setUniform(u_color, Vector4f(0.5f, 0.5f, 0.8f, 1.f).data(), 4);
const RenderState& st = s_renderStates[RenderState::Debug];
bgfx::setTransform(mtxCameraViewProjInv);
bgfx::setIndexBuffer(cube_edges_ibh);
bgfx::setVertexBuffer(cube_vbh);
bgfx::setState(st.m_state);
bgfx::submit(st.m_viewId, st.m_program);
}
}
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
// Start the next imgui frame
imguiBeginFrame (inputState.mouseX,
inputState.mouseY,
inputState.mouseButton,
inputState.mouseScroll,
width,
height);
}
Entity* Renderer::createEntity() {
Entity* result = new Entity();
entities.push_back(result);
return result;
}
bgfxutils::Mesh* Renderer::loadMesh(const char* filename) {
MeshIdMap::iterator mesh_iter = meshIdMap.find (filename);
bgfxutils::Mesh* result = NULL;
if (mesh_iter == meshIdMap.end()) {
std::string filename_str (filename);
if (filename_str.substr(filename_str.size() - 4, 4) == ".obj") {
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
std::string err;
bool result = tinyobj::LoadObj(shapes, materials, err, filename);
if (!result) {
std::cerr << "Error loading '" << filename << "': " << err << std::endl;
exit(-1);
}
// result = bgfxutils::createMeshFromVBO (vbo);
} else {
result = bgfxutils::meshLoad(filename);
}
meshes.push_back (result);
meshIdMap[filename] = meshes.size() - 1;
} else {
result = meshes[mesh_iter->second];
}
return result;
}

View File

@ -1,218 +0,0 @@
#pragma once
#include <cstdint>
#include <map>
#include <vector>
#include <bgfx/bgfx.h>
#include "RenderUtils.h"
struct Entity;
struct InputState {
int32_t mousedX;
int32_t mousedY;
int32_t mouseX;
int32_t mouseY;
uint8_t mouseButton;
int32_t mouseScroll;
char key;
InputState() :
mouseX(0),
mouseY(0),
mouseButton(0),
mouseScroll(0),
key(0) {
}
};
struct Camera {
float eye[3];
float poi[3];
float up[3];
float near;
float far;
float fov;
bool orthographic;
float width;
float height;
float mtxProj[16];
float mtxView[16];
Camera() :
eye {5.f, 4.f, 5.f},
poi {0.f, 2.f, 0.f},
up {0.f, 1.f, 0.f},
near (1.f),
far (20.f),
fov (70.f),
orthographic (false),
width (-1.f),
height (-1.f),
mtxProj {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f},
mtxView {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f}
{}
void updateMatrices();
};
struct Light {
bgfx::UniformHandle u_shadowMap;
bgfx::UniformHandle u_shadowMapParams;
bgfx::UniformHandle u_lightPos;
bgfx::UniformHandle u_lightMtx;
bgfx::TextureHandle shadowMapTexture;
bgfx::FrameBufferHandle shadowMapFB;
float pos[3];
float dir[3];
float mtxView[16];
float mtxProj[16];
float mtxLight[16];
float mtxShadow[16];
float shadowMapBias;
uint16_t shadowMapSize;
bool enabled;
float near;
float far;
float area;
Light() :
u_shadowMap (BGFX_INVALID_HANDLE),
u_lightPos (BGFX_INVALID_HANDLE),
u_lightMtx (BGFX_INVALID_HANDLE),
shadowMapTexture (BGFX_INVALID_HANDLE),
shadowMapFB (BGFX_INVALID_HANDLE),
pos {1.f, 1.f, 1.f},
dir {-1.f, -1.f, -1.f},
mtxView {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f
},
mtxProj {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f
},
mtxShadow {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f
},
shadowMapBias (0.0001f),
shadowMapSize (1024),
near (-100.f),
far (100.f),
area (10.f),
enabled (false)
{
}
};
struct Entity {
float transform[16];
float color[4];
bgfxutils::Mesh* mesh;
Entity() :
transform {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.0, 0.f, 1.f
},
color { 1.f, 1.f, 1.f, 1.f },
mesh (NULL) {};
};
struct Renderer {
bool initialized;
bool drawDebug;
uint32_t width;
uint32_t height;
bgfx::UniformHandle sceneDefaultTextureSampler;
bgfx::TextureHandle sceneDefaultTexture;
std::vector<bgfxutils::Mesh*> meshes;
typedef std::map<std::string, unsigned int> MeshIdMap;
MeshIdMap meshIdMap;
std::vector<Entity*> entities;
std::vector<Camera> cameras;
std::vector<Light> lights;
uint16_t activeCameraIndex;
// needed to forward inputs to IMGUI
InputState inputState;
Renderer() :
initialized(false),
drawDebug(false),
width (0),
height (0)
{}
// initialize simple geometries (cube, sphere, ...)
void createGeometries();
// create uniforms, load shaders, and create render targets
void setupShaders();
// setup renderpasses and wire up render targets
void setupRenderPasses();
void initialize(int width, int height);
void shutdown();
void paintGL();
void paintGLSimple();
void resize (int width, int height);
Entity* createEntity();
bgfxutils::Mesh* loadMesh(const char* filename);
};
struct RenderState {
enum {
ShadowMap,
Scene,
SceneTextured,
Debug,
Count
};
struct Texture {
uint32_t m_flags;
bgfx::UniformHandle m_sampler;
bgfx::TextureHandle m_texture;
uint8_t m_stage;
};
uint64_t m_state;
uint8_t m_numTextures;
bgfx::ProgramHandle m_program;
uint8_t m_viewId;
Texture m_textures[4];
};

View File

@ -1,4 +1,5 @@
#include "RuntimeModuleManager.h"
#include <GLFW/glfw3.h>
#define _BSD_SOURCE // usleep()
#include <stdio.h>
@ -10,11 +11,14 @@
#include "RuntimeModule.h"
#include <iostream>
#include "Globals.h"
struct RuntimeModule {
std::string name = "";
void *handle = nullptr;
ino_t id = 0;
void *data = nullptr;
int mtime = 0;
struct module_api api;
struct module_state *state = nullptr;
@ -28,40 +32,64 @@ void RuntimeModuleManager::RegisterModule(const char* name) {
void RuntimeModuleManager::LoadModule(RuntimeModule* module) {
struct stat attr;
if ((stat(module->name.c_str(), &attr) == 0) && (module->id != attr.st_ino)) {
std::cerr << "Detected update of module " << module->name << std::endl;
if (module->handle) {
std::cerr << "Unloading module " << module->name << std::endl;
module->api.unload(module->state);
dlclose(module->handle);
}
std::cerr << "Opening module " << module->name << std::endl;
void *handle = dlopen(module->name.c_str(), RTLD_NOW);
bool stat_result = stat(module->name.c_str(), &attr);
if (glfwGetKey(gWindow, GLFW_KEY_F11) == GLFW_PRESS) {
std::cerr << "Module " << module->name << " id = " << module->id
<< " mtime " << ctime((time_t *) &module->mtime) << std::endl;
}
if ( stat_result == 0 &&
(module->id != attr.st_ino || module->mtime != attr.st_mtime)
) {
std::cout << "Opening module " << module->name << std::endl;
void *handle = dlopen(module->name.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (handle) {
module->handle = handle;
module->id = attr.st_ino;
module->mtime = attr.st_mtime;
const struct module_api *api = (module_api*) dlsym(module->handle, "MODULE_API");
if (api != NULL) {
module->api = *api;
if (module->state == NULL) {
std::cerr << "Initializing module" << std::endl;
std::cout << "Initializing module " << module->name << std::endl;
module->state = module->api.init();
}
std::cerr << "Reloading module " << module->name << std::endl;
std::cout << "Reloading module " << module->name << std::endl;
module->api.reload(module->state);
} else {
std::cerr << "Error: could not find API for module " << module->name << std::endl;
dlclose(module->handle);
module->handle = NULL;
module->id = 0;
}
} else {
std::cerr << "Error: could not load module " << module->name << std::endl;
std::cerr << dlerror() << std::endl;
module->handle = NULL;
module->id = 0;
abort();
}
}
}
void RuntimeModuleManager::Update(float dt) {
if (CheckModulesChanged()) {
std::cout << "Detected module update. Unloading all modules." << std::endl;
for (int i = 0; i < mModules.size(); i++) {
if (mModules[i]->handle) {
std::cerr << "Unloading module " << mModules[i]->name << std::endl;
mModules[i]->api.unload(mModules[i]->state);
dlclose(mModules[i]->handle);
mModules[i]->handle = 0;
mModules[i]->id = 0;
}
}
// We need to sleep to make sure we load the new files
usleep(150000);
}
for (int i = 0; i < mModules.size(); i++) {
LoadModule(mModules[i]);
if (mModules[i]->handle) {
@ -70,6 +98,23 @@ void RuntimeModuleManager::Update(float dt) {
}
}
bool RuntimeModuleManager::CheckModulesChanged() {
struct stat attr;
for (int i = 0; i < mModules.size(); i++) {
RuntimeModule* module = mModules[i];
bool stat_result = stat(module->name.c_str(), &attr);
if ( stat_result == 0 &&
(module->id != attr.st_ino || module->mtime != attr.st_mtime)
) {
return true;
}
}
return false;
}
void RuntimeModuleManager::UnloadModules() {
for (int i = 0; i < mModules.size(); i++) {
if (mModules[i]->handle) {
@ -83,4 +128,3 @@ void RuntimeModuleManager::UnloadModules() {
}
}

View File

@ -10,6 +10,7 @@ struct RuntimeModuleManager {
void RegisterModule(const char* name);
void LoadModule(RuntimeModule* module);
bool CheckModulesChanged();
void UnloadModules();
void Update(float dt);
};

View File

@ -90,10 +90,9 @@ int main(void)
printf("Initializing ModuleManager...\n");
RuntimeModuleManager module_manager;
module_manager.RegisterModule("src/modules/libTestModule.so");
module_manager.RegisterModule("src/modules/libRenderModule.so");
module_manager.RegisterModule("src/modules/libTestModule.so");
printf("Starting main loop...\n");
glfwSetKeyCallback(gWindow, key_callback);
int64_t time_offset = bx::getHPCounter();
@ -121,5 +120,3 @@ int main(void)
imguiDestroy();
bgfx::shutdown();
}
//! [code]

View File

@ -10,3 +10,7 @@ ADD_LIBRARY (RenderModule SHARED
ADD_LIBRARY (TestModule SHARED
TestModule.cc
)
TARGET_LINK_LIBRARIES ( TestModule
RenderModule
)

View File

@ -3,7 +3,12 @@
#include "RenderModule.h"
#include "3rdparty/ocornut-imgui/imgui.h"
#include "imgui/imgui.h"
#define GLFW_EXPOSE_NATIVE_GLX
#define GLFW_EXPOSE_NATIVE_X11
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include "SimpleMath/SimpleMath.h"
#include "SimpleMath/SimpleMathMap.h"
@ -15,6 +20,7 @@
#include <bx/timer.h>
#include <bx/fpumath.h>
#include <bx/uint32_t.h>
#include <bx/string.h>
#include <dbg.h>
#define TINYOBJLOADER_IMPLEMENTATION
@ -65,6 +71,7 @@ static void module_reload(struct module_state *state) {
int width, height;
glfwGetWindowSize(gWindow, &width, &height);
std::cout << "renderer initialize" << std::endl;
assert (state != nullptr);
state->renderer->initialize(width, height);
gRenderer = state->renderer;
@ -111,6 +118,127 @@ bgfx::VertexBufferHandle plane_vbh;
bgfx::IndexBufferHandle plane_ibh;
bgfx::UniformHandle u_time;
bgfx::UniformHandle u_color;
bgfx::UniformHandle u_mtx;
bgfx::UniformHandle u_exposure;
bgfx::UniformHandle u_flags;
bgfx::UniformHandle u_camPos;
bgfx::UniformHandle s_texCube;
bgfx::UniformHandle s_texCubeIrr;
namespace IBL {
struct Uniforms
{
enum { NumVec4 = 12 };
void init()
{
u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, NumVec4);
}
void submit()
{
bgfx::setUniform(u_params, m_params, NumVec4);
}
void destroy()
{
bgfx::destroyUniform(u_params);
}
union
{
struct
{
union
{
float m_mtx[16];
/* 0*/ struct { float m_mtx0[4]; };
/* 1*/ struct { float m_mtx1[4]; };
/* 2*/ struct { float m_mtx2[4]; };
/* 3*/ struct { float m_mtx3[4]; };
};
/* 4*/ struct { float m_glossiness, m_reflectivity, m_exposure, m_bgType; };
/* 5*/ struct { float m_metalOrSpec, m_unused5[3]; };
/* 6*/ struct { float m_doDiffuse, m_doSpecular, m_doDiffuseIbl, m_doSpecularIbl; };
/* 7*/ struct { float m_cameraPos[3], m_unused7[1]; };
/* 8*/ struct { float m_rgbDiff[4]; };
/* 9*/ struct { float m_rgbSpec[4]; };
/*10*/ struct { float m_lightDir[3], m_unused10[1]; };
/*11*/ struct { float m_lightCol[3], m_unused11[1]; };
};
float m_params[NumVec4*4];
};
bgfx::UniformHandle u_params;
};
struct Settings
{
Settings()
{
m_envRotCurr = 0.0f;
m_envRotDest = 0.0f;
m_lightDir[0] = -0.8f;
m_lightDir[1] = 0.2f;
m_lightDir[2] = -0.5f;
m_lightCol[0] = 1.0f;
m_lightCol[1] = 1.0f;
m_lightCol[2] = 1.0f;
m_glossiness = 0.7f;
m_exposure = 0.0f;
m_bgType = 3.0f;
m_radianceSlider = 2.0f;
m_reflectivity = 0.85f;
m_rgbDiff[0] = 1.0f;
m_rgbDiff[1] = 1.0f;
m_rgbDiff[2] = 1.0f;
m_rgbSpec[0] = 1.0f;
m_rgbSpec[1] = 1.0f;
m_rgbSpec[2] = 1.0f;
m_lod = 0.0f;
m_doDiffuse = false;
m_doSpecular = false;
m_doDiffuseIbl = true;
m_doSpecularIbl = true;
m_showLightColorWheel = true;
m_showDiffColorWheel = true;
m_showSpecColorWheel = true;
m_metalOrSpec = 0;
m_meshSelection = 0;
m_crossCubemapPreview = ImguiCubemap::Latlong;
}
float m_envRotCurr;
float m_envRotDest;
float m_lightDir[3];
float m_lightCol[3];
float m_glossiness;
float m_exposure;
float m_radianceSlider;
float m_bgType;
float m_reflectivity;
float m_rgbDiff[3];
float m_rgbSpec[3];
float m_lod;
bool m_doDiffuse;
bool m_doSpecular;
bool m_doDiffuseIbl;
bool m_doSpecularIbl;
bool m_showLightColorWheel;
bool m_showDiffColorWheel;
bool m_showSpecColorWheel;
uint8_t m_metalOrSpec;
uint8_t m_meshSelection;
ImguiCubemap::Enum m_crossCubemapPreview;
};
Settings settings;
Uniforms uniforms;
};
int64_t m_timeOffset;
//
@ -147,6 +275,18 @@ uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f)
//
RenderState s_renderStates[RenderState::Count] = {
{ // Skybox
0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA,
0,
bgfx::invalidHandle,
RenderState::Skybox
},
{ // ShadowMap
0
| BGFX_STATE_RGB_WRITE
@ -156,7 +296,7 @@ RenderState s_renderStates[RenderState::Count] = {
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
bgfx::invalidHandle,
RenderState::ShadowMap
},
{ // Scene
@ -168,7 +308,7 @@ RenderState s_renderStates[RenderState::Count] = {
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
bgfx::invalidHandle,
RenderState::Scene
},
{ // SceneTextured
@ -180,7 +320,7 @@ RenderState s_renderStates[RenderState::Count] = {
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
bgfx::invalidHandle,
RenderState::SceneTextured
},
{ // Debug
@ -193,7 +333,7 @@ RenderState s_renderStates[RenderState::Count] = {
| BGFX_STATE_PT_LINES
| BGFX_STATE_MSAA,
0,
UINT16_MAX,
bgfx::invalidHandle,
RenderState::Debug
}
};
@ -270,6 +410,30 @@ struct PosNormalColorTexcoordVertex
bgfx::VertexDecl PosNormalColorTexcoordVertex::ms_decl;
struct PosColorTexCoord0Vertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_rgba;
float m_u;
float m_v;
static void init()
{
ms_decl
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
.end();
}
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosColorTexCoord0Vertex::ms_decl;
//
// Static geometries
//
@ -336,23 +500,135 @@ const uint16_t s_cubeIndices[36] =
6, 3, 7,
};
bool flipV = false;
static float s_texelHalf = 0.0f;
void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBottomLeft = false, float _width = 1.0f, float _height = 1.0f)
{
if (bgfx::checkAvailTransientVertexBuffer(3, PosColorTexCoord0Vertex::ms_decl) )
{
bgfx::TransientVertexBuffer vb;
bgfx::allocTransientVertexBuffer(&vb, 3, PosColorTexCoord0Vertex::ms_decl);
PosColorTexCoord0Vertex* vertex = (PosColorTexCoord0Vertex*)vb.data;
const float zz = 0.0f;
const float minx = -_width;
const float maxx = _width;
const float miny = 0.0f;
const float maxy = _height*2.0f;
const float texelHalfW = s_texelHalf/_textureWidth;
const float texelHalfH = s_texelHalf/_textureHeight;
const float minu = -1.0f + texelHalfW;
const float maxu = 1.0f + texelHalfW;
float minv = texelHalfH;
float maxv = 2.0f + texelHalfH;
if (_originBottomLeft)
{
std::swap(minv, maxv);
minv -= 1.0f;
maxv -= 1.0f;
}
vertex[0].m_x = minx;
vertex[0].m_y = miny;
vertex[0].m_z = zz;
vertex[0].m_rgba = 0xffffffff;
vertex[0].m_u = minu;
vertex[0].m_v = minv;
vertex[1].m_x = maxx;
vertex[1].m_y = miny;
vertex[1].m_z = zz;
vertex[1].m_rgba = 0xffffffff;
vertex[1].m_u = maxu;
vertex[1].m_v = minv;
vertex[2].m_x = maxx;
vertex[2].m_y = maxy;
vertex[2].m_z = zz;
vertex[2].m_rgba = 0xffffffff;
vertex[2].m_u = maxu;
vertex[2].m_v = maxv;
bgfx::setVertexBuffer(&vb);
}
}
void Camera::updateMatrices() {
assert (width != -1.f && height != -1.f);
float aspect = width / height;
// view matrix
bx::mtxLookAt (mtxView, eye, poi, up);
// projection matrix
if (orthographic) {
bx::mtxOrtho(mtxProj,
-width * 0.5f, width * 0.5f,
-height * 0.5f, height * 0.5f,
near, far);
} else {
float aspect = width / height;
bx::mtxProj(mtxProj, fov, aspect, near, far);
}
// environment matrix
const float dir[3] =
{
poi[0] - eye[0],
poi[1] - eye[1],
poi[2] - eye[2]
};
const float dirLen = bx::vec3Length(dir);
const float invDirLen = 1.0f / (dirLen + FLT_MIN);
const float dirNorm[3] =
{
dir[0] * invDirLen,
dir[1] * invDirLen,
dir[2] * invDirLen
};
float tmp[3];
const float fakeUp[3] = { 0.0f, 1.0f, 0.0f };
float right[3];
bx::vec3Cross (tmp, fakeUp, dirNorm);
bx::vec3Norm(right, tmp);
float up[3];
bx::vec3Cross(tmp, dirNorm, right);
bx::vec3Norm(up, tmp);
mtxEnv[ 0] = right[0];
mtxEnv[ 1] = right[1];
mtxEnv[ 2] = right[2];
mtxEnv[ 3] = 0.0f;
mtxEnv[ 4] = up[0];
mtxEnv[ 5] = up[1];
mtxEnv[ 6] = up[2];
mtxEnv[ 7] = 0.0f;
mtxEnv[ 8] = dirNorm[0];
mtxEnv[ 9] = dirNorm[1];
mtxEnv[10] = dirNorm[2];
mtxEnv[11] = 0.0f;
mtxEnv[12] = 0.0f;
mtxEnv[13] = 0.0f;
mtxEnv[14] = 0.0f;
mtxEnv[15] = 1.0f;
}
void LightProbe::load(const char* _name) {
char filePath[512];
bx::snprintf(filePath, BX_COUNTOF(filePath), "data/textures/%s_lod.dds", _name);
m_tex = bgfxutils::loadTexture(filePath, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP);
bx::snprintf(filePath, BX_COUNTOF(filePath), "data/textures/%s_irr.dds", _name);
m_texIrr = bgfxutils::loadTexture(filePath, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP);
}
void Renderer::createGeometries() {
@ -360,6 +636,7 @@ void Renderer::createGeometries() {
PosColorVertex::init();
PosNormalVertex::init();
PosNormalColorTexcoordVertex::init();
PosColorTexCoord0Vertex::init();
// Create static vertex buffer.
cube_vbh = bgfx::createVertexBuffer(
@ -393,6 +670,11 @@ void Renderer::createGeometries() {
void Renderer::setupShaders() {
// Create uniforms
sceneDefaultTextureSampler = bgfx::createUniform("sceneDefaultTexture", bgfx::UniformType::Int1);
u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4);
u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Vec4);
u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Vec4);
s_texCube = bgfx::createUniform("s_texCube", bgfx::UniformType::Int1);
s_texCubeIrr = bgfx::createUniform("s_texCubeIrr", bgfx::UniformType::Int1);
int grid_size = 1024;
int grid_border = 12;
@ -432,11 +714,30 @@ void Renderer::setupShaders() {
m_timeOffset = bx::getHPCounter();
// Initialize light
std::cout << "Creating light uniforms..." << std::endl;
lights[0].u_shadowMap = bgfx::createUniform("u_shadowMap", bgfx::UniformType::Int1);
lights[0].u_shadowMapParams = bgfx::createUniform("u_shadowMapParams", bgfx::UniformType::Vec4);
lights[0].u_lightPos = bgfx::createUniform("u_lightPos", bgfx::UniformType::Int1);
lights[0].u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Int1);
// Setup the light probe pass
IBL::uniforms.init();
IBL::uniforms.m_glossiness = IBL::settings.m_glossiness;
IBL::uniforms.m_reflectivity = IBL::settings.m_reflectivity;
IBL::uniforms.m_exposure = IBL::settings.m_exposure;
IBL::uniforms.m_bgType = IBL::settings.m_bgType;
IBL::uniforms.m_metalOrSpec = float(IBL::settings.m_metalOrSpec);
IBL::uniforms.m_doDiffuse = float(IBL::settings.m_doDiffuse);
IBL::uniforms.m_doSpecular = float(IBL::settings.m_doSpecular);
IBL::uniforms.m_doDiffuseIbl = float(IBL::settings.m_doDiffuseIbl);
IBL::uniforms.m_doSpecularIbl = float(IBL::settings.m_doSpecularIbl);
memcpy(IBL::uniforms.m_rgbDiff, IBL::settings.m_rgbDiff, 3*sizeof(float) );
memcpy(IBL::uniforms.m_rgbSpec, IBL::settings.m_rgbSpec, 3*sizeof(float) );
memcpy(IBL::uniforms.m_lightDir, IBL::settings.m_lightDir, 3*sizeof(float) );
memcpy(IBL::uniforms.m_lightCol, IBL::settings.m_lightCol, 3*sizeof(float) );
s_renderStates[RenderState::Skybox].m_program = bgfxutils::loadProgramFromFiles("shaders/src/vs_ibl_skybox.sc", "shaders/src/fs_ibl_skybox.sc");
// Get renderer capabilities info.
const bgfx::Caps* caps = bgfx::getCaps();
// Shadow samplers are supported at least partially supported if texture
@ -545,6 +846,30 @@ class BGFXCallbacks: public bgfx::CallbackI {
};
};
namespace bgfx {
inline void glfwSetWindow(GLFWwindow* _window)
{
bgfx::PlatformData pd;
# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
pd.ndt = glfwGetX11Display();
pd.nwh = (void*)(uintptr_t)glfwGetGLXWindow(_window);
pd.context = glfwGetGLXContext(_window);
# elif BX_PLATFORM_OSX
pd.ndt = NULL;
pd.nwh = glfwGetCocoaWindow(_window);
pd.context = glfwGetNSGLContext(_window);
# elif BX_PLATFORM_WINDOWS
pd.ndt = NULL;
pd.nwh = glfwGetWin32Window(_window);
pd.context = NULL;
# endif // BX_PLATFORM_WINDOWS
pd.backBuffer = NULL;
pd.backBufferDS = NULL;
bgfx::setPlatformData(pd);
}
}
void Renderer::initialize(int width, int height) {
this->width = width;
this->height = height;
@ -555,6 +880,8 @@ void Renderer::initialize(int width, int height) {
reset = BGFX_RESET_VSYNC | BGFX_RESET_MAXANISOTROPY | BGFX_RESET_MSAA_X16;
bgfx::reset(width, height, reset);
std::cout << "bla55aa" << std::endl;
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
, 0x303030ff
@ -571,26 +898,21 @@ void Renderer::initialize(int width, int height) {
bgfx::setDebug(debug);
std::cout << "Creating Cameras" << std::endl;
cameras.push_back (Camera());
activeCameraIndex = 0;
lights.push_back (Light());
// set the clear state
// for (int i = 0; i < 2; i++) {
// bgfx::setViewClear(i
// , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
// , 0x303030ff
// , 1.0f
// , 0
// );
// }
createGeometries();
setupShaders();
setupRenderPasses();
mLightProbes[LightProbe::Bolonga].load("bolonga");
mLightProbes[LightProbe::Kyoto ].load("kyoto");
mCurrentLightProbe = LightProbe::Bolonga;
// Start the imgui frame such that widgets can be submitted
imguiBeginFrame (inputState.mouseX,
inputState.mouseY,
@ -605,22 +927,34 @@ void Renderer::initialize(int width, int height) {
}
void Renderer::shutdown() {
bgfx::destroyFrameBuffer(lights[0].shadowMapFB);
bgfx::destroyUniform(lights[0].u_shadowMap);
bgfx::destroyUniform(lights[0].u_shadowMapParams);
bgfx::destroyUniform(lights[0].u_lightPos);
bgfx::destroyUniform(lights[0].u_lightMtx);
bgfx::destroyIndexBuffer(cube_ibh);
bgfx::destroyIndexBuffer(cube_edges_ibh);
bgfx::destroyVertexBuffer(cube_vbh);
bgfx::destroyIndexBuffer(plane_ibh);
bgfx::destroyVertexBuffer(plane_vbh);
bgfx::destroyUniform(u_camPos);
bgfx::destroyUniform(u_flags);
bgfx::destroyUniform(u_mtx);
IBL::uniforms.destroy();
bgfx::destroyUniform(s_texCube);
bgfx::destroyUniform(s_texCubeIrr);
bgfx::destroyUniform(u_time);
bgfx::destroyUniform(u_color);
for (uint8_t ii = 0; ii < RenderState::Count; ++ii) {
if (bgfx::isValid(s_renderStates[ii].m_program)) {
bgfx::destroyProgram(s_renderStates[ii].m_program);
}
}
for (uint8_t ii = 0; ii < LightProbe::Count; ++ii) {
mLightProbes[ii].destroy();
}
for (size_t i = 0; i < entities.size(); i++) {
delete entities[i];
entities[i] = NULL;
@ -631,7 +965,18 @@ void Renderer::shutdown() {
meshes[i] = NULL;
}
for (size_t i = 0; i < lights.size(); i++) {
std::cout << "Destroying light uniforms for light " << i << std::endl;
bgfx::destroyFrameBuffer(lights[i].shadowMapFB);
bgfx::destroyUniform(lights[i].u_shadowMap);
bgfx::destroyUniform(lights[i].u_shadowMapParams);
bgfx::destroyUniform(lights[i].u_lightPos);
bgfx::destroyUniform(lights[i].u_lightMtx);
}
lights.clear();
cameras.clear();
}
void Renderer::resize (int width, int height) {
@ -747,6 +1092,13 @@ void Renderer::paintGL() {
}
// setup render passes
float view[16];
float proj[16];
bx::mtxIdentity(view);
bx::mtxOrtho(proj, 0.f, 1.f, 1.f, 0.f, 0.f, 100.0f);
bgfx::setViewRect(RenderState::Skybox, 0, 0, width, height);
bgfx::setViewTransform(RenderState::Skybox, view, proj);
bgfx::setViewRect(RenderState::ShadowMap, 0, 0, lights[0].shadowMapSize, lights[0].shadowMapSize);
bgfx::setViewFrameBuffer(RenderState::ShadowMap, lights[0].shadowMapFB);
bgfx::setViewTransform(RenderState::ShadowMap, lights[0].mtxView, lights[0].mtxProj);
@ -774,17 +1126,47 @@ void Renderer::paintGL() {
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
// Clear backbuffer and shadowmap framebuffer at beginning.
bgfx::setViewClear(RenderState::Skybox
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0xf03030ff, 1.0f, 0
);
bgfx::setViewClear(RenderState::ShadowMap
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x303030ff, 1.0f, 0
);
bgfx::setViewClear(RenderState::Scene
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x303030ff, 1.0f, 0
);
// bgfx::setViewClear(RenderState::Scene
// , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
// , 0x303030ff, 1.0f, 0
// );
bgfx::touch(RenderState::Scene);
bgfx::touch(RenderState::Skybox);
// Skybox pass
memcpy (IBL::uniforms.m_cameraPos, cameras[activeCameraIndex].eye, 3 * sizeof(float));
const float amount = bx::fmin(0.012/0.12f, 1.0f);
IBL::settings.m_envRotCurr = bx::flerp(IBL::settings.m_envRotCurr, IBL::settings.m_envRotDest, amount);
float mtxEnvRot[16];
float env_rot_cur = 0.0f;
float mtx_u_mtx[16];
bx::mtxRotateY(mtxEnvRot, env_rot_cur);
bx::mtxMul(IBL::uniforms.m_mtx, cameras[activeCameraIndex].mtxEnv, mtxEnvRot); // Used for Skybox.
bgfx::setTexture(0, s_texCube, mLightProbes[mCurrentLightProbe].m_tex);
bgfx::setTexture(1, s_texCubeIrr, mLightProbes[mCurrentLightProbe].m_texIrr);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
screenSpaceQuad(
(float)cameras[activeCameraIndex].width,
(float)cameras[activeCameraIndex].height, true);
IBL::uniforms.submit();
bgfx::submit(RenderState::Skybox, s_renderStates[RenderState::Skybox].m_program);
// render the plane
uint32_t cached = bgfx::setTransform(mtxFloor);
@ -795,6 +1177,10 @@ void Renderer::paintGL() {
continue;
const RenderState& st = s_renderStates[pass];
if (!isValid(st.m_program)) {
continue;
}
bgfx::setTransform(cached);
for (uint8_t tex = 0; tex < st.m_numTextures; ++tex)
{

View File

@ -43,13 +43,14 @@ struct Camera {
float mtxProj[16];
float mtxView[16];
float mtxEnv[16];
Camera() :
eye {5.f, 4.f, 5.f},
poi {0.f, 2.f, 0.f},
up {0.f, 1.f, 0.f},
near (1.f),
far (20.f),
near (0.1f),
far (150.f),
fov (70.f),
orthographic (false),
width (-1.f),
@ -61,6 +62,11 @@ struct Camera {
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f},
mtxView {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f},
mtxEnv {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
@ -146,6 +152,30 @@ struct Entity {
mesh (NULL) {};
};
struct LightProbe
{
enum Enum
{
Bolonga,
Kyoto,
Count
};
void load(const char* _name);
void destroy()
{
bgfx::destroyTexture(m_tex);
bgfx::destroyTexture(m_texIrr);
}
bgfx::TextureHandle m_tex;
bgfx::TextureHandle m_texIrr;
};
struct Renderer {
bool initialized;
bool drawDebug;
@ -159,6 +189,9 @@ struct Renderer {
typedef std::map<std::string, unsigned int> MeshIdMap;
MeshIdMap meshIdMap;
LightProbe mLightProbes[LightProbe::Count];
LightProbe::Enum mCurrentLightProbe;
std::vector<Entity*> entities;
std::vector<Camera> cameras;
@ -195,6 +228,7 @@ struct Renderer {
struct RenderState {
enum {
Skybox,
ShadowMap,
Scene,
SceneTextured,

View File

@ -20,7 +20,7 @@ namespace stl = tinystl;
#include "shaderc.h"
#include "Renderer.h"
#include "RenderModule.h"
#include "RenderUtils.h"
//#include "MeshVBO.h"
@ -293,11 +293,13 @@ bgfx::TextureHandle loadTexture(bx::FileReaderI* _reader, const char* _name, uin
char filePath[512] = { '\0' };
if (NULL == strchr(_name, '/') )
{
strcpy(filePath, "textures/");
strcpy(filePath, "data/textures/");
}
strcat(filePath, _name);
std::cout << "Loading texture " << filePath << std::endl;
if (NULL != bx::stristr(_name, ".dds")
|| NULL != bx::stristr(_name, ".pvr")
|| NULL != bx::stristr(_name, ".ktx") )

View File

@ -1,6 +1,6 @@
#include "RuntimeModule.h"
#include "Globals.h"
#include "Renderer.h"
#include "modules/RenderModule.h"
#include "3rdparty/ocornut-imgui/imgui.h"
#include "imgui/imgui.h"
#include <bx/fpumath.h>
@ -73,9 +73,9 @@ void handle_mouse (struct module_state *state) {
if (glfwGetMouseButton(gWindow, 1)) {
Vector3f view_dir;
view_dir = poi - eye;
view_dir = (poi - eye).normalized();
Vector3f right = camera_rot_inv.block<1,3>(0,0).transpose();
right = view_dir.normalized().cross (Vector3f (0.f, 1.f, 0.f));
right = view_dir.cross (Vector3f (0.f, 1.f, 0.f));
Matrix33f rot_matrix_y = SimpleMath::GL::RotateMat33(
gRenderer->inputState.mousedY * 0.4f,
right[0], right[1], right[2]);
@ -87,15 +87,7 @@ void handle_mouse (struct module_state *state) {
memcpy (active_camera->poi, poi.data(), sizeof(float) * 3);
}
// bx::mtxLookAt(
// active_camera->mtxView,
// active_camera->eye,
// active_camera->poi,
// active_camera->up
// );
// Not working: why?!?
// active_camera->updateMatrices();
active_camera->updateMatrices();
}
void handle_keyboard (struct module_state *state) {
@ -159,7 +151,7 @@ static void module_finalize(struct module_state *state) {
}
static void module_reload(struct module_state *state) {
std::cout << "Module reload called" << std::endl;
std::cout << "Module reload called. State: " << state << std::endl;
// reset mouse scrolling state
mouse_scroll_x = 0;
@ -169,7 +161,7 @@ static void module_reload(struct module_state *state) {
}
static void module_unload(struct module_state *state) {
std::cout << "Module unload called" << std::endl;
std::cout << "TestModule unloaded. State: " << state << std::endl;
glfwSetScrollCallback (gWindow, nullptr);
}
@ -194,7 +186,6 @@ static bool module_step(struct module_state *state) {
assert (active_camera != nullptr);
}
if (ImGui::Button("Hallo Katrina Whaddup?")) {
if (gRenderer->drawDebug) {
gRenderer->drawDebug = false;