diff options
Diffstat (limited to '3rdparty/bgfx/examples/13-stencil/stencil.cpp')
-rw-r--r-- | 3rdparty/bgfx/examples/13-stencil/stencil.cpp | 1180 |
1 files changed, 592 insertions, 588 deletions
diff --git a/3rdparty/bgfx/examples/13-stencil/stencil.cpp b/3rdparty/bgfx/examples/13-stencil/stencil.cpp index b66aaa48e4b..a1af5aceb02 100644 --- a/3rdparty/bgfx/examples/13-stencil/stencil.cpp +++ b/3rdparty/bgfx/examples/13-stencil/stencil.cpp @@ -8,46 +8,29 @@ #include "common.h" #include "bgfx_utils.h" +#include <bx/file.h> -#include <bx/crtimpl.h> #include "camera.h" #include "imgui/imgui.h" -#define RENDER_VIEWID_RANGE1_PASS_0 1 -#define RENDER_VIEWID_RANGE1_PASS_1 2 -#define RENDER_VIEWID_RANGE1_PASS_2 3 -#define RENDER_VIEWID_RANGE1_PASS_3 4 -#define RENDER_VIEWID_RANGE1_PASS_4 5 -#define RENDER_VIEWID_RANGE1_PASS_5 6 -#define RENDER_VIEWID_RANGE5_PASS_6 7 -#define RENDER_VIEWID_RANGE1_PASS_7 13 - -#define MAX_NUM_LIGHTS 5 - -uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w) +namespace bgfx { - 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; + int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL); } -uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f) +namespace { - 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); -} + +#define RENDER_VIEWID_RANGE1_PASS_0 1 +#define RENDER_VIEWID_RANGE1_PASS_1 2 +#define RENDER_VIEWID_RANGE1_PASS_2 3 +#define RENDER_VIEWID_RANGE1_PASS_3 4 +#define RENDER_VIEWID_RANGE1_PASS_4 5 +#define RENDER_VIEWID_RANGE1_PASS_5 6 +#define RENDER_VIEWID_RANGE5_PASS_6 7 +#define RENDER_VIEWID_RANGE1_PASS_7 13 + +#define MAX_NUM_LIGHTS 5 struct PosNormalTexcoordVertex { @@ -76,46 +59,46 @@ bgfx::VertexDecl PosNormalTexcoordVertex::ms_decl; static const float s_texcoord = 5.0f; static PosNormalTexcoordVertex s_hplaneVertices[] = { - { -1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), s_texcoord, s_texcoord }, - { 1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), s_texcoord, 0.0f }, - { -1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), 0.0f, s_texcoord }, - { 1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), 0.0f, 0.0f }, + { -1.0f, 0.0f, 1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), s_texcoord, s_texcoord }, + { 1.0f, 0.0f, 1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), s_texcoord, 0.0f }, + { -1.0f, 0.0f, -1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), 0.0f, s_texcoord }, + { 1.0f, 0.0f, -1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), 0.0f, 0.0f }, }; static PosNormalTexcoordVertex s_vplaneVertices[] = { - { -1.0f, 1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 1.0f, 1.0f }, - { 1.0f, 1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 1.0f, 0.0f }, - { -1.0f, -1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 0.0f, 1.0f }, - { 1.0f, -1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 0.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 1.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 1.0f, 0.0f }, + { -1.0f, -1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 0.0f, 1.0f }, + { 1.0f, -1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 0.0f, 0.0f }, }; static const PosNormalTexcoordVertex s_cubeVertices[] = { - { -1.0f, 1.0f, 1.0f, packF4u( 0.0f, 1.0f, 0.0f), 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, packF4u( 0.0f, 1.0f, 0.0f), 0.0f, 1.0f }, - { -1.0f, 1.0f, -1.0f, packF4u( 0.0f, 1.0f, 0.0f), 1.0f, 0.0f }, - { 1.0f, 1.0f, -1.0f, packF4u( 0.0f, 1.0f, 0.0f), 0.0f, 0.0f }, - { -1.0f, -1.0f, 1.0f, packF4u( 0.0f, -1.0f, 0.0f), 1.0f, 1.0f }, - { 1.0f, -1.0f, 1.0f, packF4u( 0.0f, -1.0f, 0.0f), 0.0f, 1.0f }, - { -1.0f, -1.0f, -1.0f, packF4u( 0.0f, -1.0f, 0.0f), 1.0f, 0.0f }, - { 1.0f, -1.0f, -1.0f, packF4u( 0.0f, -1.0f, 0.0f), 0.0f, 0.0f }, - { 1.0f, -1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 0.0f, 0.0f }, - { 1.0f, 1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 0.0f, 1.0f }, - { -1.0f, -1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 1.0f, 0.0f }, - { -1.0f, 1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 1.0f, 1.0f }, - { 1.0f, -1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 0.0f, 0.0f }, - { 1.0f, 1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 0.0f, 1.0f }, - { -1.0f, -1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 1.0f, 0.0f }, - { -1.0f, 1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 1.0f, 1.0f }, - { 1.0f, 1.0f, -1.0f, packF4u( 1.0f, 0.0f, 0.0f), 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, packF4u( 1.0f, 0.0f, 0.0f), 0.0f, 1.0f }, - { 1.0f, -1.0f, -1.0f, packF4u( 1.0f, 0.0f, 0.0f), 1.0f, 0.0f }, - { 1.0f, -1.0f, 1.0f, packF4u( 1.0f, 0.0f, 0.0f), 0.0f, 0.0f }, - { -1.0f, 1.0f, -1.0f, packF4u(-1.0f, 0.0f, 0.0f), 1.0f, 1.0f }, - { -1.0f, 1.0f, 1.0f, packF4u(-1.0f, 0.0f, 0.0f), 0.0f, 1.0f }, - { -1.0f, -1.0f, -1.0f, packF4u(-1.0f, 0.0f, 0.0f), 1.0f, 0.0f }, - { -1.0f, -1.0f, 1.0f, packF4u(-1.0f, 0.0f, 0.0f), 0.0f, 0.0f }, + { -1.0f, 1.0f, 1.0f, encodeNormalRgba8( 0.0f, 1.0f, 0.0f), 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, encodeNormalRgba8( 0.0f, 1.0f, 0.0f), 0.0f, 1.0f }, + { -1.0f, 1.0f, -1.0f, encodeNormalRgba8( 0.0f, 1.0f, 0.0f), 1.0f, 0.0f }, + { 1.0f, 1.0f, -1.0f, encodeNormalRgba8( 0.0f, 1.0f, 0.0f), 0.0f, 0.0f }, + { -1.0f, -1.0f, 1.0f, encodeNormalRgba8( 0.0f, -1.0f, 0.0f), 1.0f, 1.0f }, + { 1.0f, -1.0f, 1.0f, encodeNormalRgba8( 0.0f, -1.0f, 0.0f), 0.0f, 1.0f }, + { -1.0f, -1.0f, -1.0f, encodeNormalRgba8( 0.0f, -1.0f, 0.0f), 1.0f, 0.0f }, + { 1.0f, -1.0f, -1.0f, encodeNormalRgba8( 0.0f, -1.0f, 0.0f), 0.0f, 0.0f }, + { 1.0f, -1.0f, 1.0f, encodeNormalRgba8( 0.0f, 0.0f, 1.0f), 0.0f, 0.0f }, + { 1.0f, 1.0f, 1.0f, encodeNormalRgba8( 0.0f, 0.0f, 1.0f), 0.0f, 1.0f }, + { -1.0f, -1.0f, 1.0f, encodeNormalRgba8( 0.0f, 0.0f, 1.0f), 1.0f, 0.0f }, + { -1.0f, 1.0f, 1.0f, encodeNormalRgba8( 0.0f, 0.0f, 1.0f), 1.0f, 1.0f }, + { 1.0f, -1.0f, -1.0f, encodeNormalRgba8( 0.0f, 0.0f, -1.0f), 0.0f, 0.0f }, + { 1.0f, 1.0f, -1.0f, encodeNormalRgba8( 0.0f, 0.0f, -1.0f), 0.0f, 1.0f }, + { -1.0f, -1.0f, -1.0f, encodeNormalRgba8( 0.0f, 0.0f, -1.0f), 1.0f, 0.0f }, + { -1.0f, 1.0f, -1.0f, encodeNormalRgba8( 0.0f, 0.0f, -1.0f), 1.0f, 1.0f }, + { 1.0f, 1.0f, -1.0f, encodeNormalRgba8( 1.0f, 0.0f, 0.0f), 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, encodeNormalRgba8( 1.0f, 0.0f, 0.0f), 0.0f, 1.0f }, + { 1.0f, -1.0f, -1.0f, encodeNormalRgba8( 1.0f, 0.0f, 0.0f), 1.0f, 0.0f }, + { 1.0f, -1.0f, 1.0f, encodeNormalRgba8( 1.0f, 0.0f, 0.0f), 0.0f, 0.0f }, + { -1.0f, 1.0f, -1.0f, encodeNormalRgba8(-1.0f, 0.0f, 0.0f), 1.0f, 1.0f }, + { -1.0f, 1.0f, 1.0f, encodeNormalRgba8(-1.0f, 0.0f, 0.0f), 0.0f, 1.0f }, + { -1.0f, -1.0f, -1.0f, encodeNormalRgba8(-1.0f, 0.0f, 0.0f), 1.0f, 0.0f }, + { -1.0f, -1.0f, 1.0f, encodeNormalRgba8(-1.0f, 0.0f, 0.0f), 0.0f, 0.0f }, }; static const uint16_t s_cubeIndices[] = @@ -142,16 +125,10 @@ static const uint16_t s_planeIndices[] = 1, 3, 2, }; -static bool s_flipV = false; static uint32_t s_viewMask = 0; static uint32_t s_clearMask = 0; static bgfx::UniformHandle s_texColor; -inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far) -{ - bx::mtxProj(_result, _fovy, _aspect, _near, _far, s_flipV); -} - void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil) { for (uint32_t view = 0, viewMask = _viewMask, ntz = bx::uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, view += 1, ntz = bx::uint32_cnttz(viewMask) ) @@ -340,13 +317,13 @@ struct Uniforms void destroy() { - bgfx::destroyUniform(u_params); - bgfx::destroyUniform(u_ambient); - bgfx::destroyUniform(u_diffuse); - bgfx::destroyUniform(u_specular_shininess); - bgfx::destroyUniform(u_color); - bgfx::destroyUniform(u_lightPosRadius); - bgfx::destroyUniform(u_lightRgbInnerR); + bgfx::destroy(u_params); + bgfx::destroy(u_ambient); + bgfx::destroy(u_diffuse); + bgfx::destroy(u_specular_shininess); + bgfx::destroy(u_color); + bgfx::destroy(u_lightPosRadius); + bgfx::destroy(u_lightRgbInnerR); } struct Params @@ -536,7 +513,7 @@ static RenderState s_renderStates[RenderState::Count] = struct ViewState { - ViewState(uint32_t _width = 1280, uint32_t _height = 720) + ViewState(uint32_t _width = 0, uint32_t _height = 0) : m_width(_width) , m_height(_height) { @@ -565,7 +542,7 @@ struct ClearValues uint8_t m_clearStencil; }; -void clearView(uint8_t _id, uint8_t _flags, const ClearValues& _clearValues) +void clearView(bgfx::ViewId _id, uint8_t _flags, const ClearValues& _clearValues) { bgfx::setViewClear(_id , _flags @@ -631,8 +608,8 @@ struct Group void reset() { - m_vbh.idx = bgfx::invalidHandle; - m_ibh.idx = bgfx::invalidHandle; + m_vbh.idx = bgfx::kInvalidHandle; + m_ibh.idx = bgfx::kInvalidHandle; m_prims.clear(); } @@ -644,11 +621,6 @@ struct Group PrimitiveArray m_prims; }; -namespace bgfx -{ - int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL); -} - struct Mesh { void load(const void* _vertices, uint32_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices) @@ -764,23 +736,23 @@ struct Mesh for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it) { const Group& group = *it; - bgfx::destroyVertexBuffer(group.m_vbh); + bgfx::destroy(group.m_vbh); - if (bgfx::invalidHandle != group.m_ibh.idx) + if (bgfx::isValid(group.m_ibh) ) { - bgfx::destroyIndexBuffer(group.m_ibh); + bgfx::destroy(group.m_ibh); } } m_groups.clear(); } - void submit(uint8_t _viewId, float* _mtx, bgfx::ProgramHandle _program, const RenderState& _renderState) + void submit(bgfx::ViewId _id, float* _mtx, bgfx::ProgramHandle _program, const RenderState& _renderState) { bgfx::TextureHandle texture = BGFX_INVALID_HANDLE; - submit(_viewId, _mtx, _program, _renderState, texture); + submit(_id, _mtx, _program, _renderState, texture); } - void submit(uint8_t _viewId, float* _mtx, bgfx::ProgramHandle _program, const RenderState& _renderState, bgfx::TextureHandle _texture) + void submit(bgfx::ViewId _id, float* _mtx, bgfx::ProgramHandle _program, const RenderState& _renderState, bgfx::TextureHandle _texture) { for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it) { @@ -792,23 +764,20 @@ struct Mesh // Set model matrix for rendering. bgfx::setTransform(_mtx); bgfx::setIndexBuffer(group.m_ibh); - bgfx::setVertexBuffer(group.m_vbh); + bgfx::setVertexBuffer(0, group.m_vbh); // Set texture - if (bgfx::invalidHandle != _texture.idx) - { - bgfx::setTexture(0, s_texColor, _texture); - } + bgfx::setTexture(0, s_texColor, _texture); // Apply render state bgfx::setStencil(_renderState.m_fstencil, _renderState.m_bstencil); bgfx::setState(_renderState.m_state, _renderState.m_blendFactorRgba); // Submit - bgfx::submit(_viewId, _program); + bgfx::submit(_id, _program); // Keep track of submited view ids - s_viewMask |= 1 << _viewId; + s_viewMask |= 1 << _id; } } @@ -817,586 +786,621 @@ struct Mesh GroupArray m_groups; }; -int _main_(int _argc, char** _argv) + +class ExampleStencil : public entry::AppI { - Args args(_argc, _argv); +public: + ExampleStencil(const char* _name, const char* _description) + : entry::AppI(_name, _description) + { + } - ViewState viewState(1280, 720); - ClearValues clearValues(0x30303000, 1.0f, 0); + virtual void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override + { + Args args(_argc, _argv); - uint32_t debug = BGFX_DEBUG_TEXT; - uint32_t reset = BGFX_RESET_VSYNC; + m_viewState = ViewState(_width, _height); + m_clearValues = ClearValues(0x30303000, 1.0f, 0); - bgfx::init(args.m_type, args.m_pciId); - bgfx::reset(viewState.m_width, viewState.m_height, reset); + m_debug = BGFX_DEBUG_NONE; + m_reset = BGFX_RESET_VSYNC; - // Enable debug text. - bgfx::setDebug(debug); + bgfx::init(args.m_type, args.m_pciId); + bgfx::reset(m_viewState.m_width, m_viewState.m_height, m_reset); - // Setup root path for binary shaders. Shader binaries are different - // for each renderer. - switch (bgfx::getRendererType() ) - { - case bgfx::RendererType::OpenGL: - case bgfx::RendererType::OpenGLES: - s_flipV = true; - break; + // Enable debug text. + bgfx::setDebug(m_debug); - default: - break; - } + // Imgui. + imguiCreate(); - // Imgui. - imguiCreate(); + PosNormalTexcoordVertex::init(); - PosNormalTexcoordVertex::init(); + s_uniforms.init(); - s_uniforms.init(); - s_uniforms.submitConstUniforms(); + s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1); - s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1); + m_programTextureLighting = loadProgram("vs_stencil_texture_lighting", "fs_stencil_texture_lighting"); + m_programColorLighting = loadProgram("vs_stencil_color_lighting", "fs_stencil_color_lighting" ); + m_programColorTexture = loadProgram("vs_stencil_color_texture", "fs_stencil_color_texture" ); + m_programColorBlack = loadProgram("vs_stencil_color", "fs_stencil_color_black" ); + m_programTexture = loadProgram("vs_stencil_texture", "fs_stencil_texture" ); - bgfx::ProgramHandle programTextureLighting = loadProgram("vs_stencil_texture_lighting", "fs_stencil_texture_lighting"); - bgfx::ProgramHandle programColorLighting = loadProgram("vs_stencil_color_lighting", "fs_stencil_color_lighting" ); - bgfx::ProgramHandle programColorTexture = loadProgram("vs_stencil_color_texture", "fs_stencil_color_texture" ); - bgfx::ProgramHandle programColorBlack = loadProgram("vs_stencil_color", "fs_stencil_color_black" ); - bgfx::ProgramHandle programTexture = loadProgram("vs_stencil_texture", "fs_stencil_texture" ); + m_bunnyMesh.load("meshes/bunny.bin"); + m_columnMesh.load("meshes/column.bin"); + m_cubeMesh.load(s_cubeVertices, BX_COUNTOF(s_cubeVertices), PosNormalTexcoordVertex::ms_decl, s_cubeIndices, BX_COUNTOF(s_cubeIndices) ); + m_hplaneMesh.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) ); + m_vplaneMesh.load(s_vplaneVertices, BX_COUNTOF(s_vplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) ); - Mesh bunnyMesh; - Mesh columnMesh; - Mesh cubeMesh; - Mesh hplaneMesh; - Mesh vplaneMesh; - bunnyMesh.load("meshes/bunny.bin"); - columnMesh.load("meshes/column.bin"); - cubeMesh.load(s_cubeVertices, BX_COUNTOF(s_cubeVertices), PosNormalTexcoordVertex::ms_decl, s_cubeIndices, BX_COUNTOF(s_cubeIndices) ); - hplaneMesh.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) ); - vplaneMesh.load(s_vplaneVertices, BX_COUNTOF(s_vplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) ); + m_figureTex = loadTexture("textures/figure-rgba.dds"); + m_flareTex = loadTexture("textures/flare.dds"); + m_fieldstoneTex = loadTexture("textures/fieldstone-rgba.dds"); - bgfx::TextureHandle figureTex = loadTexture("textures/figure-rgba.dds"); - bgfx::TextureHandle flareTex = loadTexture("textures/flare.dds"); - bgfx::TextureHandle fieldstoneTex = loadTexture("textures/fieldstone-rgba.dds"); + // Setup lights. + const float rgbInnerR[][4] = + { + { 1.0f, 0.7f, 0.2f, 0.0f }, //yellow + { 0.7f, 0.2f, 1.0f, 0.0f }, //purple + { 0.2f, 1.0f, 0.7f, 0.0f }, //cyan + { 1.0f, 0.4f, 0.2f, 0.0f }, //orange + { 0.7f, 0.7f, 0.7f, 0.0f }, //white + }; - // Setup lights. - const float rgbInnerR[][4] = - { - { 1.0f, 0.7f, 0.2f, 0.0f }, //yellow - { 0.7f, 0.2f, 1.0f, 0.0f }, //purple - { 0.2f, 1.0f, 0.7f, 0.0f }, //cyan - { 1.0f, 0.4f, 0.2f, 0.0f }, //orange - { 0.7f, 0.7f, 0.7f, 0.0f }, //white - }; + for (uint8_t ii = 0, jj = 0; ii < MAX_NUM_LIGHTS; ++ii, ++jj) + { + const uint8_t index = jj%BX_COUNTOF(rgbInnerR); + m_lightRgbInnerR[ii][0] = rgbInnerR[index][0]; + m_lightRgbInnerR[ii][1] = rgbInnerR[index][1]; + m_lightRgbInnerR[ii][2] = rgbInnerR[index][2]; + m_lightRgbInnerR[ii][3] = rgbInnerR[index][3]; + } + bx::memCopy(s_uniforms.m_lightRgbInnerR, m_lightRgbInnerR, MAX_NUM_LIGHTS * 4*sizeof(float) ); + + // Set view and projection matrices. + const float aspect = float(m_viewState.m_width)/float(m_viewState.m_height); + const bgfx::Caps* caps = bgfx::getCaps(); + bx::mtxProj(m_viewState.m_proj, 60.0f, aspect, 0.1f, 100.0f, caps->homogeneousDepth); + + float initialPos[3] = { 0.0f, 18.0f, -40.0f }; + cameraCreate(); + cameraSetPosition(initialPos); + cameraSetVerticalAngle(-0.35f); + cameraGetViewMtx(m_viewState.m_view); + + m_timeOffset = bx::getHPCounter(); + + m_scene = StencilReflectionScene; + m_numLights = 4; + m_reflectionValue = 0.8f; + m_updateLights = true; + m_updateScene = true; + } - float lightRgbInnerR[MAX_NUM_LIGHTS][4]; - for (uint8_t ii = 0, jj = 0; ii < MAX_NUM_LIGHTS; ++ii, ++jj) + virtual int shutdown() override { - const uint8_t index = jj%BX_COUNTOF(rgbInnerR); - lightRgbInnerR[ii][0] = rgbInnerR[index][0]; - lightRgbInnerR[ii][1] = rgbInnerR[index][1]; - lightRgbInnerR[ii][2] = rgbInnerR[index][2]; - lightRgbInnerR[ii][3] = rgbInnerR[index][3]; - } - bx::memCopy(s_uniforms.m_lightRgbInnerR, lightRgbInnerR, MAX_NUM_LIGHTS * 4*sizeof(float) ); + // Cleanup. + m_bunnyMesh.unload(); + m_columnMesh.unload(); + m_cubeMesh.unload(); + m_hplaneMesh.unload(); + m_vplaneMesh.unload(); - // Set view and projection matrices. - const float aspect = float(viewState.m_width)/float(viewState.m_height); - mtxProj(viewState.m_proj, 60.0f, aspect, 0.1f, 100.0f); + bgfx::destroy(m_figureTex); + bgfx::destroy(m_fieldstoneTex); + bgfx::destroy(m_flareTex); - float initialPos[3] = { 0.0f, 18.0f, -40.0f }; - cameraCreate(); - cameraSetPosition(initialPos); - cameraSetVerticalAngle(-0.35f); - cameraGetViewMtx(viewState.m_view); + bgfx::destroy(m_programTextureLighting); + bgfx::destroy(m_programColorLighting); + bgfx::destroy(m_programColorTexture); + bgfx::destroy(m_programColorBlack); + bgfx::destroy(m_programTexture); - int64_t timeOffset = bx::getHPCounter(); + bgfx::destroy(s_texColor); - enum Scene - { - StencilReflectionScene = 0, - ProjectionShadowsScene, - }; + s_uniforms.destroy(); - Scene scene = StencilReflectionScene; - float settings_numLights = 4.0f; - float settings_reflectionValue = 0.8f; - bool settings_updateLights = true; - bool settings_updateScene = true; + cameraDestroy(); + imguiDestroy(); - static const char* titles[3] = - { - "Stencil Reflection Scene", - "Projection Shadows Scene", - }; + // Shutdown bgfx. + bgfx::shutdown(); - entry::MouseState mouseState; - while (!entry::processEvents(viewState.m_width, viewState.m_height, debug, reset, &mouseState) ) + return 0; + } + + virtual bool update() override { - imguiBeginFrame(mouseState.m_mx - , mouseState.m_my - , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) - | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) - | (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) - , mouseState.m_mz - , uint16_t(viewState.m_width) - , uint16_t(viewState.m_height) - ); - - static int32_t scrollArea = 0; - imguiBeginScrollArea("Settings", viewState.m_width - 256 - 10, 10, 256, 215, &scrollArea); - - if (imguiCheck(titles[StencilReflectionScene], StencilReflectionScene == scene) ) + if (!entry::processEvents(m_viewState.m_width, m_viewState.m_height, m_debug, m_reset, &m_mouseState) ) { - scene = StencilReflectionScene; - settings_numLights = 4.0f; - } + imguiBeginFrame(m_mouseState.m_mx + , m_mouseState.m_my + , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) + , m_mouseState.m_mz + , uint16_t(m_viewState.m_width) + , uint16_t(m_viewState.m_height) + ); - if (imguiCheck(titles[ProjectionShadowsScene], ProjectionShadowsScene == scene) ) - { - scene = ProjectionShadowsScene; - settings_numLights = 1.0f; - } + showExampleDialog(this); - imguiSeparatorLine(); - imguiSlider("Lights", settings_numLights, 1.0f, float(MAX_NUM_LIGHTS), 1.0f); - if (scene == StencilReflectionScene) - { - imguiSlider("Reflection value", settings_reflectionValue, 0.0f, 1.0f, 0.01f); - } + ImGui::SetNextWindowPos( + ImVec2(m_viewState.m_width - m_viewState.m_width / 5.0f - 10.0f, 10.0f) + , ImGuiSetCond_FirstUseEver + ); + ImGui::Begin("Settings" + , NULL + , ImVec2(m_viewState.m_width / 5.0f, m_viewState.m_height / 2.0f) + , ImGuiWindowFlags_AlwaysAutoResize + ); - if (imguiCheck("Update lights", settings_updateLights) ) - { - settings_updateLights = !settings_updateLights; - } + { + bool check = StencilReflectionScene == m_scene; + if (ImGui::Checkbox("Stencil Reflection Scene", &check) ) + { + m_scene = StencilReflectionScene; + m_numLights = 4; + } + } - if (imguiCheck("Update scene", settings_updateScene) ) - { - settings_updateScene = !settings_updateScene; - } + { + bool check = ProjectionShadowsScene == m_scene; + if (ImGui::Checkbox("Projection Shadows Scene", &check) ) + { + m_scene = ProjectionShadowsScene; + m_numLights = 1; + } + } - imguiEndScrollArea(); - imguiEndFrame(); - - // Update settings. - uint8_t numLights = (uint8_t)settings_numLights; - s_uniforms.m_params.m_ambientPass = 1.0f; - s_uniforms.m_params.m_lightingPass = 1.0f; - s_uniforms.m_params.m_lightCount = settings_numLights; - s_uniforms.m_params.m_lightIndex = 0.0f; - s_uniforms.m_color[3] = settings_reflectionValue; - - // Time. - 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; - const float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) ); - const float deltaTime = float(frameTime/freq); - s_uniforms.m_time = time; - - // Use debug font to print information about this example. - bgfx::dbgTextClear(); - bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/13-stencil"); - bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Stencil reflections and shadows."); - bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); - - // Update camera. - cameraUpdate(deltaTime, mouseState); - cameraGetViewMtx(viewState.m_view); - - static float lightTimeAccumulator = 0.0f; - if (settings_updateLights) - { - lightTimeAccumulator += deltaTime; - } + ImGui::SliderInt("Lights", &m_numLights, 1, MAX_NUM_LIGHTS); + if (m_scene == StencilReflectionScene) + { + ImGui::SliderFloat("Reflection value", &m_reflectionValue, 0.0f, 1.0f); + } - static float sceneTimeAccumulator = 0.0f; - if (settings_updateScene) - { - sceneTimeAccumulator += deltaTime; - } + ImGui::Checkbox("Update lights", &m_updateLights); + ImGui::Checkbox("Update scene", &m_updateScene); - float lightPosRadius[MAX_NUM_LIGHTS][4]; - const float radius = (scene == StencilReflectionScene) ? 15.0f : 25.0f; - for (uint8_t ii = 0; ii < numLights; ++ii) - { - lightPosRadius[ii][0] = bx::fsin( (lightTimeAccumulator*1.1f + ii*0.03f + ii*bx::piHalf*1.07f ) )*20.0f; - lightPosRadius[ii][1] = 8.0f + (1.0f - bx::fcos( (lightTimeAccumulator*1.5f + ii*0.29f + bx::piHalf*1.49f ) ) )*4.0f; - lightPosRadius[ii][2] = bx::fcos( (lightTimeAccumulator*1.3f + ii*0.13f + ii*bx::piHalf*1.79f ) )*20.0f; - lightPosRadius[ii][3] = radius; - } - bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) ); - - // Floor position. - float floorMtx[16]; - bx::mtxSRT(floorMtx - , 20.0f //scaleX - , 20.0f //scaleY - , 20.0f //scaleZ - , 0.0f //rotX - , 0.0f //rotY - , 0.0f //rotZ - , 0.0f //translateX - , 0.0f //translateY - , 0.0f //translateZ - ); - - // Bunny position. - float bunnyMtx[16]; - bx::mtxSRT(bunnyMtx - , 5.0f - , 5.0f - , 5.0f - , 0.0f - , 1.56f - sceneTimeAccumulator - , 0.0f - , 0.0f - , 2.0f - , 0.0f - ); - - // Columns position. - const float dist = 14.0f; - const float columnPositions[4][3] = - { - { dist, 0.0f, dist }, - { -dist, 0.0f, dist }, - { dist, 0.0f, -dist }, - { -dist, 0.0f, -dist }, - }; + ImGui::End(); - float columnMtx[4][16]; - for (uint8_t ii = 0; ii < 4; ++ii) - { - bx::mtxSRT(columnMtx[ii] - , 1.0f - , 1.0f - , 1.0f - , 0.0f - , 0.0f - , 0.0f - , columnPositions[ii][0] - , columnPositions[ii][1] - , columnPositions[ii][2] + imguiEndFrame(); + + s_uniforms.submitConstUniforms(); + + // Update settings. + uint8_t numLights = (uint8_t)m_numLights; + s_uniforms.m_params.m_ambientPass = 1.0f; + s_uniforms.m_params.m_lightingPass = 1.0f; + s_uniforms.m_params.m_lightCount = float(m_numLights); + s_uniforms.m_params.m_lightIndex = 0.0f; + s_uniforms.m_color[3] = m_reflectionValue; + + // Time. + 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 float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) ); + const float deltaTime = float(frameTime/freq); + s_uniforms.m_time = time; + + // Update camera. + cameraUpdate(deltaTime, m_mouseState); + cameraGetViewMtx(m_viewState.m_view); + + static float lightTimeAccumulator = 0.0f; + if (m_updateLights) + { + lightTimeAccumulator += deltaTime; + } + + static float sceneTimeAccumulator = 0.0f; + if (m_updateScene) + { + sceneTimeAccumulator += deltaTime; + } + + float lightPosRadius[MAX_NUM_LIGHTS][4]; + const float radius = (m_scene == StencilReflectionScene) ? 15.0f : 25.0f; + for (uint8_t ii = 0; ii < numLights; ++ii) + { + lightPosRadius[ii][0] = bx::fsin( (lightTimeAccumulator*1.1f + ii*0.03f + ii*bx::kPiHalf*1.07f ) )*20.0f; + lightPosRadius[ii][1] = 8.0f + (1.0f - bx::fcos( (lightTimeAccumulator*1.5f + ii*0.29f + bx::kPiHalf*1.49f ) ) )*4.0f; + lightPosRadius[ii][2] = bx::fcos( (lightTimeAccumulator*1.3f + ii*0.13f + ii*bx::kPiHalf*1.79f ) )*20.0f; + lightPosRadius[ii][3] = radius; + } + bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) ); + + // Floor position. + float floorMtx[16]; + bx::mtxSRT(floorMtx + , 20.0f //scaleX + , 20.0f //scaleY + , 20.0f //scaleZ + , 0.0f //rotX + , 0.0f //rotY + , 0.0f //rotZ + , 0.0f //translateX + , 0.0f //translateY + , 0.0f //translateZ ); - } - const uint8_t numCubes = 9; - float cubeMtx[numCubes][16]; - for (uint16_t ii = 0; ii < numCubes; ++ii) - { - bx::mtxSRT(cubeMtx[ii] - , 1.0f - , 1.0f - , 1.0f + // Bunny position. + float bunnyMtx[16]; + bx::mtxSRT(bunnyMtx + , 5.0f + , 5.0f + , 5.0f , 0.0f + , 1.56f - sceneTimeAccumulator , 0.0f , 0.0f - , bx::fsin(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f - , 4.0f - , bx::fcos(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f + , 2.0f + , 0.0f ); - } - - // Make sure at the beginning everything gets cleared. - clearView(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL, clearValues); - bgfx::touch(0); - s_viewMask |= 1; - // Bunny and columns color. - s_uniforms.m_color[0] = 0.70f; - s_uniforms.m_color[1] = 0.65f; - s_uniforms.m_color[2] = 0.60f; - - switch (scene) - { - case StencilReflectionScene: + // Columns position. + const float dist = 14.0f; + const float columnPositions[4][3] = { - // First pass - Draw plane. - - // Setup params for this scene. - s_uniforms.m_params.m_ambientPass = 1.0f; - s_uniforms.m_params.m_lightingPass = 1.0f; - - // Floor. - hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 - , floorMtx - , programColorBlack - , s_renderStates[RenderState::StencilReflection_CraftStencil] + { dist, 0.0f, dist }, + { -dist, 0.0f, dist }, + { dist, 0.0f, -dist }, + { -dist, 0.0f, -dist }, + }; + + float columnMtx[4][16]; + for (uint8_t ii = 0; ii < 4; ++ii) + { + bx::mtxSRT(columnMtx[ii] + , 1.0f + , 1.0f + , 1.0f + , 0.0f + , 0.0f + , 0.0f + , columnPositions[ii][0] + , columnPositions[ii][1] + , columnPositions[ii][2] ); + } - // Second pass - Draw reflected objects. + const uint8_t numCubes = 9; + float cubeMtx[numCubes][16]; + for (uint16_t ii = 0; ii < numCubes; ++ii) + { + bx::mtxSRT(cubeMtx[ii] + , 1.0f + , 1.0f + , 1.0f + , 0.0f + , 0.0f + , 0.0f + , bx::fsin(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f + , 4.0f + , bx::fcos(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f + ); + } - // Clear depth from previous pass. - clearView(RENDER_VIEWID_RANGE1_PASS_1, BGFX_CLEAR_DEPTH, clearValues); + // Make sure at the beginning everything gets cleared. + clearView(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL, m_clearValues); + bgfx::touch(0); + s_viewMask |= 1; - // Compute reflected matrix. - float reflectMtx[16]; - float plane_pos[3] = { 0.0f, 0.01f, 0.0f }; - float normal[3] = { 0.0f, 1.0f, 0.0f }; - mtxReflected(reflectMtx, plane_pos, normal); + // Bunny and columns color. + s_uniforms.m_color[0] = 0.70f; + s_uniforms.m_color[1] = 0.65f; + s_uniforms.m_color[2] = 0.60f; - // Reflect lights. - float reflectedLights[MAX_NUM_LIGHTS][4]; - for (uint8_t ii = 0; ii < numLights; ++ii) + switch (m_scene) + { + case StencilReflectionScene: { - bx::vec3MulMtx(reflectedLights[ii], lightPosRadius[ii], reflectMtx); - reflectedLights[ii][3] = lightPosRadius[ii][3]; - } - bx::memCopy(s_uniforms.m_lightPosRadius, reflectedLights, numLights * 4*sizeof(float) ); - - // Reflect and submit bunny. - float mtxReflectedBunny[16]; - bx::mtxMul(mtxReflectedBunny, bunnyMtx, reflectMtx); - bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_1 - , mtxReflectedBunny - , programColorLighting - , s_renderStates[RenderState::StencilReflection_DrawReflected] - ); + // First pass - Draw plane. - // Reflect and submit columns. - float mtxReflectedColumn[16]; - for (uint8_t ii = 0; ii < 4; ++ii) - { - bx::mtxMul(mtxReflectedColumn, columnMtx[ii], reflectMtx); - columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_1 - , mtxReflectedColumn - , programColorLighting - , s_renderStates[RenderState::StencilReflection_DrawReflected] - ); - } + // Setup params for this scene. + s_uniforms.m_params.m_ambientPass = 1.0f; + s_uniforms.m_params.m_lightingPass = 1.0f; - // Set lights back. - bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) ); - // Third pass - Blend plane. + // Floor. + m_hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 + , floorMtx + , m_programColorBlack + , s_renderStates[RenderState::StencilReflection_CraftStencil] + ); - // Floor. - hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_2 - , floorMtx - , programTextureLighting - , s_renderStates[RenderState::StencilReflection_BlendPlane] - , fieldstoneTex - ); + // Second pass - Draw reflected objects. - // Fourth pass - Draw everything else but the plane. + // Clear depth from previous pass. + clearView(RENDER_VIEWID_RANGE1_PASS_1, BGFX_CLEAR_DEPTH, m_clearValues); - // Bunny. - bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_3 - , bunnyMtx - , programColorLighting - , s_renderStates[RenderState::StencilReflection_DrawScene] - ); + // Compute reflected matrix. + float reflectMtx[16]; + float plane_pos[3] = { 0.0f, 0.01f, 0.0f }; + float normal[3] = { 0.0f, 1.0f, 0.0f }; + mtxReflected(reflectMtx, plane_pos, normal); - // Columns. - for (uint8_t ii = 0; ii < 4; ++ii) - { - columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_3 - , columnMtx[ii] - , programColorLighting - , s_renderStates[RenderState::StencilReflection_DrawScene] + // Reflect lights. + float reflectedLights[MAX_NUM_LIGHTS][4]; + for (uint8_t ii = 0; ii < numLights; ++ii) + { + bx::vec3MulMtx(reflectedLights[ii], lightPosRadius[ii], reflectMtx); + reflectedLights[ii][3] = lightPosRadius[ii][3]; + } + bx::memCopy(s_uniforms.m_lightPosRadius, reflectedLights, numLights * 4*sizeof(float) ); + + // Reflect and submit bunny. + float mtxReflectedBunny[16]; + bx::mtxMul(mtxReflectedBunny, bunnyMtx, reflectMtx); + m_bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_1 + , mtxReflectedBunny + , m_programColorLighting + , s_renderStates[RenderState::StencilReflection_DrawReflected] ); - } - - } - break; - case ProjectionShadowsScene: - { - // First pass - Draw entire scene. (ambient only). - s_uniforms.m_params.m_ambientPass = 1.0f; - s_uniforms.m_params.m_lightingPass = 0.0f; - - // Bunny. - bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 - , bunnyMtx - , programColorLighting - , s_renderStates[RenderState::ProjectionShadows_DrawAmbient] - ); + // Reflect and submit columns. + float mtxReflectedColumn[16]; + for (uint8_t ii = 0; ii < 4; ++ii) + { + bx::mtxMul(mtxReflectedColumn, columnMtx[ii], reflectMtx); + m_columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_1 + , mtxReflectedColumn + , m_programColorLighting + , s_renderStates[RenderState::StencilReflection_DrawReflected] + ); + } - // Floor. - hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 - , floorMtx - , programTextureLighting - , s_renderStates[RenderState::ProjectionShadows_DrawAmbient] - , fieldstoneTex - ); + // Set lights back. + bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) ); + // Third pass - Blend plane. - // Cubes. - for (uint8_t ii = 0; ii < numCubes; ++ii) - { - cubeMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 - , cubeMtx[ii] - , programTextureLighting - , s_renderStates[RenderState::ProjectionShadows_DrawAmbient] - , figureTex + // Floor. + m_hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_2 + , floorMtx + , m_programTextureLighting + , s_renderStates[RenderState::StencilReflection_BlendPlane] + , m_fieldstoneTex ); - } - // Ground plane. - float ground[4]; - float plane_pos[3] = { 0.0f, 0.0f, 0.0f }; - float normal[3] = { 0.0f, 1.0f, 0.0f }; - bx::memCopy(ground, normal, sizeof(float) * 3); - ground[3] = -bx::vec3Dot(plane_pos, normal) - 0.01f; // - 0.01 against z-fighting + // Fourth pass - Draw everything else but the plane. - for (uint8_t ii = 0, viewId = RENDER_VIEWID_RANGE5_PASS_6; ii < numLights; ++ii, ++viewId) - { - // Clear stencil for this light source. - clearView(viewId, BGFX_CLEAR_STENCIL, clearValues); - - // Draw shadow projection of scene objects. - - // Get homogeneous light pos. - float* lightPos = lightPosRadius[ii]; - float pos[4]; - bx::memCopy(pos, lightPos, sizeof(float) * 3); - pos[3] = 1.0f; - - // Calculate shadow mtx for current light. - float shadowMtx[16]; - mtxShadow(shadowMtx, ground, pos); - - // Submit bunny's shadow. - float mtxShadowedBunny[16]; - bx::mtxMul(mtxShadowedBunny, bunnyMtx, shadowMtx); - bunnyMesh.submit(viewId - , mtxShadowedBunny - , programColorBlack - , s_renderStates[RenderState::ProjectionShadows_CraftStencil] - ); + // Bunny. + m_bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_3 + , bunnyMtx + , m_programColorLighting + , s_renderStates[RenderState::StencilReflection_DrawScene] + ); - // Submit cube shadows. - float mtxShadowedCube[16]; - for (uint8_t jj = 0; jj < numCubes; ++jj) + // Columns. + for (uint8_t ii = 0; ii < 4; ++ii) { - bx::mtxMul(mtxShadowedCube, cubeMtx[jj], shadowMtx); - cubeMesh.submit(viewId - , mtxShadowedCube - , programColorBlack - , s_renderStates[RenderState::ProjectionShadows_CraftStencil] - ); + m_columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_3 + , columnMtx[ii] + , m_programColorLighting + , s_renderStates[RenderState::StencilReflection_DrawScene] + ); } - // Draw entire scene. (lighting pass only. blending is on) - s_uniforms.m_params.m_ambientPass = 0.0f; - s_uniforms.m_params.m_lightingPass = 1.0f; - s_uniforms.m_params.m_lightCount = 1.0f; - s_uniforms.m_params.m_lightIndex = float(ii); + } + break; + + case ProjectionShadowsScene: + { + // First pass - Draw entire scene. (ambient only). + s_uniforms.m_params.m_ambientPass = 1.0f; + s_uniforms.m_params.m_lightingPass = 0.0f; // Bunny. - bunnyMesh.submit(viewId + m_bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 , bunnyMtx - , programColorLighting - , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse] - ); + , m_programColorLighting + , s_renderStates[RenderState::ProjectionShadows_DrawAmbient] + ); // Floor. - hplaneMesh.submit(viewId + m_hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 , floorMtx - , programTextureLighting - , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse] - , fieldstoneTex + , m_programTextureLighting + , s_renderStates[RenderState::ProjectionShadows_DrawAmbient] + , m_fieldstoneTex ); // Cubes. - for (uint8_t jj = 0; jj < numCubes; ++jj) + for (uint8_t ii = 0; ii < numCubes; ++ii) + { + m_cubeMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 + , cubeMtx[ii] + , m_programTextureLighting + , s_renderStates[RenderState::ProjectionShadows_DrawAmbient] + , m_figureTex + ); + } + + // Ground plane. + float ground[4]; + float plane_pos[3] = { 0.0f, 0.0f, 0.0f }; + float normal[3] = { 0.0f, 1.0f, 0.0f }; + bx::memCopy(ground, normal, sizeof(float) * 3); + ground[3] = -bx::vec3Dot(plane_pos, normal) - 0.01f; // - 0.01 against z-fighting + + for (uint8_t ii = 0, viewId = RENDER_VIEWID_RANGE5_PASS_6; ii < numLights; ++ii, ++viewId) { - cubeMesh.submit(viewId - , cubeMtx[jj] - , programTextureLighting + // Clear stencil for this light source. + clearView(viewId, BGFX_CLEAR_STENCIL, m_clearValues); + + // Draw shadow projection of scene objects. + + // Get homogeneous light pos. + float* lightPos = lightPosRadius[ii]; + float pos[4]; + bx::memCopy(pos, lightPos, sizeof(float) * 3); + pos[3] = 1.0f; + + // Calculate shadow mtx for current light. + float shadowMtx[16]; + mtxShadow(shadowMtx, ground, pos); + + // Submit bunny's shadow. + float mtxShadowedBunny[16]; + bx::mtxMul(mtxShadowedBunny, bunnyMtx, shadowMtx); + m_bunnyMesh.submit(viewId + , mtxShadowedBunny + , m_programColorBlack + , s_renderStates[RenderState::ProjectionShadows_CraftStencil] + ); + + // Submit cube shadows. + float mtxShadowedCube[16]; + for (uint8_t jj = 0; jj < numCubes; ++jj) + { + bx::mtxMul(mtxShadowedCube, cubeMtx[jj], shadowMtx); + m_cubeMesh.submit(viewId + , mtxShadowedCube + , m_programColorBlack + , s_renderStates[RenderState::ProjectionShadows_CraftStencil] + ); + } + + // Draw entire scene. (lighting pass only. blending is on) + s_uniforms.m_params.m_ambientPass = 0.0f; + s_uniforms.m_params.m_lightingPass = 1.0f; + s_uniforms.m_params.m_lightCount = 1.0f; + s_uniforms.m_params.m_lightIndex = float(ii); + + // Bunny. + m_bunnyMesh.submit(viewId + , bunnyMtx + , m_programColorLighting + , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse] + ); + + // Floor. + m_hplaneMesh.submit(viewId + , floorMtx + , m_programTextureLighting , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse] - , figureTex + , m_fieldstoneTex ); + + // Cubes. + for (uint8_t jj = 0; jj < numCubes; ++jj) + { + m_cubeMesh.submit(viewId + , cubeMtx[jj] + , m_programTextureLighting + , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse] + , m_figureTex + ); + } } + + // Reset these to default.. + s_uniforms.m_params.m_ambientPass = 1.0f; + s_uniforms.m_params.m_lightingPass = 1.0f; } + break; + }; - // Reset these to default.. - s_uniforms.m_params.m_ambientPass = 1.0f; - s_uniforms.m_params.m_lightingPass = 1.0f; + //lights + const float lightScale[3] = { 1.5f, 1.5f, 1.5f }; + float lightMtx[16]; + for (uint8_t ii = 0; ii < numLights; ++ii) + { + s_uniforms.m_color[0] = m_lightRgbInnerR[ii][0]; + s_uniforms.m_color[1] = m_lightRgbInnerR[ii][1]; + s_uniforms.m_color[2] = m_lightRgbInnerR[ii][2]; + + mtxBillboard(lightMtx, m_viewState.m_view, lightPosRadius[ii], lightScale); + m_vplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7 + , lightMtx + , m_programColorTexture + , s_renderStates[RenderState::Custom_BlendLightTexture] + , m_flareTex + ); } - break; - }; - //lights - const float lightScale[3] = { 1.5f, 1.5f, 1.5f }; - float lightMtx[16]; - for (uint8_t ii = 0; ii < numLights; ++ii) - { - s_uniforms.m_color[0] = lightRgbInnerR[ii][0]; - s_uniforms.m_color[1] = lightRgbInnerR[ii][1]; - s_uniforms.m_color[2] = lightRgbInnerR[ii][2]; - - mtxBillboard(lightMtx, viewState.m_view, lightPosRadius[ii], lightScale); - vplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7 - , lightMtx - , programColorTexture - , s_renderStates[RenderState::Custom_BlendLightTexture] - , flareTex + // Draw floor bottom. + float floorBottomMtx[16]; + bx::mtxSRT(floorBottomMtx + , 20.0f //scaleX + , 20.0f //scaleY + , 20.0f //scaleZ + , 0.0f //rotX + , 0.0f //rotY + , 0.0f //rotZ + , 0.0f //translateX + , -0.1f //translateY + , 0.0f //translateZ ); + + m_hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7 + , floorBottomMtx + , m_programTexture + , s_renderStates[RenderState::Custom_DrawPlaneBottom] + , m_figureTex + ); + + // Setup view rect and transform for all used views. + setViewRectMask(s_viewMask, 0, 0, uint16_t(m_viewState.m_width), uint16_t(m_viewState.m_height) ); + setViewTransformMask(s_viewMask, m_viewState.m_view, m_viewState.m_proj); + s_viewMask = 0; + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + bgfx::frame(); + + //reset clear values on used views + clearViewMask(s_clearMask, BGFX_CLEAR_NONE, m_clearValues); + s_clearMask = 0; + + return true; } - // Draw floor bottom. - float floorBottomMtx[16]; - bx::mtxSRT(floorBottomMtx - , 20.0f //scaleX - , 20.0f //scaleY - , 20.0f //scaleZ - , 0.0f //rotX - , 0.0f //rotY - , 0.0f //rotZ - , 0.0f //translateX - , -0.1f //translateY - , 0.0f //translateZ - ); - - hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7 - , floorBottomMtx - , programTexture - , s_renderStates[RenderState::Custom_DrawPlaneBottom] - , figureTex - ); - - // Setup view rect and transform for all used views. - setViewRectMask(s_viewMask, 0, 0, uint16_t(viewState.m_width), uint16_t(viewState.m_height) ); - setViewTransformMask(s_viewMask, viewState.m_view, viewState.m_proj); - s_viewMask = 0; - - // Advance to next frame. Rendering thread will be kicked to - // process submitted rendering primitives. - bgfx::frame(); - - //reset clear values on used views - clearViewMask(s_clearMask, BGFX_CLEAR_NONE, clearValues); - s_clearMask = 0; + return false; } - // Cleanup. - bunnyMesh.unload(); - columnMesh.unload(); - cubeMesh.unload(); - hplaneMesh.unload(); - vplaneMesh.unload(); + ViewState m_viewState; + entry::MouseState m_mouseState; + ClearValues m_clearValues; - bgfx::destroyTexture(figureTex); - bgfx::destroyTexture(fieldstoneTex); - bgfx::destroyTexture(flareTex); + uint32_t m_debug; + uint32_t m_reset; - bgfx::destroyProgram(programTextureLighting); - bgfx::destroyProgram(programColorLighting); - bgfx::destroyProgram(programColorTexture); - bgfx::destroyProgram(programColorBlack); - bgfx::destroyProgram(programTexture); + bgfx::ProgramHandle m_programTextureLighting; + bgfx::ProgramHandle m_programColorLighting; + bgfx::ProgramHandle m_programColorTexture; + bgfx::ProgramHandle m_programColorBlack; + bgfx::ProgramHandle m_programTexture; - bgfx::destroyUniform(s_texColor); + Mesh m_bunnyMesh; + Mesh m_columnMesh; + Mesh m_cubeMesh; + Mesh m_hplaneMesh; + Mesh m_vplaneMesh; - s_uniforms.destroy(); + bgfx::TextureHandle m_figureTex; + bgfx::TextureHandle m_flareTex; + bgfx::TextureHandle m_fieldstoneTex; - cameraDestroy(); - imguiDestroy(); + float m_lightRgbInnerR[MAX_NUM_LIGHTS][4]; - // Shutdown bgfx. - bgfx::shutdown(); + int64_t m_timeOffset; - return 0; -} + enum Scene + { + StencilReflectionScene = 0, + ProjectionShadowsScene, + }; + + Scene m_scene; + int32_t m_numLights; + float m_reflectionValue; + bool m_updateLights; + bool m_updateScene; + +}; + +} // namespace + +ENTRY_IMPLEMENT_MAIN(ExampleStencil, "13-stencil", "Stencil reflections and shadows."); |