summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp')
-rw-r--r--3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp1877
1 files changed, 979 insertions, 898 deletions
diff --git a/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp b/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp
index 5149e79e33b..d6195526d12 100644
--- a/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp
+++ b/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp
@@ -18,12 +18,20 @@ namespace stl = tinystl;
#include <bx/allocator.h>
#include <bx/hash.h>
#include <bx/simd_t.h>
-#include <bx/fpumath.h>
-#include <bx/crtimpl.h>
+#include <bx/math.h>
+#include <bx/file.h>
#include "entry/entry.h"
#include "camera.h"
#include "imgui/imgui.h"
+namespace bgfx
+{
+ int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
+}
+
+namespace
+{
+
#define SV_USE_SIMD 1
#define MAX_INSTANCE_COUNT 25
#define MAX_LIGHTS_COUNT 5
@@ -33,31 +41,6 @@ namespace stl = tinystl;
#define VIEWID_RANGE15_PASS2 3
#define VIEWID_RANGE1_PASS3 20
-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);
-}
-
struct PosNormalTexcoordVertex
{
float m_x;
@@ -85,18 +68,18 @@ bgfx::VertexDecl PosNormalTexcoordVertex::ms_decl;
static const float s_texcoord = 50.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 uint16_t s_planeIndices[] =
@@ -278,16 +261,16 @@ struct Uniforms
void destroy()
{
- bgfx::destroyUniform(u_params);
- bgfx::destroyUniform(u_svparams);
- bgfx::destroyUniform(u_ambient);
- bgfx::destroyUniform(u_diffuse);
- bgfx::destroyUniform(u_specular_shininess);
- bgfx::destroyUniform(u_fog);
- bgfx::destroyUniform(u_color);
- bgfx::destroyUniform(u_lightPosRadius);
- bgfx::destroyUniform(u_lightRgbInnerR);
- bgfx::destroyUniform(u_virtualLightPos_extrusionDist);
+ bgfx::destroy(u_params);
+ bgfx::destroy(u_svparams);
+ bgfx::destroy(u_ambient);
+ bgfx::destroy(u_diffuse);
+ bgfx::destroy(u_specular_shininess);
+ bgfx::destroy(u_fog);
+ bgfx::destroy(u_color);
+ bgfx::destroy(u_lightPosRadius);
+ bgfx::destroy(u_lightRgbInnerR);
+ bgfx::destroy(u_virtualLightPos_extrusionDist);
}
struct Params
@@ -541,7 +524,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)
{
@@ -561,7 +544,7 @@ struct ClearValues
uint8_t m_clearStencil;
};
-void submit(uint8_t _id, bgfx::ProgramHandle _handle, int32_t _depth = 0)
+void submit(bgfx::ViewId _id, bgfx::ProgramHandle _handle, int32_t _depth = 0)
{
bgfx::submit(_id, _handle, _depth);
@@ -569,7 +552,7 @@ void submit(uint8_t _id, bgfx::ProgramHandle _handle, int32_t _depth = 0)
s_viewMask |= 1 << _id;
}
-void touch(uint8_t _id)
+void touch(bgfx::ViewId _id)
{
bgfx::ProgramHandle handle = BGFX_INVALID_HANDLE;
::submit(_id, handle);
@@ -765,7 +748,7 @@ uint16_t weldVertices(WeldedVertex* _output, const bgfx::VertexDecl& _decl, cons
{
float pos[4];
vertexUnpack(pos, bgfx::Attrib::Position, _decl, _data, ii);
- uint32_t hashValue = bx::hashMurmur2A(pos, 3*sizeof(float) ) & hashMask;
+ uint32_t hashValue = bx::hash<bx::HashMurmur2A>(pos, 3*sizeof(float) ) & hashMask;
uint16_t offset = hashTable[hashValue];
for (; UINT16_MAX != offset; offset = next[offset])
@@ -803,8 +786,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_numVertices = 0;
m_vertices = NULL;
m_numIndices = 0;
@@ -945,10 +928,10 @@ struct Group
void unload()
{
- bgfx::destroyVertexBuffer(m_vbh);
- if (bgfx::invalidHandle != m_ibh.idx)
+ bgfx::destroy(m_vbh);
+ if (bgfx::kInvalidHandle != m_ibh.idx)
{
- bgfx::destroyIndexBuffer(m_ibh);
+ bgfx::destroy(m_ibh);
}
free(m_vertices);
m_vertices = NULL;
@@ -981,11 +964,6 @@ struct Group
typedef std::vector<Group> GroupArray;
-namespace bgfx
-{
- int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
-}
-
struct Mesh
{
void load(const void* _vertices, uint16_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
@@ -1133,8 +1111,8 @@ struct Model
{
Model()
{
- m_program.idx = bgfx::invalidHandle;
- m_texture.idx = bgfx::invalidHandle;
+ m_program.idx = bgfx::kInvalidHandle;
+ m_texture.idx = bgfx::kInvalidHandle;
}
void load(const void* _vertices, uint16_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
@@ -1166,10 +1144,10 @@ struct Model
// Set buffers
bgfx::setIndexBuffer(group.m_ibh);
- bgfx::setVertexBuffer(group.m_vbh);
+ bgfx::setVertexBuffer(0, group.m_vbh);
// Set textures
- if (bgfx::invalidHandle != m_texture.idx)
+ if (bgfx::kInvalidHandle != m_texture.idx)
{
bgfx::setTexture(0, s_texColor, m_texture);
}
@@ -1179,7 +1157,7 @@ struct Model
::setRenderState(_renderState);
// Submit
- BX_CHECK(bgfx::invalidHandle != m_program, "Error, program is not set.");
+ BX_CHECK(bgfx::kInvalidHandle != m_program, "Error, program is not set.");
::submit(_viewId, m_program);
}
}
@@ -1683,8 +1661,8 @@ void shadowVolumeCreate(ShadowVolume& _shadowVolume
// bgfx::destroy*Buffer doesn't actually destroy buffers now.
// Instead, these bgfx::destroy*Buffer commands get queued to be executed after the end of the next frame.
- bgfx::destroyVertexBuffer(_shadowVolume.m_vbSides);
- bgfx::destroyIndexBuffer(_shadowVolume.m_ibSides);
+ bgfx::destroy(_shadowVolume.m_vbSides);
+ bgfx::destroy(_shadowVolume.m_ibSides);
if (cap)
{
@@ -1694,7 +1672,7 @@ void shadowVolumeCreate(ShadowVolume& _shadowVolume
_shadowVolume.m_ibFrontCap = bgfx::createIndexBuffer(mem);
//gets destroyed after the end of the next frame
- bgfx::destroyIndexBuffer(_shadowVolume.m_ibFrontCap);
+ bgfx::destroy(_shadowVolume.m_ibFrontCap);
//back cap
isize = backCapI * sizeof(uint16_t);
@@ -1702,7 +1680,7 @@ void shadowVolumeCreate(ShadowVolume& _shadowVolume
_shadowVolume.m_ibBackCap = bgfx::createIndexBuffer(mem);
//gets destroyed after the end of the next frame
- bgfx::destroyIndexBuffer(_shadowVolume.m_ibBackCap);
+ bgfx::destroy(_shadowVolume.m_ibBackCap);
}
}
@@ -1844,804 +1822,875 @@ bool clipTest(const float* _planes, uint8_t _planeNum, const Mesh& _mesh, const
return false;
}
-int _main_(int _argc, char** _argv)
+struct ShadowVolumeProgramType
{
- Args args(_argc, _argv);
-
- ViewState viewState(1280, 720);
- ClearValues clearValues = {0x00000000, 1.0f, 0};
+ enum Enum
+ {
+ Blank = 0,
+ Color,
+ Tex1,
+ Tex2,
- uint32_t debug = BGFX_DEBUG_TEXT;
- uint32_t reset = BGFX_RESET_VSYNC;
+ Count
+ };
+};
- bgfx::init(args.m_type, args.m_pciId);
- bgfx::reset(viewState.m_width, viewState.m_height, reset);
+struct ShadowVolumePart
+{
+ enum Enum
+ {
+ Back = 0,
+ Side,
+ Front,
- // Enable debug text.
- bgfx::setDebug(debug);
+ Count
+ };
+};
- const bgfx::Caps* caps = bgfx::getCaps();
- s_oglNdc = caps->homogeneousDepth;
- s_texelHalf = bgfx::RendererType::Direct3D9 == caps->rendererType ? 0.5f : 0.0f;
+enum LightPattern
+{
+ LightPattern0 = 0,
+ LightPattern1
+};
- // Imgui
- imguiCreate();
+enum MeshChoice
+{
+ BunnyHighPoly = 0,
+ BunnyLowPoly
+};
- PosNormalTexcoordVertex::init();
+enum Scene
+{
+ Scene0 = 0,
+ Scene1,
- s_uniforms.init();
- s_uniforms.submitConstUniforms();
+ SceneCount
+};
- bgfx::TextureHandle figureTex = loadTexture("textures/figure-rgba.dds");
- bgfx::TextureHandle flareTex = loadTexture("textures/flare.dds");
- bgfx::TextureHandle fieldstoneTex = loadTexture("textures/fieldstone-rgba.dds");
+class ExampleShadowVolumes : public entry::AppI
+{
+public:
+ ExampleShadowVolumes(const char* _name, const char* _description)
+ : entry::AppI(_name, _description)
+ {
+ }
- bgfx::TextureHandle fbtextures[] =
+ void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
{
- bgfx::createTexture2D(uint16_t(viewState.m_width), uint16_t(viewState.m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_RT),
- bgfx::createTexture2D(uint16_t(viewState.m_width), uint16_t(viewState.m_height), false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_WRITE_ONLY),
- };
- s_stencilFb = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ Args args(_argc, _argv);
- s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
- s_texStencil = bgfx::createUniform("s_texStencil", bgfx::UniformType::Int1);
+ m_viewState = ViewState(_width, _height);
+ m_clearValues = { 0x00000000, 1.0f, 0 };
- bgfx::ProgramHandle programTextureLighting = loadProgram("vs_shadowvolume_texture_lighting", "fs_shadowvolume_texture_lighting");
- bgfx::ProgramHandle programColorLighting = loadProgram("vs_shadowvolume_color_lighting", "fs_shadowvolume_color_lighting" );
- bgfx::ProgramHandle programColorTexture = loadProgram("vs_shadowvolume_color_texture", "fs_shadowvolume_color_texture" );
- bgfx::ProgramHandle programTexture = loadProgram("vs_shadowvolume_texture", "fs_shadowvolume_texture" );
+ m_debug = BGFX_DEBUG_NONE;
+ m_reset = BGFX_RESET_VSYNC;
- bgfx::ProgramHandle programBackBlank = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbackblank" );
- bgfx::ProgramHandle programSideBlank = loadProgram("vs_shadowvolume_svside", "fs_shadowvolume_svsideblank" );
- bgfx::ProgramHandle programFrontBlank = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfrontblank");
+ bgfx::init(args.m_type, args.m_pciId);
+ bgfx::reset(m_viewState.m_width, m_viewState.m_height, m_reset);
- bgfx::ProgramHandle programBackColor = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbackcolor" );
- bgfx::ProgramHandle programSideColor = loadProgram("vs_shadowvolume_svside", "fs_shadowvolume_svsidecolor" );
- bgfx::ProgramHandle programFrontColor = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfrontcolor");
+ // Enable debug text.
+ bgfx::setDebug(m_debug);
- bgfx::ProgramHandle programSideTex = loadProgram("vs_shadowvolume_svside", "fs_shadowvolume_svsidetex" );
- bgfx::ProgramHandle programBackTex1 = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbacktex1" );
- bgfx::ProgramHandle programBackTex2 = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbacktex2" );
- bgfx::ProgramHandle programFrontTex1 = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfronttex1" );
- bgfx::ProgramHandle programFrontTex2 = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfronttex2" );
+ const bgfx::Caps* caps = bgfx::getCaps();
+ s_oglNdc = caps->homogeneousDepth;
+ s_texelHalf = bgfx::RendererType::Direct3D9 == caps->rendererType ? 0.5f : 0.0f;
- struct ShadowVolumeProgramType
- {
- enum Enum
- {
- Blank = 0,
- Color,
- Tex1,
- Tex2,
+ // Imgui
+ imguiCreate();
- Count
- };
- };
+ PosNormalTexcoordVertex::init();
- struct ShadowVolumePart
- {
- enum Enum
- {
- Back = 0,
- Side,
- Front,
+ s_uniforms.init();
+
+ m_figureTex = loadTexture("textures/figure-rgba.dds");
+ m_flareTex = loadTexture("textures/flare.dds");
+ m_fieldstoneTex = loadTexture("textures/fieldstone-rgba.dds");
- Count
+ bgfx::TextureHandle fbtextures[] =
+ {
+ bgfx::createTexture2D(uint16_t(m_viewState.m_width), uint16_t(m_viewState.m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_RT),
+ bgfx::createTexture2D(uint16_t(m_viewState.m_width), uint16_t(m_viewState.m_height), false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_WRITE_ONLY),
};
- };
- bgfx::ProgramHandle svProgs[ShadowVolumeProgramType::Count][ShadowVolumePart::Count] =
- {
- { programBackBlank, programSideBlank, programFrontBlank }, // Blank
- { programBackColor, programSideColor, programFrontColor }, // Color
- { programBackTex1, programSideTex, programFrontTex1 }, // Tex1
- { programBackTex2, programSideTex, programFrontTex2 }, // Tex2
- };
+ s_stencilFb = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
- Model bunnyLowPolyModel;
- Model bunnyHighPolyModel;
- Model columnModel;
- Model platformModel;
- Model cubeModel;
- Model hplaneFieldModel;
- Model hplaneFigureModel;
- Model vplaneModel;
+ s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
+ s_texStencil = bgfx::createUniform("s_texStencil", bgfx::UniformType::Int1);
- bunnyHighPolyModel.load("meshes/bunny_patched.bin");
- bunnyHighPolyModel.m_program = programColorLighting;
+ m_programTextureLighting = loadProgram("vs_shadowvolume_texture_lighting", "fs_shadowvolume_texture_lighting");
+ m_programColorLighting = loadProgram("vs_shadowvolume_color_lighting", "fs_shadowvolume_color_lighting" );
+ m_programColorTexture = loadProgram("vs_shadowvolume_color_texture", "fs_shadowvolume_color_texture" );
+ m_programTexture = loadProgram("vs_shadowvolume_texture", "fs_shadowvolume_texture" );
- bunnyLowPolyModel.load("meshes/bunny_decimated.bin");
- bunnyLowPolyModel.m_program = programColorLighting;
+ m_programBackBlank = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbackblank" );
+ m_programSideBlank = loadProgram("vs_shadowvolume_svside", "fs_shadowvolume_svsideblank" );
+ m_programFrontBlank = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfrontblank");
- columnModel.load("meshes/column.bin");
- columnModel.m_program = programColorLighting;
+ m_programBackColor = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbackcolor" );
+ m_programSideColor = loadProgram("vs_shadowvolume_svside", "fs_shadowvolume_svsidecolor" );
+ m_programFrontColor = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfrontcolor");
- platformModel.load("meshes/platform.bin");
- platformModel.m_program = programTextureLighting;
- platformModel.m_texture = figureTex;
+ m_programSideTex = loadProgram("vs_shadowvolume_svside", "fs_shadowvolume_svsidetex" );
+ m_programBackTex1 = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbacktex1" );
+ m_programBackTex2 = loadProgram("vs_shadowvolume_svback", "fs_shadowvolume_svbacktex2" );
+ m_programFrontTex1 = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfronttex1" );
+ m_programFrontTex2 = loadProgram("vs_shadowvolume_svfront", "fs_shadowvolume_svfronttex2" );
- cubeModel.load("meshes/cube.bin");
- cubeModel.m_program = programTextureLighting;
- cubeModel.m_texture = figureTex;
+ bgfx::ProgramHandle svProgs[ShadowVolumeProgramType::Count][ShadowVolumePart::Count] =
+ {
+ { m_programBackBlank, m_programSideBlank, m_programFrontBlank }, // Blank
+ { m_programBackColor, m_programSideColor, m_programFrontColor }, // Color
+ { m_programBackTex1, m_programSideTex, m_programFrontTex1 }, // Tex1
+ { m_programBackTex2, m_programSideTex, m_programFrontTex2 }, // Tex2
+ };
+ bx::memCopy(m_svProgs, svProgs, sizeof(svProgs));
- hplaneFieldModel.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
- hplaneFieldModel.m_program = programTextureLighting;
- hplaneFieldModel.m_texture = fieldstoneTex;
+ m_bunnyHighPolyModel.load("meshes/bunny_patched.bin");
+ m_bunnyHighPolyModel.m_program = m_programColorLighting;
- hplaneFigureModel.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
- hplaneFigureModel.m_program = programTextureLighting;
- hplaneFigureModel.m_texture = figureTex;
+ m_bunnyLowPolyModel.load("meshes/bunny_decimated.bin");
+ m_bunnyLowPolyModel.m_program = m_programColorLighting;
- vplaneModel.load(s_vplaneVertices, BX_COUNTOF(s_vplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
- vplaneModel.m_program = programColorTexture;
- vplaneModel.m_texture = flareTex;
+ m_columnModel.load("meshes/column.bin");
+ m_columnModel.m_program = m_programColorLighting;
- // Setup lights.
- const float rgbInnerR[MAX_LIGHTS_COUNT][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
- };
+ m_platformModel.load("meshes/platform.bin");
+ m_platformModel.m_program = m_programTextureLighting;
+ m_platformModel.m_texture = m_figureTex;
- float lightRgbInnerR[MAX_LIGHTS_COUNT][4];
- for (uint8_t ii = 0, jj = 0; ii < MAX_LIGHTS_COUNT; ++ii, ++jj)
- {
- const uint8_t index = jj%MAX_LIGHTS_COUNT;
- lightRgbInnerR[ii][0] = rgbInnerR[index][0];
- lightRgbInnerR[ii][1] = rgbInnerR[index][1];
- lightRgbInnerR[ii][2] = rgbInnerR[index][2];
- lightRgbInnerR[ii][3] = rgbInnerR[index][3];
- }
+ m_cubeModel.load("meshes/cube.bin");
+ m_cubeModel.m_program = m_programTextureLighting;
+ m_cubeModel.m_texture = m_figureTex;
- int64_t profTime = 0;
- int64_t timeOffset = bx::getHPCounter();
-
- uint32_t numShadowVolumeVertices = 0;
- uint32_t numShadowVolumeIndices = 0;
-
- uint32_t oldWidth = 0;
- uint32_t oldHeight = 0;
-
- // Imgui.
- bool settings_showHelp = false;
- bool settings_updateLights = true;
- bool settings_updateScene = true;
- bool settings_mixedSvImpl = true;
- bool settings_useStencilTexture = false;
- bool settings_drawShadowVolumes = false;
- float settings_numLights = 1.0f;
- float settings_instanceCount = 9.0f;
- ShadowVolumeImpl::Enum settings_shadowVolumeImpl = ShadowVolumeImpl::DepthFail;
- ShadowVolumeAlgorithm::Enum settings_shadowVolumeAlgorithm = ShadowVolumeAlgorithm::EdgeBased;
- int32_t scrollAreaRight = 0;
-
- const char* titles[2] =
- {
- "Scene 0",
- "Scene 1",
- };
+ m_hplaneFieldModel.load(s_hplaneVertices
+ , BX_COUNTOF(s_hplaneVertices)
+ , PosNormalTexcoordVertex::ms_decl
+ , s_planeIndices
+ , BX_COUNTOF(s_planeIndices)
+ );
+ m_hplaneFieldModel.m_program = m_programTextureLighting;
+ m_hplaneFieldModel.m_texture = m_fieldstoneTex;
+
+ m_hplaneFigureModel.load(s_hplaneVertices
+ , BX_COUNTOF(s_hplaneVertices)
+ , PosNormalTexcoordVertex::ms_decl
+ , s_planeIndices
+ , BX_COUNTOF(s_planeIndices)
+ );
+ m_hplaneFigureModel.m_program = m_programTextureLighting;
+ m_hplaneFigureModel.m_texture = m_figureTex;
+
+ m_vplaneModel.load(s_vplaneVertices
+ , BX_COUNTOF(s_vplaneVertices)
+ , PosNormalTexcoordVertex::ms_decl
+ , s_planeIndices
+ , BX_COUNTOF(s_planeIndices)
+ );
+ m_vplaneModel.m_program = m_programColorTexture;
+ m_vplaneModel.m_texture = m_flareTex;
- enum LightPattern
- {
- LightPattern0 = 0,
- LightPattern1
- };
+ // Setup lights.
+ const float rgbInnerR[MAX_LIGHTS_COUNT][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
+ };
- enum MeshChoice
- {
- BunnyHighPoly = 0,
- BunnyLowPoly
- };
+ for (uint8_t ii = 0, jj = 0; ii < MAX_LIGHTS_COUNT; ++ii, ++jj)
+ {
+ const uint8_t index = jj%MAX_LIGHTS_COUNT;
+ 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];
+ }
+
+ m_profTime = 0;
+ m_timeOffset = bx::getHPCounter();
+
+ m_numShadowVolumeVertices = 0;
+ m_numShadowVolumeIndices = 0;
+
+ m_oldWidth = 0;
+ m_oldHeight = 0;
+
+ // Imgui.
+ m_showHelp = false;
+ m_updateLights = true;
+ m_updateScene = true;
+ m_mixedSvImpl = true;
+ m_useStencilTexture = false;
+ m_drawShadowVolumes = false;
+ m_numLights = 1;
+ m_instanceCount = 9;
+ m_shadowVolumeImpl = ShadowVolumeImpl::DepthFail;
+ m_shadowVolumeAlgorithm = ShadowVolumeAlgorithm::EdgeBased;
+
+ m_lightPattern = LightPattern0;
+ m_currentMesh = BunnyLowPoly;
+ m_currentScene = Scene0;
+
+ // Set view matrix
+ cameraCreate();
+ float initialPos[3] = { 3.0f, 20.0f, -58.0f };
+ cameraSetPosition(initialPos);
+ cameraSetVerticalAngle(-0.25f);
+ cameraGetViewMtx(m_viewState.m_view);
+ }
- enum Scene
+ virtual int shutdown() override
{
- Scene0 = 0,
- Scene1,
+ // Cleanup
+ m_bunnyLowPolyModel.unload();
+ m_bunnyHighPolyModel.unload();
+ m_columnModel.unload();
+ m_cubeModel.unload();
+ m_platformModel.unload();
+ m_hplaneFieldModel.unload();
+ m_hplaneFigureModel.unload();
+ m_vplaneModel.unload();
+
+ s_uniforms.destroy();
+
+ bgfx::destroy(s_texColor);
+ bgfx::destroy(s_texStencil);
+ bgfx::destroy(s_stencilFb);
+
+ bgfx::destroy(m_figureTex);
+ bgfx::destroy(m_fieldstoneTex);
+ bgfx::destroy(m_flareTex);
+
+ bgfx::destroy(m_programTextureLighting);
+ bgfx::destroy(m_programColorLighting);
+ bgfx::destroy(m_programColorTexture);
+ bgfx::destroy(m_programTexture);
+
+ bgfx::destroy(m_programBackBlank);
+ bgfx::destroy(m_programSideBlank);
+ bgfx::destroy(m_programFrontBlank);
+ bgfx::destroy(m_programBackColor);
+ bgfx::destroy(m_programSideColor);
+ bgfx::destroy(m_programFrontColor);
+ bgfx::destroy(m_programSideTex);
+ bgfx::destroy(m_programBackTex1);
+ bgfx::destroy(m_programBackTex2);
+ bgfx::destroy(m_programFrontTex1);
+ bgfx::destroy(m_programFrontTex2);
+
+ cameraDestroy();
+ imguiDestroy();
+
+ // Shutdown bgfx.
+ bgfx::shutdown();
+
+ return 0;
+ }
- SceneCount
- };
+ bool update() override
+ {
+ if (!entry::processEvents(m_viewState.m_width, m_viewState.m_height, m_debug, m_reset, &m_mouseState) )
+ {
+ s_uniforms.submitConstUniforms();
- LightPattern lightPattern = LightPattern0;
- MeshChoice currentMesh = BunnyLowPoly;
- Scene currentScene = Scene0;
+ // Set projection matrices.
+ const float fov = 60.0f;
+ const float aspect = float(m_viewState.m_width)/float(m_viewState.m_height);
+ const float nearPlane = 1.0f;
+ const float farPlane = 1000.0f;
- // Set view and projection matrices.
- const float fov = 60.0f;
- const float aspect = float(viewState.m_width)/float(viewState.m_height);
- const float nearPlane = 1.0f;
- const float farPlane = 1000.0f;
+ // Respond properly on resize.
+ if (m_oldWidth != m_viewState.m_width
+ || m_oldHeight != m_viewState.m_height)
+ {
+ m_oldWidth = m_viewState.m_width;
+ m_oldHeight = m_viewState.m_height;
- float initialPos[3] = { 3.0f, 20.0f, -58.0f };
- cameraCreate();
- cameraSetPosition(initialPos);
- cameraSetVerticalAngle(-0.25f);
- cameraGetViewMtx(viewState.m_view);
+ bgfx::destroy(s_stencilFb);
- entry::MouseState mouseState;
- while (!entry::processEvents(viewState.m_width, viewState.m_height, debug, reset, &mouseState) )
- {
- // Respond properly on resize.
- if (oldWidth != viewState.m_width
- || oldHeight != viewState.m_height)
- {
- oldWidth = viewState.m_width;
- oldHeight = viewState.m_height;
+ bgfx::TextureHandle fbtextures[] =
+ {
+ bgfx::createTexture2D(uint16_t(m_viewState.m_width), uint16_t(m_viewState.m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_RT),
+ bgfx::createTexture2D(uint16_t(m_viewState.m_width), uint16_t(m_viewState.m_height), false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_WRITE_ONLY)
+ };
+ s_stencilFb = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ }
- bgfx::destroyFrameBuffer(s_stencilFb);
+ // 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;
+ 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);
+
+ // Set view and projection matrix for view 0.
+ const bgfx::HMD* hmd = bgfx::getHMD();
+ if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
+ {
+ float eye[3];
+ cameraGetPosition(eye);
- fbtextures[0] = bgfx::createTexture2D(uint16_t(viewState.m_width), uint16_t(viewState.m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_RT);
- fbtextures[1] = bgfx::createTexture2D(uint16_t(viewState.m_width), uint16_t(viewState.m_height), false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_WRITE_ONLY);
- s_stencilFb = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
- }
+ bx::mtxQuatTranslationHMD(m_viewState.m_view, hmd->eye[0].rotation, eye);
+ bx::mtxProj(m_viewState.m_proj, hmd->eye[0].fov, nearPlane, farPlane, s_oglNdc);
- // 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;
- float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) );
- const float deltaTime = float(frameTime/freq);
- s_uniforms.m_time = time;
-
- // Update camera.
- cameraUpdate(deltaTime, mouseState);
-
- // Set view and projection matrix for view 0.
- const bgfx::HMD* hmd = bgfx::getHMD();
- if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
- {
- float eye[3];
- cameraGetPosition(eye);
+ m_viewState.m_width = hmd->width;
+ m_viewState.m_height = hmd->height;
+ }
+ else
+ {
+ cameraGetViewMtx(m_viewState.m_view);
+ bx::mtxProj(m_viewState.m_proj, fov, aspect, nearPlane, farPlane, s_oglNdc);
+ }
- bx::mtxQuatTranslationHMD(viewState.m_view, hmd->eye[0].rotation, eye);
- bx::mtxProj(viewState.m_proj, hmd->eye[0].fov, nearPlane, farPlane, s_oglNdc);
+ 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)
+ );
- viewState.m_width = hmd->width;
- viewState.m_height = hmd->height;
- }
- else
- {
- cameraGetViewMtx(viewState.m_view);
- bx::mtxProj(viewState.m_proj, fov, aspect, nearPlane, farPlane, s_oglNdc);
- }
+ showExampleDialog(this);
- 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)
- );
+ ImGui::SetNextWindowPos(ImVec2(m_viewState.m_width - 256.0f, 10.0f) );
+ ImGui::Begin("Settings"
+ , NULL
+ , ImVec2(256.0f, 700.0f)
+ , ImGuiWindowFlags_AlwaysAutoResize
+ );
- imguiBeginScrollArea("Settings", viewState.m_width - 256 - 10, 10, 256, 700, &scrollAreaRight);
+ const char* titles[2] =
+ {
+ "Scene 0",
+ "Scene 1",
+ };
- if (imguiCheck(titles[Scene0], Scene0 == currentScene) )
- {
- currentScene = Scene0;
- }
+ if (ImGui::RadioButton(titles[Scene0], Scene0 == m_currentScene) )
+ {
+ m_currentScene = Scene0;
+ }
- if (imguiCheck(titles[Scene1], Scene1 == currentScene) )
- {
- currentScene = Scene1;
- }
+ if (ImGui::RadioButton(titles[Scene1], Scene1 == m_currentScene) )
+ {
+ m_currentScene = Scene1;
+ }
- imguiSlider("Lights", settings_numLights, 1.0f, float(MAX_LIGHTS_COUNT), 1.0f);
+ ImGui::SliderInt("Lights", &m_numLights, 1, MAX_LIGHTS_COUNT);
+ ImGui::Checkbox("Update lights", &m_updateLights);
+ ImGui::Indent();
- if (imguiCheck("Update lights", settings_updateLights) )
- {
- settings_updateLights = !settings_updateLights;
- }
+ if (ImGui::RadioButton("Light pattern 0", LightPattern0 == m_lightPattern) )
+ {
+ m_lightPattern = LightPattern0;
+ }
- imguiIndent();
+ if (ImGui::RadioButton("Light pattern 1", LightPattern1 == m_lightPattern) )
+ {
+ m_lightPattern = LightPattern1;
+ }
- if (imguiCheck("Light pattern 0", LightPattern0 == lightPattern, settings_updateLights) )
- {
- lightPattern = LightPattern0;
- }
+ ImGui::Unindent();
- if (imguiCheck("Light pattern 1", LightPattern1 == lightPattern, settings_updateLights) )
- {
- lightPattern = LightPattern1;
- }
+ if ( Scene0 == m_currentScene )
+ {
+ ImGui::Checkbox("Update scene", &m_updateScene);
+ }
- imguiUnindent();
+ ImGui::Separator();
- if (imguiCheck("Update scene", settings_updateScene, Scene0 == currentScene) )
- {
- settings_updateScene = !settings_updateScene;
- }
+ ImGui::Text("Stencil buffer implementation:");
+ ImGui::Checkbox("Mixed", &m_mixedSvImpl);
+ if (!m_mixedSvImpl)
+ {
+ m_shadowVolumeImpl = (ImGui::RadioButton("Depth fail", ShadowVolumeImpl::DepthFail == m_shadowVolumeImpl) ? ShadowVolumeImpl::DepthFail : m_shadowVolumeImpl);
+ m_shadowVolumeImpl = (ImGui::RadioButton("Depth pass", ShadowVolumeImpl::DepthPass == m_shadowVolumeImpl) ? ShadowVolumeImpl::DepthPass : m_shadowVolumeImpl);
+ }
- imguiSeparatorLine();
- imguiLabel("Stencil buffer implementation:");
- settings_shadowVolumeImpl = (imguiCheck("Depth fail", ShadowVolumeImpl::DepthFail == settings_shadowVolumeImpl, !settings_mixedSvImpl) ? ShadowVolumeImpl::DepthFail : settings_shadowVolumeImpl);
- settings_shadowVolumeImpl = (imguiCheck("Depth pass", ShadowVolumeImpl::DepthPass == settings_shadowVolumeImpl, !settings_mixedSvImpl) ? ShadowVolumeImpl::DepthPass : settings_shadowVolumeImpl);
- settings_mixedSvImpl = (imguiCheck("Mixed", settings_mixedSvImpl) ? !settings_mixedSvImpl : settings_mixedSvImpl);
+ ImGui::Text("Shadow volume implementation:");
+ m_shadowVolumeAlgorithm = (ImGui::RadioButton("Face based impl.", ShadowVolumeAlgorithm::FaceBased == m_shadowVolumeAlgorithm) ? ShadowVolumeAlgorithm::FaceBased : m_shadowVolumeAlgorithm);
+ m_shadowVolumeAlgorithm = (ImGui::RadioButton("Edge based impl.", ShadowVolumeAlgorithm::EdgeBased == m_shadowVolumeAlgorithm) ? ShadowVolumeAlgorithm::EdgeBased : m_shadowVolumeAlgorithm);
- imguiLabel("Shadow volume implementation:");
- settings_shadowVolumeAlgorithm = (imguiCheck("Face based impl.", ShadowVolumeAlgorithm::FaceBased == settings_shadowVolumeAlgorithm) ? ShadowVolumeAlgorithm::FaceBased : settings_shadowVolumeAlgorithm);
- settings_shadowVolumeAlgorithm = (imguiCheck("Edge based impl.", ShadowVolumeAlgorithm::EdgeBased == settings_shadowVolumeAlgorithm) ? ShadowVolumeAlgorithm::EdgeBased : settings_shadowVolumeAlgorithm);
+ ImGui::Text("Stencil:");
+ if (ImGui::RadioButton("Use stencil buffer", !m_useStencilTexture) )
+ {
+ if (m_useStencilTexture)
+ {
+ m_useStencilTexture = false;
+ }
+ }
+ if (ImGui::RadioButton("Use texture as stencil", m_useStencilTexture) )
+ {
+ if (!m_useStencilTexture)
+ {
+ m_useStencilTexture = true;
+ }
+ }
- imguiLabel("Stencil:");
- if (imguiCheck("Use stencil buffer", !settings_useStencilTexture) )
- {
- if (settings_useStencilTexture)
+ ImGui::Separator();
+ ImGui::Text("Mesh:");
+ if (ImGui::RadioButton("Bunny - high poly", BunnyHighPoly == m_currentMesh) )
{
- settings_useStencilTexture = false;
+ m_currentMesh = BunnyHighPoly;
}
- }
- if (imguiCheck("Use texture as stencil", settings_useStencilTexture) )
- {
- if (!settings_useStencilTexture)
+
+ if (ImGui::RadioButton("Bunny - low poly", BunnyLowPoly == m_currentMesh) )
{
- settings_useStencilTexture = true;
+ m_currentMesh = BunnyLowPoly;
}
- }
- imguiSeparatorLine();
- imguiLabel("Mesh:");
- if (imguiCheck("Bunny - high poly", BunnyHighPoly == currentMesh) )
- {
- currentMesh = BunnyHighPoly;
- }
+ if (Scene1 == m_currentScene)
+ {
+ ImGui::SliderInt("Instance count", &m_instanceCount, 1, MAX_INSTANCE_COUNT);
+ }
- if (imguiCheck("Bunny - low poly", BunnyLowPoly == currentMesh) )
- {
- currentMesh = BunnyLowPoly;
- }
+ ImGui::Text("CPU Time: %7.1f [ms]", double(m_profTime)*toMs);
+ ImGui::Text("Volume Vertices: %5.uk", m_numShadowVolumeVertices/1000);
+ ImGui::Text("Volume Indices: %6.uk", m_numShadowVolumeIndices/1000);
+ m_numShadowVolumeVertices = 0;
+ m_numShadowVolumeIndices = 0;
- if (Scene1 == currentScene)
- {
- imguiSlider("Instance count", settings_instanceCount, 1.0f, float(MAX_INSTANCE_COUNT), 1.0f);
- }
+ ImGui::Separator();
+ ImGui::Checkbox("Draw Shadow Volumes", &m_drawShadowVolumes);
- imguiLabel("CPU Time: %7.1f [ms]", double(profTime)*toMs);
- imguiLabel("Volume Vertices: %5.uk", numShadowVolumeVertices/1000);
- imguiLabel("Volume Indices: %6.uk", numShadowVolumeIndices/1000);
- numShadowVolumeVertices = 0;
- numShadowVolumeIndices = 0;
-
- imguiSeparatorLine();
- settings_drawShadowVolumes = imguiCheck("Draw Shadow Volumes", settings_drawShadowVolumes)
- ? !settings_drawShadowVolumes
- : settings_drawShadowVolumes
- ;
- imguiIndent();
- imguiUnindent();
-
- imguiEndScrollArea();
-
- static int32_t scrollAreaLeft = 0;
- imguiBeginScrollArea("Show help:", 10, viewState.m_height - 77 - 10, 120, 77, &scrollAreaLeft);
- settings_showHelp = imguiButton(settings_showHelp ? "ON" : "OFF")
- ? !settings_showHelp
- : settings_showHelp
- ;
-
- imguiEndScrollArea();
-
- imguiEndFrame();
-
- //update settings
- s_uniforms.m_params.m_ambientPass = 1.0f;
- s_uniforms.m_params.m_lightingPass = 1.0f;
- s_uniforms.m_params.m_texelHalf = s_texelHalf;
- s_uniforms.m_svparams.m_useStencilTex = float(settings_useStencilTexture);
-
- //set picked bunny model
- Model* bunnyModel = BunnyLowPoly == currentMesh ? &bunnyLowPolyModel : &bunnyHighPolyModel;
-
- //update time accumulators
- static float sceneTimeAccumulator = 0.0f;
- if (settings_updateScene)
- {
- sceneTimeAccumulator += deltaTime;
- }
+ ImGui::End();
- static float lightTimeAccumulator = 0.0f;
- if (settings_updateLights)
- {
- lightTimeAccumulator += deltaTime;
- }
+ ImGui::SetNextWindowPos(ImVec2(10, float(m_viewState.m_height) - 77.0f - 10.0f) );
+ ImGui::Begin("Show help:"
+ , NULL
+ , ImVec2(120.0f, 77.0f)
+ , ImGuiWindowFlags_AlwaysAutoResize
+ );
- //setup light positions
- float lightPosRadius[MAX_LIGHTS_COUNT][4];
- if (LightPattern0 == lightPattern)
- {
- for (uint8_t ii = 0; ii < settings_numLights; ++ii)
- {
- lightPosRadius[ii][0] = bx::fcos(2.0f*bx::pi/settings_numLights * float(ii) + lightTimeAccumulator * 1.1f + 3.0f) * 20.0f;
- lightPosRadius[ii][1] = 20.0f;
- lightPosRadius[ii][2] = bx::fsin(2.0f*bx::pi/settings_numLights * float(ii) + lightTimeAccumulator * 1.1f + 3.0f) * 20.0f;
- lightPosRadius[ii][3] = 20.0f;
- }
- }
- else
- {
- for (uint8_t ii = 0; ii < settings_numLights; ++ii)
+ if (ImGui::Button(m_showHelp ? "ON" : "OFF") )
{
- lightPosRadius[ii][0] = bx::fcos(float(ii) * 2.0f/settings_numLights + lightTimeAccumulator * 1.3f + bx::pi) * 40.0f;
- lightPosRadius[ii][1] = 20.0f;
- lightPosRadius[ii][2] = bx::fsin(float(ii) * 2.0f/settings_numLights + lightTimeAccumulator * 1.3f + bx::pi) * 40.0f;
- lightPosRadius[ii][3] = 20.0f;
+ m_showHelp = !m_showHelp;
}
- }
- //use debug font to print information about this example.
- bgfx::dbgTextClear();
- bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/14-shadowvolumes");
- bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow volumes.");
- bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
+ ImGui::End();
- if (settings_showHelp)
- {
- uint8_t row = 5;
- bgfx::dbgTextPrintf(3, row++, 0x0f, "Stencil buffer implementation:");
- bgfx::dbgTextPrintf(8, row++, 0x0f, "Depth fail - Robust, but slower than 'Depth pass'. Requires computing and drawing of shadow volume caps.");
- bgfx::dbgTextPrintf(8, row++, 0x0f, "Depth pass - Faster, but not stable. Shadows are wrong when camera is in the shadow.");
- bgfx::dbgTextPrintf(8, row++, 0x0f, "Mixed - 'Depth pass' where possible, 'Depth fail' where necessary. Best of both words.");
-
- row++;
- bgfx::dbgTextPrintf(3, row++, 0x0f, "Shadow volume implementation:");
- bgfx::dbgTextPrintf(8, row++, 0x0f, "Face Based - Slower. Works fine with either stencil buffer or texture as stencil.");
- bgfx::dbgTextPrintf(8, row++, 0x0f, "Edge Based - Faster, but requires +2 incr/decr on stencil buffer. To avoid massive redraw, use RGBA texture as stencil.");
-
- row++;
- bgfx::dbgTextPrintf(3, row++, 0x0f, "Stencil:");
- bgfx::dbgTextPrintf(8, row++, 0x0f, "Stencil buffer - Faster, but capable only of +1 incr.");
- bgfx::dbgTextPrintf(8, row++, 0x0f, "Texture as stencil - Slower, but capable of +2 incr.");
- }
+ imguiEndFrame();
- // Setup instances
- Instance shadowCasters[SceneCount][60];
- uint16_t shadowCastersCount[SceneCount];
- for (uint8_t ii = 0; ii < SceneCount; ++ii)
- {
- shadowCastersCount[ii] = 0;
- }
+ //update settings
+ s_uniforms.m_params.m_ambientPass = 1.0f;
+ s_uniforms.m_params.m_lightingPass = 1.0f;
+ s_uniforms.m_params.m_texelHalf = s_texelHalf;
+ s_uniforms.m_svparams.m_useStencilTex = float(m_useStencilTexture);
- Instance shadowReceivers[SceneCount][10];
- uint16_t shadowReceiversCount[SceneCount];
- for (uint8_t ii = 0; ii < SceneCount; ++ii)
- {
- shadowReceiversCount[ii] = 0;
- }
+ //set picked bunny model
+ Model* bunnyModel = BunnyLowPoly == m_currentMesh ? &m_bunnyLowPolyModel : &m_bunnyHighPolyModel;
- // Scene 0 - shadow casters - Bunny
- {
- Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
- inst.m_scale[0] = 5.0f;
- inst.m_scale[1] = 5.0f;
- inst.m_scale[2] = 5.0f;
- inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = float(4.0f - sceneTimeAccumulator * 0.7f);
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = 0.0f;
- inst.m_pos[1] = 10.0f;
- inst.m_pos[2] = 0.0f;
- inst.m_color[0] = 0.68f;
- inst.m_color[1] = 0.65f;
- inst.m_color[2] = 0.60f;
- inst.m_model = bunnyModel;
- }
+ //update time accumulators
+ static float sceneTimeAccumulator = 0.0f;
+ if (m_updateScene)
+ {
+ sceneTimeAccumulator += deltaTime;
+ }
- // Scene 0 - shadow casters - Cubes top.
- const uint8_t numCubesTop = 9;
- for (uint16_t ii = 0; ii < numCubesTop; ++ii)
- {
- Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
- inst.m_scale[0] = 1.0f;
- inst.m_scale[1] = 1.0f;
- inst.m_scale[2] = 1.0f;
- inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = 0.0f;
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = bx::fsin(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
- inst.m_pos[1] = 6.0f;
- inst.m_pos[2] = bx::fcos(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
- inst.m_model = &cubeModel;
- }
+ static float lightTimeAccumulator = 0.0f;
+ if (m_updateLights)
+ {
+ lightTimeAccumulator += deltaTime;
+ }
- // Scene 0 - shadow casters - Cubes bottom.
- const uint8_t numCubesBottom = 9;
- for (uint16_t ii = 0; ii < numCubesBottom; ++ii)
- {
- Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
- inst.m_scale[0] = 1.0f;
- inst.m_scale[1] = 1.0f;
- inst.m_scale[2] = 1.0f;
- inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = 0.0f;
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = bx::fsin(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
- inst.m_pos[1] = 22.0f;
- inst.m_pos[2] = bx::fcos(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
- inst.m_model = &cubeModel;
- }
+ //setup light positions
+ float lightPosRadius[MAX_LIGHTS_COUNT][4];
+ if (LightPattern0 == m_lightPattern)
+ {
+ for (uint8_t ii = 0; ii < m_numLights; ++ii)
+ {
+ lightPosRadius[ii][0] = bx::fcos(2.0f*bx::kPi/float(m_numLights) * float(ii) + lightTimeAccumulator * 1.1f + 3.0f) * 20.0f;
+ lightPosRadius[ii][1] = 20.0f;
+ lightPosRadius[ii][2] = bx::fsin(2.0f*bx::kPi/float(m_numLights) * float(ii) + lightTimeAccumulator * 1.1f + 3.0f) * 20.0f;
+ lightPosRadius[ii][3] = 20.0f;
+ }
+ }
+ else
+ {
+ for (uint8_t ii = 0; ii < m_numLights; ++ii)
+ {
+ lightPosRadius[ii][0] = bx::fcos(float(ii) * 2.0f/float(m_numLights) + lightTimeAccumulator * 1.3f + bx::kPi) * 40.0f;
+ lightPosRadius[ii][1] = 20.0f;
+ lightPosRadius[ii][2] = bx::fsin(float(ii) * 2.0f/float(m_numLights) + lightTimeAccumulator * 1.3f + bx::kPi) * 40.0f;
+ lightPosRadius[ii][3] = 20.0f;
+ }
+ }
- // Scene 0 - shadow casters - Columns.
- const float dist = 16.0f;
- const float columnPositions[][3] =
- {
- { dist, 3.3f, dist },
- { -dist, 3.3f, dist },
- { dist, 3.3f, -dist },
- { -dist, 3.3f, -dist },
- };
+ if (m_showHelp)
+ {
+ uint8_t row = 5;
+ bgfx::dbgTextPrintf(3, row++, 0x0f, "Stencil buffer implementation:");
+ bgfx::dbgTextPrintf(8, row++, 0x0f, "Depth fail - Robust, but slower than 'Depth pass'. Requires computing and drawing of shadow volume caps.");
+ bgfx::dbgTextPrintf(8, row++, 0x0f, "Depth pass - Faster, but not stable. Shadows are wrong when camera is in the shadow.");
+ bgfx::dbgTextPrintf(8, row++, 0x0f, "Mixed - 'Depth pass' where possible, 'Depth fail' where necessary. Best of both words.");
+
+ row++;
+ bgfx::dbgTextPrintf(3, row++, 0x0f, "Shadow volume implementation:");
+ bgfx::dbgTextPrintf(8, row++, 0x0f, "Face Based - Slower. Works fine with either stencil buffer or texture as stencil.");
+ bgfx::dbgTextPrintf(8, row++, 0x0f, "Edge Based - Faster, but requires +2 incr/decr on stencil buffer. To avoid massive redraw, use RGBA texture as stencil.");
+
+ row++;
+ bgfx::dbgTextPrintf(3, row++, 0x0f, "Stencil:");
+ bgfx::dbgTextPrintf(8, row++, 0x0f, "Stencil buffer - Faster, but capable only of +1 incr.");
+ bgfx::dbgTextPrintf(8, row++, 0x0f, "Texture as stencil - Slower, but capable of +2 incr.");
+ }
- for (uint8_t ii = 0; ii < 4; ++ii)
- {
- Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
- inst.m_scale[0] = 1.5f;
- inst.m_scale[1] = 1.5f;
- inst.m_scale[2] = 1.5f;
- inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = 1.57f;
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = columnPositions[ii][0];
- inst.m_pos[1] = columnPositions[ii][1];
- inst.m_pos[2] = columnPositions[ii][2];
- inst.m_color[0] = 0.25f;
- inst.m_color[1] = 0.25f;
- inst.m_color[2] = 0.25f;
- inst.m_model = &columnModel;
- }
+ // Setup instances
+ Instance shadowCasters[SceneCount][60];
+ uint16_t shadowCastersCount[SceneCount];
+ for (uint8_t ii = 0; ii < SceneCount; ++ii)
+ {
+ shadowCastersCount[ii] = 0;
+ }
- // Scene 0 - shadow casters - Ceiling.
- {
- Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
- inst.m_scale[0] = 21.0f;
- inst.m_scale[1] = 21.0f;
- inst.m_scale[2] = 21.0f;
- inst.m_rotation[0] = bx::pi;
- inst.m_rotation[1] = 0.0f;
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = 0.0f;
- inst.m_pos[1] = 28.2f;
- inst.m_pos[2] = 0.0f;
- inst.m_model = &platformModel;
- inst.m_svExtrusionDistance = 2.0f; //prevent culling on tight view frustum
- }
+ Instance shadowReceivers[SceneCount][10];
+ uint16_t shadowReceiversCount[SceneCount];
+ for (uint8_t ii = 0; ii < SceneCount; ++ii)
+ {
+ shadowReceiversCount[ii] = 0;
+ }
- // Scene 0 - shadow casters - Platform.
- {
- Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
- inst.m_scale[0] = 24.0f;
- inst.m_scale[1] = 24.0f;
- inst.m_scale[2] = 24.0f;
- inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = 0.0f;
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = 0.0f;
- inst.m_pos[1] = 0.0f;
- inst.m_pos[2] = 0.0f;
- inst.m_model = &platformModel;
- inst.m_svExtrusionDistance = 2.0f; //prevent culling on tight view frustum
- }
+ // Scene 0 - shadow casters - Bunny
+ {
+ Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
+ inst.m_scale[0] = 5.0f;
+ inst.m_scale[1] = 5.0f;
+ inst.m_scale[2] = 5.0f;
+ inst.m_rotation[0] = 0.0f;
+ inst.m_rotation[1] = float(4.0f - sceneTimeAccumulator * 0.7f);
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = 0.0f;
+ inst.m_pos[1] = 10.0f;
+ inst.m_pos[2] = 0.0f;
+ inst.m_color[0] = 0.68f;
+ inst.m_color[1] = 0.65f;
+ inst.m_color[2] = 0.60f;
+ inst.m_model = bunnyModel;
+ }
- // Scene 0 - shadow receivers - Floor.
- {
- Instance& inst = shadowReceivers[Scene0][shadowReceiversCount[Scene0]++];
- inst.m_scale[0] = 500.0f;
- inst.m_scale[1] = 500.0f;
- inst.m_scale[2] = 500.0f;
- inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = 0.0f;
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = 0.0f;
- inst.m_pos[1] = 0.0f;
- inst.m_pos[2] = 0.0f;
- inst.m_model = &hplaneFieldModel;
- }
+ // Scene 0 - shadow casters - Cubes top.
+ const uint8_t numCubesTop = 9;
+ for (uint16_t ii = 0; ii < numCubesTop; ++ii)
+ {
+ Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
+ inst.m_scale[0] = 1.0f;
+ inst.m_scale[1] = 1.0f;
+ inst.m_scale[2] = 1.0f;
+ inst.m_rotation[0] = 0.0f;
+ inst.m_rotation[1] = 0.0f;
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = bx::fsin(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
+ inst.m_pos[1] = 6.0f;
+ inst.m_pos[2] = bx::fcos(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
+ inst.m_model = &m_cubeModel;
+ }
- // Scene 1 - shadow casters - Bunny instances
- {
- enum Direction
+ // Scene 0 - shadow casters - Cubes bottom.
+ const uint8_t numCubesBottom = 9;
+ for (uint16_t ii = 0; ii < numCubesBottom; ++ii)
+ {
+ Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
+ inst.m_scale[0] = 1.0f;
+ inst.m_scale[1] = 1.0f;
+ inst.m_scale[2] = 1.0f;
+ inst.m_rotation[0] = 0.0f;
+ inst.m_rotation[1] = 0.0f;
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = bx::fsin(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
+ inst.m_pos[1] = 22.0f;
+ inst.m_pos[2] = bx::fcos(ii * 2.0f + 13.0f + sceneTimeAccumulator * 1.1f) * 13.0f;
+ inst.m_model = &m_cubeModel;
+ }
+
+ // Scene 0 - shadow casters - Columns.
+ const float dist = 16.0f;
+ const float columnPositions[][3] =
{
- Left = 0x0,
- Down = 0x1,
- Right = 0x2,
- Up = 0x3,
+ { dist, 3.3f, dist },
+ { -dist, 3.3f, dist },
+ { dist, 3.3f, -dist },
+ { -dist, 3.3f, -dist },
};
- const uint8_t directionMask = 0x3;
- uint8_t currentDirection = Left;
- float currX = 0.0f;
- float currY = 0.0f;
- const float stepX = 20.0f;
- const float stepY = 20.0f;
- uint8_t stateStep = 0;
- uint8_t stateChange = 1;
+ for (uint8_t ii = 0; ii < 4; ++ii)
+ {
+ Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
+ inst.m_scale[0] = 1.5f;
+ inst.m_scale[1] = 1.5f;
+ inst.m_scale[2] = 1.5f;
+ inst.m_rotation[0] = 0.0f;
+ inst.m_rotation[1] = 1.57f;
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = columnPositions[ii][0];
+ inst.m_pos[1] = columnPositions[ii][1];
+ inst.m_pos[2] = columnPositions[ii][2];
+ inst.m_color[0] = 0.25f;
+ inst.m_color[1] = 0.25f;
+ inst.m_color[2] = 0.25f;
+ inst.m_model = &m_columnModel;
+ }
- for (uint8_t ii = 0; ii < settings_instanceCount; ++ii)
+ // Scene 0 - shadow casters - Ceiling.
{
- Instance& inst = shadowCasters[Scene1][shadowCastersCount[Scene1]++];
- inst.m_scale[0] = 5.0f;
- inst.m_scale[1] = 5.0f;
- inst.m_scale[2] = 5.0f;
+ Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
+ inst.m_scale[0] = 21.0f;
+ inst.m_scale[1] = 21.0f;
+ inst.m_scale[2] = 21.0f;
+ inst.m_rotation[0] = bx::kPi;
+ inst.m_rotation[1] = 0.0f;
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = 0.0f;
+ inst.m_pos[1] = 28.2f;
+ inst.m_pos[2] = 0.0f;
+ inst.m_model = &m_platformModel;
+ inst.m_svExtrusionDistance = 2.0f; //prevent culling on tight view frustum
+ }
+
+ // Scene 0 - shadow casters - Platform.
+ {
+ Instance& inst = shadowCasters[Scene0][shadowCastersCount[Scene0]++];
+ inst.m_scale[0] = 24.0f;
+ inst.m_scale[1] = 24.0f;
+ inst.m_scale[2] = 24.0f;
inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = bx::pi;
+ inst.m_rotation[1] = 0.0f;
inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = currX;
+ inst.m_pos[0] = 0.0f;
inst.m_pos[1] = 0.0f;
- inst.m_pos[2] = currY;
- inst.m_model = bunnyModel;
+ inst.m_pos[2] = 0.0f;
+ inst.m_model = &m_platformModel;
+ inst.m_svExtrusionDistance = 2.0f; //prevent culling on tight view frustum
+ }
+
+ // Scene 0 - shadow receivers - Floor.
+ {
+ Instance& inst = shadowReceivers[Scene0][shadowReceiversCount[Scene0]++];
+ inst.m_scale[0] = 500.0f;
+ inst.m_scale[1] = 500.0f;
+ inst.m_scale[2] = 500.0f;
+ inst.m_rotation[0] = 0.0f;
+ inst.m_rotation[1] = 0.0f;
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = 0.0f;
+ inst.m_pos[1] = 0.0f;
+ inst.m_pos[2] = 0.0f;
+ inst.m_model = &m_hplaneFieldModel;
+ }
- ++stateStep;
- if (stateStep >= ( (stateChange & ~0x1) >> 1) )
+ // Scene 1 - shadow casters - Bunny instances
+ {
+ enum Direction
{
- currentDirection = (currentDirection + 1) & directionMask;
- stateStep = 0;
- ++stateChange;
- }
+ Left = 0x0,
+ Down = 0x1,
+ Right = 0x2,
+ Up = 0x3,
+ };
+ const uint8_t directionMask = 0x3;
- switch (currentDirection)
+ uint8_t currentDirection = Left;
+ float currX = 0.0f;
+ float currY = 0.0f;
+ const float stepX = 20.0f;
+ const float stepY = 20.0f;
+ uint8_t stateStep = 0;
+ uint8_t stateChange = 1;
+
+ for (uint8_t ii = 0; ii < m_instanceCount; ++ii)
{
- case Left: currX -= stepX; break;
- case Down: currY -= stepY; break;
- case Right: currX += stepX; break;
- case Up: currY += stepY; break;
+ Instance& inst = shadowCasters[Scene1][shadowCastersCount[Scene1]++];
+ inst.m_scale[0] = 5.0f;
+ inst.m_scale[1] = 5.0f;
+ inst.m_scale[2] = 5.0f;
+ inst.m_rotation[0] = 0.0f;
+ inst.m_rotation[1] = bx::kPi;
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = currX;
+ inst.m_pos[1] = 0.0f;
+ inst.m_pos[2] = currY;
+ inst.m_model = bunnyModel;
+
+ ++stateStep;
+ if (stateStep >= ( (stateChange & ~0x1) >> 1) )
+ {
+ currentDirection = (currentDirection + 1) & directionMask;
+ stateStep = 0;
+ ++stateChange;
+ }
+
+ switch (currentDirection)
+ {
+ case Left: currX -= stepX; break;
+ case Down: currY -= stepY; break;
+ case Right: currX += stepX; break;
+ case Up: currY += stepY; break;
+ }
}
}
- }
- // Scene 1 - shadow receivers - Floor.
- {
- Instance& inst = shadowReceivers[Scene1][shadowReceiversCount[Scene1]++];
- inst.m_scale[0] = 500.0f;
- inst.m_scale[1] = 500.0f;
- inst.m_scale[2] = 500.0f;
- inst.m_rotation[0] = 0.0f;
- inst.m_rotation[1] = 0.0f;
- inst.m_rotation[2] = 0.0f;
- inst.m_pos[0] = 0.0f;
- inst.m_pos[1] = 0.0f;
- inst.m_pos[2] = 0.0f;
- inst.m_model = &hplaneFigureModel;
- }
+ // Scene 1 - shadow receivers - Floor.
+ {
+ Instance& inst = shadowReceivers[Scene1][shadowReceiversCount[Scene1]++];
+ inst.m_scale[0] = 500.0f;
+ inst.m_scale[1] = 500.0f;
+ inst.m_scale[2] = 500.0f;
+ inst.m_rotation[0] = 0.0f;
+ inst.m_rotation[1] = 0.0f;
+ inst.m_rotation[2] = 0.0f;
+ inst.m_pos[0] = 0.0f;
+ inst.m_pos[1] = 0.0f;
+ inst.m_pos[2] = 0.0f;
+ inst.m_model = &m_hplaneFigureModel;
+ }
- // Make sure at the beginning everything gets cleared.
- bgfx::setViewClear(0
+ // Make sure at the beginning everything gets cleared.
+ bgfx::setViewClear(0
, BGFX_CLEAR_COLOR
| BGFX_CLEAR_DEPTH
| BGFX_CLEAR_STENCIL
- , clearValues.m_clearRgba
- , clearValues.m_clearDepth
- , clearValues.m_clearStencil
+ , m_clearValues.m_clearRgba
+ , m_clearValues.m_clearDepth
+ , m_clearValues.m_clearStencil
);
- ::touch(0);
-
- // Draw ambient only.
- s_uniforms.m_params.m_ambientPass = 1.0f;
- s_uniforms.m_params.m_lightingPass = 0.0f;
-
- s_uniforms.m_color[0] = 1.0f;
- s_uniforms.m_color[1] = 1.0f;
- s_uniforms.m_color[2] = 1.0f;
+ ::touch(0);
- const RenderState& drawAmbient = (settings_useStencilTexture ?
- s_renderStates[RenderState::ShadowVolume_UsingStencilTexture_DrawAmbient]:
- s_renderStates[RenderState::ShadowVolume_UsingStencilBuffer_DrawAmbient]);
+ // Draw ambient only.
+ s_uniforms.m_params.m_ambientPass = 1.0f;
+ s_uniforms.m_params.m_lightingPass = 0.0f;
- // Draw shadow casters.
- for (uint8_t ii = 0; ii < shadowCastersCount[currentScene]; ++ii)
- {
- shadowCasters[currentScene][ii].submit(VIEWID_RANGE1_PASS0, drawAmbient);
- }
-
- // Draw shadow receivers.
- for (uint8_t ii = 0; ii < shadowReceiversCount[currentScene]; ++ii)
- {
- shadowReceivers[currentScene][ii].submit(VIEWID_RANGE1_PASS0, drawAmbient);
- }
+ s_uniforms.m_color[0] = 1.0f;
+ s_uniforms.m_color[1] = 1.0f;
+ s_uniforms.m_color[2] = 1.0f;
- // Using stencil texture requires rendering to separate render target. first pass is building depth buffer.
- if (settings_useStencilTexture)
- {
- bgfx::setViewClear(VIEWID_RANGE1_RT_PASS1, BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
- bgfx::setViewFrameBuffer(VIEWID_RANGE1_RT_PASS1, s_stencilFb);
-
- const RenderState& renderState = s_renderStates[RenderState::ShadowVolume_UsingStencilTexture_BuildDepth];
+ const RenderState& drawAmbient = m_useStencilTexture
+ ? s_renderStates[RenderState::ShadowVolume_UsingStencilTexture_DrawAmbient]
+ : s_renderStates[RenderState::ShadowVolume_UsingStencilBuffer_DrawAmbient]
+ ;
- for (uint8_t ii = 0; ii < shadowCastersCount[currentScene]; ++ii)
+ // Draw shadow casters.
+ for (uint8_t ii = 0; ii < shadowCastersCount[m_currentScene]; ++ii)
{
- shadowCasters[currentScene][ii].submit(VIEWID_RANGE1_RT_PASS1, renderState);
+ shadowCasters[m_currentScene][ii].submit(VIEWID_RANGE1_PASS0, drawAmbient);
}
- for (uint8_t ii = 0; ii < shadowReceiversCount[currentScene]; ++ii)
+ // Draw shadow receivers.
+ for (uint8_t ii = 0; ii < shadowReceiversCount[m_currentScene]; ++ii)
{
- shadowReceivers[currentScene][ii].submit(VIEWID_RANGE1_RT_PASS1, renderState);
+ shadowReceivers[m_currentScene][ii].submit(VIEWID_RANGE1_PASS0, drawAmbient);
}
- }
- profTime = bx::getHPCounter();
+ // Using stencil texture requires rendering to separate render target. first pass is building depth buffer.
+ if (m_useStencilTexture)
+ {
+ bgfx::setViewClear(VIEWID_RANGE1_RT_PASS1, BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
+ bgfx::setViewFrameBuffer(VIEWID_RANGE1_RT_PASS1, s_stencilFb);
- /**
- * For each light:
- * 1. Compute and draw shadow volume to stencil buffer
- * 2. Draw diffuse with stencil test
- */
- for (uint8_t ii = 0, viewId = VIEWID_RANGE15_PASS2; ii < settings_numLights; ++ii, ++viewId)
- {
- const float* lightPos = lightPosRadius[ii];
+ const RenderState& renderState = s_renderStates[RenderState::ShadowVolume_UsingStencilTexture_BuildDepth];
- bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius[ii], 4*sizeof(float) );
- bx::memCopy(s_uniforms.m_lightRgbInnerR, lightRgbInnerR[ii], 3*sizeof(float) );
- bx::memCopy(s_uniforms.m_color, lightRgbInnerR[ii], 3*sizeof(float) );
+ for (uint8_t ii = 0; ii < shadowCastersCount[m_currentScene]; ++ii)
+ {
+ shadowCasters[m_currentScene][ii].submit(VIEWID_RANGE1_RT_PASS1, renderState);
+ }
- if (settings_useStencilTexture)
+ for (uint8_t ii = 0; ii < shadowReceiversCount[m_currentScene]; ++ii)
+ {
+ shadowReceivers[m_currentScene][ii].submit(VIEWID_RANGE1_RT_PASS1, renderState);
+ }
+ }
+
+ m_profTime = bx::getHPCounter();
+
+ /**
+ * For each light:
+ * 1. Compute and draw shadow volume to stencil buffer
+ * 2. Draw diffuse with stencil test
+ */
+ for (uint8_t ii = 0, viewId = VIEWID_RANGE15_PASS2; ii < m_numLights; ++ii, ++viewId)
{
- bgfx::setViewFrameBuffer(viewId, s_stencilFb);
+ const float* lightPos = lightPosRadius[ii];
+
+ bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius[ii], 4*sizeof(float) );
+ bx::memCopy(s_uniforms.m_lightRgbInnerR, m_lightRgbInnerR[ii], 3*sizeof(float) );
+ bx::memCopy(s_uniforms.m_color, m_lightRgbInnerR[ii], 3*sizeof(float) );
+
+ if (m_useStencilTexture)
+ {
+ bgfx::setViewFrameBuffer(viewId, s_stencilFb);
- bgfx::setViewClear(viewId
+ bgfx::setViewClear(viewId
, BGFX_CLEAR_COLOR
, 0x00000000
, 1.0f
, 0
);
- }
- else
- {
- const bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE;
- bgfx::setViewFrameBuffer(viewId, invalid);
+ }
+ else
+ {
+ const bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE;
+ bgfx::setViewFrameBuffer(viewId, invalid);
- bgfx::setViewClear(viewId
+ bgfx::setViewClear(viewId
, BGFX_CLEAR_STENCIL
- , clearValues.m_clearRgba
- , clearValues.m_clearDepth
- , clearValues.m_clearStencil
+ , m_clearValues.m_clearRgba
+ , m_clearValues.m_clearDepth
+ , m_clearValues.m_clearStencil
);
- }
-
- // Create near clip volume for current light.
- float nearClipVolume[6 * 4] = {};
- float pointLight[4];
- if (settings_mixedSvImpl)
- {
- pointLight[0] = lightPos[0];
- pointLight[1] = lightPos[1];
- pointLight[2] = lightPos[2];
- pointLight[3] = 1.0f;
- createNearClipVolume(nearClipVolume, pointLight, viewState.m_view, fov, aspect, nearPlane);
- }
-
- for (uint8_t jj = 0; jj < shadowCastersCount[currentScene]; ++jj)
- {
- const Instance& instance = shadowCasters[currentScene][jj];
- Model* model = instance.m_model;
+ }
- ShadowVolumeImpl::Enum shadowVolumeImpl = settings_shadowVolumeImpl;
- if (settings_mixedSvImpl)
+ // Create near clip volume for current light.
+ float nearClipVolume[6 * 4] = {};
+ float pointLight[4];
+ if (m_mixedSvImpl)
{
- // If instance is inside near clip volume, depth fail must be used, else depth pass is fine.
- bool isInsideVolume = clipTest(nearClipVolume, 6, model->m_mesh, instance.m_scale, instance.m_pos);
- shadowVolumeImpl = (isInsideVolume ? ShadowVolumeImpl::DepthFail : ShadowVolumeImpl::DepthPass);
+ pointLight[0] = lightPos[0];
+ pointLight[1] = lightPos[1];
+ pointLight[2] = lightPos[2];
+ pointLight[3] = 1.0f;
+ createNearClipVolume(nearClipVolume, pointLight, m_viewState.m_view, fov, aspect, nearPlane);
}
- s_uniforms.m_svparams.m_dfail = float(ShadowVolumeImpl::DepthFail == shadowVolumeImpl);
-
- // Compute virtual light position for shadow volume generation.
- float transformedLightPos[3];
- shadowVolumeLightTransform(transformedLightPos
- , instance.m_scale
- , instance.m_rotation
- , instance.m_pos
- , lightPos
- );
-
- // Set virtual light pos.
- bx::memCopy(s_uniforms.m_virtualLightPos_extrusionDist, transformedLightPos, 3*sizeof(float) );
- s_uniforms.m_virtualLightPos_extrusionDist[3] = instance.m_svExtrusionDistance;
-
- // Compute transform for shadow volume.
- float shadowVolumeMtx[16];
- bx::mtxSRT(shadowVolumeMtx
+
+ for (uint8_t jj = 0; jj < shadowCastersCount[m_currentScene]; ++jj)
+ {
+ const Instance& instance = shadowCasters[m_currentScene][jj];
+ Model* model = instance.m_model;
+
+ ShadowVolumeImpl::Enum shadowVolumeImpl = m_shadowVolumeImpl;
+ if (m_mixedSvImpl)
+ {
+ // If instance is inside near clip volume, depth fail must be used, else depth pass is fine.
+ bool isInsideVolume = clipTest(nearClipVolume, 6, model->m_mesh, instance.m_scale, instance.m_pos);
+ shadowVolumeImpl = (isInsideVolume ? ShadowVolumeImpl::DepthFail : ShadowVolumeImpl::DepthPass);
+ }
+ s_uniforms.m_svparams.m_dfail = float(ShadowVolumeImpl::DepthFail == shadowVolumeImpl);
+
+ // Compute virtual light position for shadow volume generation.
+ float transformedLightPos[3];
+ shadowVolumeLightTransform(transformedLightPos
+ , instance.m_scale
+ , instance.m_rotation
+ , instance.m_pos
+ , lightPos
+ );
+
+ // Set virtual light pos.
+ bx::memCopy(s_uniforms.m_virtualLightPos_extrusionDist, transformedLightPos, 3*sizeof(float) );
+ s_uniforms.m_virtualLightPos_extrusionDist[3] = instance.m_svExtrusionDistance;
+
+ // Compute transform for shadow volume.
+ float shadowVolumeMtx[16];
+ bx::mtxSRT(shadowVolumeMtx
, instance.m_scale[0]
, instance.m_scale[1]
, instance.m_scale[2]
@@ -2653,207 +2702,239 @@ int _main_(int _argc, char** _argv)
, instance.m_pos[2]
);
- GroupArray& groups = model->m_mesh.m_groups;
- const uint16_t stride = model->m_mesh.m_decl.getStride();
- for (GroupArray::iterator it = groups.begin(), itEnd = groups.end(); it != itEnd; ++it)
- {
- Group& group = *it;
-
- // Create shadow volume.
- ShadowVolume shadowVolume;
- shadowVolumeCreate(shadowVolume
- , group
- , stride
- , shadowVolumeMtx
- , transformedLightPos
- , shadowVolumeImpl
- , settings_shadowVolumeAlgorithm
- , settings_useStencilTexture
- );
-
- numShadowVolumeVertices += shadowVolume.m_numVertices;
- numShadowVolumeIndices += shadowVolume.m_numIndices;
-
- ShadowVolumeProgramType::Enum programIndex = ShadowVolumeProgramType::Blank;
- RenderState::Enum renderStateIndex;
- if (settings_useStencilTexture)
- {
- renderStateIndex = ShadowVolumeImpl::DepthFail == shadowVolumeImpl
- ? RenderState::ShadowVolume_UsingStencilTexture_CraftStencil_DepthFail
- : RenderState::ShadowVolume_UsingStencilTexture_CraftStencil_DepthPass
- ;
-
- programIndex = ShadowVolumeAlgorithm::FaceBased == settings_shadowVolumeAlgorithm
- ? ShadowVolumeProgramType::Tex1
- : ShadowVolumeProgramType::Tex2
- ;
- }
- else
- {
- renderStateIndex = ShadowVolumeImpl::DepthFail == shadowVolumeImpl
- ? RenderState::ShadowVolume_UsingStencilBuffer_CraftStencil_DepthFail
- : RenderState::ShadowVolume_UsingStencilBuffer_CraftStencil_DepthPass
- ;
- }
- const RenderState& renderStateCraftStencil = s_renderStates[renderStateIndex];
-
- s_uniforms.submitPerDrawUniforms();
- bgfx::setTransform(shadowVolumeMtx);
- bgfx::setVertexBuffer(shadowVolume.m_vbSides);
- bgfx::setIndexBuffer(shadowVolume.m_ibSides);
- setRenderState(renderStateCraftStencil);
- ::submit(viewId, svProgs[programIndex][ShadowVolumePart::Side]);
-
- if (shadowVolume.m_cap)
+ GroupArray& groups = model->m_mesh.m_groups;
+ const uint16_t stride = model->m_mesh.m_decl.getStride();
+ for (GroupArray::iterator it = groups.begin(), itEnd = groups.end(); it != itEnd; ++it)
{
- s_uniforms.submitPerDrawUniforms();
- bgfx::setTransform(shadowVolumeMtx);
- bgfx::setVertexBuffer(group.m_vbh);
- bgfx::setIndexBuffer(shadowVolume.m_ibFrontCap);
- setRenderState(renderStateCraftStencil);
- ::submit(viewId, svProgs[programIndex][ShadowVolumePart::Front]);
+ Group& group = *it;
+
+ // Create shadow volume.
+ ShadowVolume shadowVolume;
+ shadowVolumeCreate(shadowVolume
+ , group
+ , stride
+ , shadowVolumeMtx
+ , transformedLightPos
+ , shadowVolumeImpl
+ , m_shadowVolumeAlgorithm
+ , m_useStencilTexture
+ );
- s_uniforms.submitPerDrawUniforms();
- bgfx::setTransform(shadowVolumeMtx);
- bgfx::setVertexBuffer(group.m_vbh);
- bgfx::setIndexBuffer(shadowVolume.m_ibBackCap);
- ::setRenderState(renderStateCraftStencil);
- ::submit(viewId, svProgs[programIndex][ShadowVolumePart::Back]);
- }
+ m_numShadowVolumeVertices += shadowVolume.m_numVertices;
+ m_numShadowVolumeIndices += shadowVolume.m_numIndices;
- if (settings_drawShadowVolumes)
- {
- const RenderState& renderState = s_renderStates[RenderState::Custom_DrawShadowVolume_Lines];
+ ShadowVolumeProgramType::Enum programIndex = ShadowVolumeProgramType::Blank;
+ RenderState::Enum renderStateIndex;
+ if (m_useStencilTexture)
+ {
+ renderStateIndex = ShadowVolumeImpl::DepthFail == shadowVolumeImpl
+ ? RenderState::ShadowVolume_UsingStencilTexture_CraftStencil_DepthFail
+ : RenderState::ShadowVolume_UsingStencilTexture_CraftStencil_DepthPass
+ ;
+
+ programIndex = ShadowVolumeAlgorithm::FaceBased == m_shadowVolumeAlgorithm
+ ? ShadowVolumeProgramType::Tex1
+ : ShadowVolumeProgramType::Tex2
+ ;
+ }
+ else
+ {
+ renderStateIndex = ShadowVolumeImpl::DepthFail == shadowVolumeImpl
+ ? RenderState::ShadowVolume_UsingStencilBuffer_CraftStencil_DepthFail
+ : RenderState::ShadowVolume_UsingStencilBuffer_CraftStencil_DepthPass
+ ;
+ }
+ const RenderState& renderStateCraftStencil = s_renderStates[renderStateIndex];
s_uniforms.submitPerDrawUniforms();
bgfx::setTransform(shadowVolumeMtx);
- bgfx::setVertexBuffer(shadowVolume.m_vbSides);
+ bgfx::setVertexBuffer(0, shadowVolume.m_vbSides);
bgfx::setIndexBuffer(shadowVolume.m_ibSides);
- ::setRenderState(renderState);
- ::submit(VIEWID_RANGE1_PASS3, svProgs[ShadowVolumeProgramType::Color][ShadowVolumePart::Side]);
+ setRenderState(renderStateCraftStencil);
+ ::submit(viewId, m_svProgs[programIndex][ShadowVolumePart::Side]);
if (shadowVolume.m_cap)
{
s_uniforms.submitPerDrawUniforms();
bgfx::setTransform(shadowVolumeMtx);
- bgfx::setVertexBuffer(group.m_vbh);
+ bgfx::setVertexBuffer(0, group.m_vbh);
bgfx::setIndexBuffer(shadowVolume.m_ibFrontCap);
- ::setRenderState(renderState);
- ::submit(VIEWID_RANGE1_PASS3, svProgs[ShadowVolumeProgramType::Color][ShadowVolumePart::Front]);
+ setRenderState(renderStateCraftStencil);
+ ::submit(viewId, m_svProgs[programIndex][ShadowVolumePart::Front]);
s_uniforms.submitPerDrawUniforms();
bgfx::setTransform(shadowVolumeMtx);
- bgfx::setVertexBuffer(group.m_vbh);
+ bgfx::setVertexBuffer(0, group.m_vbh);
bgfx::setIndexBuffer(shadowVolume.m_ibBackCap);
+ ::setRenderState(renderStateCraftStencil);
+ ::submit(viewId, m_svProgs[programIndex][ShadowVolumePart::Back]);
+ }
+
+ if (m_drawShadowVolumes)
+ {
+ const RenderState& renderState = s_renderStates[RenderState::Custom_DrawShadowVolume_Lines];
+
+ s_uniforms.submitPerDrawUniforms();
+ bgfx::setTransform(shadowVolumeMtx);
+ bgfx::setVertexBuffer(0, shadowVolume.m_vbSides);
+ bgfx::setIndexBuffer(shadowVolume.m_ibSides);
::setRenderState(renderState);
- ::submit(VIEWID_RANGE1_PASS3, svProgs[ShadowVolumeProgramType::Color][ShadowVolumePart::Back]);
+ ::submit(VIEWID_RANGE1_PASS3, m_svProgs[ShadowVolumeProgramType::Color][ShadowVolumePart::Side]);
+
+ if (shadowVolume.m_cap)
+ {
+ s_uniforms.submitPerDrawUniforms();
+ bgfx::setTransform(shadowVolumeMtx);
+ bgfx::setVertexBuffer(0, group.m_vbh);
+ bgfx::setIndexBuffer(shadowVolume.m_ibFrontCap);
+ ::setRenderState(renderState);
+ ::submit(VIEWID_RANGE1_PASS3, m_svProgs[ShadowVolumeProgramType::Color][ShadowVolumePart::Front]);
+
+ s_uniforms.submitPerDrawUniforms();
+ bgfx::setTransform(shadowVolumeMtx);
+ bgfx::setVertexBuffer(0, group.m_vbh);
+ bgfx::setIndexBuffer(shadowVolume.m_ibBackCap);
+ ::setRenderState(renderState);
+ ::submit(VIEWID_RANGE1_PASS3, m_svProgs[ShadowVolumeProgramType::Color][ShadowVolumePart::Back]);
+ }
}
}
}
- }
- // Draw diffuse only.
- s_uniforms.m_params.m_ambientPass = 0.0f;
- s_uniforms.m_params.m_lightingPass = 1.0f;
+ // Draw diffuse only.
+ s_uniforms.m_params.m_ambientPass = 0.0f;
+ s_uniforms.m_params.m_lightingPass = 1.0f;
- RenderState& drawDiffuse = settings_useStencilTexture
- ? s_renderStates[RenderState::ShadowVolume_UsingStencilTexture_DrawDiffuse]
- : s_renderStates[RenderState::ShadowVolume_UsingStencilBuffer_DrawDiffuse]
- ;
+ RenderState& drawDiffuse = m_useStencilTexture
+ ? s_renderStates[RenderState::ShadowVolume_UsingStencilTexture_DrawDiffuse]
+ : s_renderStates[RenderState::ShadowVolume_UsingStencilBuffer_DrawDiffuse]
+ ;
- // If using stencil texture, viewId is set to render target. Incr it to render to default back buffer.
- viewId += uint8_t(settings_useStencilTexture);
+ // If using stencil texture, viewId is set to render target. Incr it to render to default back buffer.
+ viewId += uint8_t(m_useStencilTexture);
- // Draw shadow casters.
- for (uint8_t jj = 0; jj < shadowCastersCount[currentScene]; ++jj)
- {
- shadowCasters[currentScene][jj].submit(viewId, drawDiffuse);
+ // Draw shadow casters.
+ for (uint8_t jj = 0; jj < shadowCastersCount[m_currentScene]; ++jj)
+ {
+ shadowCasters[m_currentScene][jj].submit(viewId, drawDiffuse);
+ }
+
+ // Draw shadow receivers.
+ for (uint8_t jj = 0; jj < shadowReceiversCount[m_currentScene]; ++jj)
+ {
+ shadowReceivers[m_currentScene][jj].submit(viewId, drawDiffuse);
+ }
}
- // Draw shadow receivers.
- for (uint8_t jj = 0; jj < shadowReceiversCount[currentScene]; ++jj)
+ m_profTime = bx::getHPCounter() - m_profTime;
+
+ // Lights.
+ const float lightScale[3] = { 1.5f, 1.5f, 1.5f };
+ for (uint8_t ii = 0; ii < m_numLights; ++ii)
{
- shadowReceivers[currentScene][jj].submit(viewId, drawDiffuse);
- }
- }
+ bx::memCopy(s_uniforms.m_color, m_lightRgbInnerR[ii], 3*sizeof(float) );
- profTime = bx::getHPCounter() - profTime;
+ float lightMtx[16];
+ mtxBillboard(lightMtx, m_viewState.m_view, lightPosRadius[ii], lightScale);
- // Lights.
- const float lightScale[3] = { 1.5f, 1.5f, 1.5f };
- for (uint8_t ii = 0; ii < settings_numLights; ++ii)
- {
- bx::memCopy(s_uniforms.m_color, lightRgbInnerR[ii], 3*sizeof(float) );
+ m_vplaneModel.submit(VIEWID_RANGE1_PASS3, lightMtx, s_renderStates[RenderState::Custom_BlendLightTexture]);
+ }
- float lightMtx[16];
- mtxBillboard(lightMtx, viewState.m_view, lightPosRadius[ii], lightScale);
+ // 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;
- vplaneModel.submit(VIEWID_RANGE1_PASS3, lightMtx, s_renderStates[RenderState::Custom_BlendLightTexture]);
- }
+ // Advance to next frame. Rendering thread will be kicked to
+ // process submitted rendering primitives.
+ bgfx::frame();
- // 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;
+ // Swap memory pages.
+ s_svAllocator.swap();
- // Advance to next frame. Rendering thread will be kicked to
- // process submitted rendering primitives.
- bgfx::frame();
+ // Reset clear values.
+ setViewClearMask(UINT32_MAX
+ , BGFX_CLEAR_NONE
+ , m_clearValues.m_clearRgba
+ , m_clearValues.m_clearDepth
+ , m_clearValues.m_clearStencil
+ );
- // Swap memory pages.
- s_svAllocator.swap();
+ return true;
+ }
- // Reset clear values.
- setViewClearMask(UINT32_MAX
- , BGFX_CLEAR_NONE
- , clearValues.m_clearRgba
- , clearValues.m_clearDepth
- , clearValues.m_clearStencil
- );
+ return false;
}
- // Cleanup
- bunnyLowPolyModel.unload();
- bunnyHighPolyModel.unload();
- columnModel.unload();
- cubeModel.unload();
- platformModel.unload();
- hplaneFieldModel.unload();
- hplaneFigureModel.unload();
- vplaneModel.unload();
-
- s_uniforms.destroy();
-
- bgfx::destroyUniform(s_texColor);
- bgfx::destroyUniform(s_texStencil);
- bgfx::destroyFrameBuffer(s_stencilFb);
-
- bgfx::destroyTexture(figureTex);
- bgfx::destroyTexture(fieldstoneTex);
- bgfx::destroyTexture(flareTex);
-
- bgfx::destroyProgram(programTextureLighting);
- bgfx::destroyProgram(programColorLighting);
- bgfx::destroyProgram(programColorTexture);
- bgfx::destroyProgram(programTexture);
-
- bgfx::destroyProgram(programBackBlank);
- bgfx::destroyProgram(programSideBlank);
- bgfx::destroyProgram(programFrontBlank);
- bgfx::destroyProgram(programBackColor);
- bgfx::destroyProgram(programSideColor);
- bgfx::destroyProgram(programFrontColor);
- bgfx::destroyProgram(programSideTex);
- bgfx::destroyProgram(programBackTex1);
- bgfx::destroyProgram(programBackTex2);
- bgfx::destroyProgram(programFrontTex1);
- bgfx::destroyProgram(programFrontTex2);
-
- cameraDestroy();
- imguiDestroy();
-
- // Shutdown bgfx.
- bgfx::shutdown();
-
- return 0;
-}
+ ViewState m_viewState;
+ ClearValues m_clearValues;
+
+ uint32_t m_debug;
+ uint32_t m_reset;
+
+ bgfx::TextureHandle m_figureTex;
+ bgfx::TextureHandle m_flareTex;
+ bgfx::TextureHandle m_fieldstoneTex;
+
+ bgfx::ProgramHandle m_programTextureLighting;
+ bgfx::ProgramHandle m_programColorLighting;
+ bgfx::ProgramHandle m_programColorTexture;
+ bgfx::ProgramHandle m_programTexture;
+
+ bgfx::ProgramHandle m_programBackBlank;
+ bgfx::ProgramHandle m_programSideBlank;
+ bgfx::ProgramHandle m_programFrontBlank;
+
+ bgfx::ProgramHandle m_programBackColor;
+ bgfx::ProgramHandle m_programSideColor;
+ bgfx::ProgramHandle m_programFrontColor;
+
+ bgfx::ProgramHandle m_programSideTex;
+ bgfx::ProgramHandle m_programBackTex1;
+ bgfx::ProgramHandle m_programBackTex2;
+ bgfx::ProgramHandle m_programFrontTex1;
+ bgfx::ProgramHandle m_programFrontTex2;
+
+ bgfx::ProgramHandle m_svProgs[ShadowVolumeProgramType::Count][ShadowVolumePart::Count];
+
+ Model m_bunnyLowPolyModel;
+ Model m_bunnyHighPolyModel;
+ Model m_columnModel;
+ Model m_platformModel;
+ Model m_cubeModel;
+ Model m_hplaneFieldModel;
+ Model m_hplaneFigureModel;
+ Model m_vplaneModel;
+
+ float m_lightRgbInnerR[MAX_LIGHTS_COUNT][4];
+
+ int64_t m_profTime;
+ int64_t m_timeOffset;
+
+ uint32_t m_numShadowVolumeVertices;
+ uint32_t m_numShadowVolumeIndices;
+
+ uint32_t m_oldWidth;
+ uint32_t m_oldHeight;
+
+ int32_t m_numLights;
+ int32_t m_instanceCount;
+ bool m_showHelp;
+ bool m_updateLights;
+ bool m_updateScene;
+ bool m_mixedSvImpl;
+ bool m_useStencilTexture;
+ bool m_drawShadowVolumes;
+ ShadowVolumeImpl::Enum m_shadowVolumeImpl;
+ ShadowVolumeAlgorithm::Enum m_shadowVolumeAlgorithm;
+
+ LightPattern m_lightPattern;
+ MeshChoice m_currentMesh;
+ Scene m_currentScene;
+
+ entry::MouseState m_mouseState;
+};
+
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleShadowVolumes, "14-shadowvolumes", "Shadow volumes.");