diff --git a/data/textures/bark1.dds b/data/textures/bark1.dds new file mode 100644 index 0000000..5623d98 Binary files /dev/null and b/data/textures/bark1.dds differ diff --git a/data/textures/bolonga_irr.dds b/data/textures/bolonga_irr.dds new file mode 100644 index 0000000..618b334 Binary files /dev/null and b/data/textures/bolonga_irr.dds differ diff --git a/data/textures/bolonga_lod.dds b/data/textures/bolonga_lod.dds new file mode 100644 index 0000000..139328b Binary files /dev/null and b/data/textures/bolonga_lod.dds differ diff --git a/data/textures/fieldstone-n.dds b/data/textures/fieldstone-n.dds new file mode 100644 index 0000000..c74a33e Binary files /dev/null and b/data/textures/fieldstone-n.dds differ diff --git a/data/textures/fieldstone-rgba.dds b/data/textures/fieldstone-rgba.dds new file mode 100644 index 0000000..e64a033 Binary files /dev/null and b/data/textures/fieldstone-rgba.dds differ diff --git a/data/textures/figure-rgba.dds b/data/textures/figure-rgba.dds new file mode 100644 index 0000000..be608c8 Binary files /dev/null and b/data/textures/figure-rgba.dds differ diff --git a/data/textures/flare.dds b/data/textures/flare.dds new file mode 100644 index 0000000..c424642 Binary files /dev/null and b/data/textures/flare.dds differ diff --git a/data/textures/kyoto_irr.dds b/data/textures/kyoto_irr.dds new file mode 100644 index 0000000..c3f5ccf Binary files /dev/null and b/data/textures/kyoto_irr.dds differ diff --git a/data/textures/kyoto_lod.dds b/data/textures/kyoto_lod.dds new file mode 100644 index 0000000..dc2e055 Binary files /dev/null and b/data/textures/kyoto_lod.dds differ diff --git a/data/textures/leafs1.dds b/data/textures/leafs1.dds new file mode 100644 index 0000000..21102ba Binary files /dev/null and b/data/textures/leafs1.dds differ diff --git a/data/textures/texture_compression_bc1.ktx b/data/textures/texture_compression_bc1.ktx new file mode 100644 index 0000000..6dfe110 Binary files /dev/null and b/data/textures/texture_compression_bc1.ktx differ diff --git a/data/textures/texture_compression_bc2.ktx b/data/textures/texture_compression_bc2.ktx new file mode 100644 index 0000000..5b191d2 Binary files /dev/null and b/data/textures/texture_compression_bc2.ktx differ diff --git a/data/textures/texture_compression_bc3.ktx b/data/textures/texture_compression_bc3.ktx new file mode 100644 index 0000000..ed4ae91 Binary files /dev/null and b/data/textures/texture_compression_bc3.ktx differ diff --git a/data/textures/texture_compression_etc1.ktx b/data/textures/texture_compression_etc1.ktx new file mode 100644 index 0000000..b500684 Binary files /dev/null and b/data/textures/texture_compression_etc1.ktx differ diff --git a/data/textures/texture_compression_etc2.ktx b/data/textures/texture_compression_etc2.ktx new file mode 100644 index 0000000..0d14cf2 Binary files /dev/null and b/data/textures/texture_compression_etc2.ktx differ diff --git a/data/textures/texture_compression_ptc12.pvr b/data/textures/texture_compression_ptc12.pvr new file mode 100644 index 0000000..87e7434 Binary files /dev/null and b/data/textures/texture_compression_ptc12.pvr differ diff --git a/data/textures/texture_compression_ptc14.pvr b/data/textures/texture_compression_ptc14.pvr new file mode 100644 index 0000000..a79a820 Binary files /dev/null and b/data/textures/texture_compression_ptc14.pvr differ diff --git a/data/textures/texture_compression_ptc22.pvr b/data/textures/texture_compression_ptc22.pvr new file mode 100644 index 0000000..0c3ce35 Binary files /dev/null and b/data/textures/texture_compression_ptc22.pvr differ diff --git a/data/textures/texture_compression_ptc24.pvr b/data/textures/texture_compression_ptc24.pvr new file mode 100644 index 0000000..3e2c54e Binary files /dev/null and b/data/textures/texture_compression_ptc24.pvr differ diff --git a/data/textures/uffizi.dds b/data/textures/uffizi.dds new file mode 100644 index 0000000..e6c4fc3 Binary files /dev/null and b/data/textures/uffizi.dds differ diff --git a/shaders/include/shaderlib.sh b/shaders/include/shaderlib.sh new file mode 100644 index 0000000..51f9b6a --- /dev/null +++ b/shaders/include/shaderlib.sh @@ -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__ diff --git a/shaders/src/bgfx_shader.sh b/shaders/src/bgfx_shader.sh new file mode 100644 index 0000000..f607f17 --- /dev/null +++ b/shaders/src/bgfx_shader.sh @@ -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 m_texture; +}; + +struct BgfxUSampler2D +{ + Texture2D 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 m_texture; +}; + +struct BgfxUSampler3D +{ + Texture3D m_texture; +}; + +struct BgfxSamplerCube +{ + SamplerState m_sampler; + TextureCube m_texture; +}; + +struct BgfxSampler2DMS +{ + Texture2DMS 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 _name ## Texture : register(t[_reg]); \ + static BgfxISampler2D _name = { _name ## Texture } +# define USAMPLER2D(_name, _reg) \ + uniform Texture2D _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 _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 _name ## Texture : register(t[_reg]); \ + static BgfxISampler3D _name = { _name ## Texture } +# define USAMPLER3D(_name, _reg) \ + uniform Texture3D _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 diff --git a/shaders/src/fs_ibl_skybox.sc b/shaders/src/fs_ibl_skybox.sc new file mode 100644 index 0000000..d092038 --- /dev/null +++ b/shaders/src/fs_ibl_skybox.sc @@ -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); +} diff --git a/shaders/src/shaderlib.sh b/shaders/src/shaderlib.sh new file mode 100644 index 0000000..51f9b6a --- /dev/null +++ b/shaders/src/shaderlib.sh @@ -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__ diff --git a/shaders/src/uniforms.sh b/shaders/src/uniforms.sh new file mode 100644 index 0000000..61354fc --- /dev/null +++ b/shaders/src/uniforms.sh @@ -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 diff --git a/shaders/src/varying.def.sc b/shaders/src/varying.def.sc index df4e1cc..0bdd3b8 100644 --- a/shaders/src/varying.def.sc +++ b/shaders/src/varying.def.sc @@ -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); diff --git a/shaders/src/vs_ibl_skybox.sc b/shaders/src/vs_ibl_skybox.sc new file mode 100644 index 0000000..f3a15e0 --- /dev/null +++ b/shaders/src/vs_ibl_skybox.sc @@ -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; +} diff --git a/src/Renderer.cc b/src/Renderer.cc deleted file mode 100644 index 84c450d..0000000 --- a/src/Renderer.cc +++ /dev/null @@ -1,850 +0,0 @@ -#include "Renderer.h" - -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include - -#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(width); - cameras[i].height = static_cast(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(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 shapes; - std::vector 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; -} diff --git a/src/Renderer.h b/src/Renderer.h deleted file mode 100644 index 30b1faa..0000000 --- a/src/Renderer.h +++ /dev/null @@ -1,218 +0,0 @@ -#pragma once - -#include - -#include -#include - -#include - -#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 meshes; - typedef std::map MeshIdMap; - MeshIdMap meshIdMap; - - std::vector entities; - - std::vector cameras; - std::vector 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]; -}; - diff --git a/src/RuntimeModuleManager.cc b/src/RuntimeModuleManager.cc index b81e870..f467664 100644 --- a/src/RuntimeModuleManager.cc +++ b/src/RuntimeModuleManager.cc @@ -1,4 +1,5 @@ #include "RuntimeModuleManager.h" +#include #define _BSD_SOURCE // usleep() #include @@ -10,11 +11,14 @@ #include "RuntimeModule.h" #include +#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() { } } - diff --git a/src/RuntimeModuleManager.h b/src/RuntimeModuleManager.h index fea4461..1859f9a 100644 --- a/src/RuntimeModuleManager.h +++ b/src/RuntimeModuleManager.h @@ -10,6 +10,7 @@ struct RuntimeModuleManager { void RegisterModule(const char* name); void LoadModule(RuntimeModule* module); + bool CheckModulesChanged(); void UnloadModules(); void Update(float dt); }; diff --git a/src/main.cc b/src/main.cc index 291d38d..16dc1e5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -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] diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 2c5e24a..58e1535 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -10,3 +10,7 @@ ADD_LIBRARY (RenderModule SHARED ADD_LIBRARY (TestModule SHARED TestModule.cc ) + +TARGET_LINK_LIBRARIES ( TestModule + RenderModule + ) diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 4f59434..c360f8c 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -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 +#include + + #include "SimpleMath/SimpleMath.h" #include "SimpleMath/SimpleMathMap.h" @@ -15,6 +20,7 @@ #include #include #include +#include #include #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) { diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index 30b1faa..28fbf5e 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -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 MeshIdMap; MeshIdMap meshIdMap; + LightProbe mLightProbes[LightProbe::Count]; + LightProbe::Enum mCurrentLightProbe; + std::vector entities; std::vector cameras; @@ -195,6 +228,7 @@ struct Renderer { struct RenderState { enum { + Skybox, ShadowMap, Scene, SceneTextured, diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 54023c1..c9f01c7 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -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") ) diff --git a/src/modules/TestModule.cc b/src/modules/TestModule.cc index 2c9bfa7..051629b 100644 --- a/src/modules/TestModule.cc +++ b/src/modules/TestModule.cc @@ -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 @@ -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;