summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/examples/15-shadowmaps-simple/shadowmaps_simple.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/examples/15-shadowmaps-simple/shadowmaps_simple.cpp')
-rw-r--r--3rdparty/bgfx/examples/15-shadowmaps-simple/shadowmaps_simple.cpp683
1 files changed, 372 insertions, 311 deletions
diff --git a/3rdparty/bgfx/examples/15-shadowmaps-simple/shadowmaps_simple.cpp b/3rdparty/bgfx/examples/15-shadowmaps-simple/shadowmaps_simple.cpp
index ae125ea98ab..0119c730d8f 100644
--- a/3rdparty/bgfx/examples/15-shadowmaps-simple/shadowmaps_simple.cpp
+++ b/3rdparty/bgfx/examples/15-shadowmaps-simple/shadowmaps_simple.cpp
@@ -12,37 +12,16 @@
#include <bgfx/bgfx.h>
#include <bx/timer.h>
#include <bx/readerwriter.h>
-#include <bx/fpumath.h>
+#include <bx/math.h>
#include "entry/entry.h"
#include "bgfx_utils.h"
+#include "imgui/imgui.h"
-#define RENDER_SHADOW_PASS_ID 0
-#define RENDER_SCENE_PASS_ID 1
-
-uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w)
+namespace
{
- 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);
-}
+#define RENDER_SHADOW_PASS_ID 0
+#define RENDER_SCENE_PASS_ID 1
struct PosNormalVertex
{
@@ -50,14 +29,27 @@ struct PosNormalVertex
float m_y;
float m_z;
uint32_t m_normal;
+
+ static void init()
+ {
+ ms_decl
+ .begin()
+ .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
+ .add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true)
+ .end();
+ };
+
+ static bgfx::VertexDecl ms_decl;
};
+bgfx::VertexDecl PosNormalVertex::ms_decl;
+
static PosNormalVertex s_hplaneVertices[] =
{
- { -1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f) },
- { 1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f) },
- { -1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f) },
- { 1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f) },
+ { -1.0f, 0.0f, 1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f) },
+ { 1.0f, 0.0f, 1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f) },
+ { -1.0f, 0.0f, -1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f) },
+ { 1.0f, 0.0f, -1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f) },
};
static const uint16_t s_planeIndices[] =
@@ -66,329 +58,398 @@ static const uint16_t s_planeIndices[] =
1, 3, 2,
};
-int _main_(int _argc, char** _argv)
+class ExampleShadowmapsSimple : public entry::AppI
{
- Args args(_argc, _argv);
-
- uint32_t width = 1280;
- uint32_t height = 720;
- uint32_t debug = BGFX_DEBUG_TEXT;
- uint32_t reset = BGFX_RESET_VSYNC;
-
- bgfx::init(args.m_type, args.m_pciId);
- bgfx::reset(width, height, reset);
-
- bgfx::RendererType::Enum renderer = bgfx::getRendererType();
- bool flipV = false
- || renderer == bgfx::RendererType::OpenGL
- || renderer == bgfx::RendererType::OpenGLES
- ;
-
- // Enable debug text.
- bgfx::setDebug(debug);
-
- // Uniforms.
- bgfx::UniformHandle u_shadowMap = bgfx::createUniform("u_shadowMap", bgfx::UniformType::Int1);
- bgfx::UniformHandle u_lightPos = bgfx::createUniform("u_lightPos", bgfx::UniformType::Vec4);
- bgfx::UniformHandle u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Mat4);
- // When using GL clip space depth range [-1, 1] and packing depth into color buffer, we need to
- // adjust the depth range to be [0, 1] for writing to the color buffer
- bgfx::UniformHandle u_depthScaleOffset = bgfx::createUniform("u_depthScaleOffset", bgfx::UniformType::Vec4);
- const float depthScale = flipV ? 0.5f : 1.0f;
- const float depthOffset = flipV ? 0.5f : 0.0f;
- float depthScaleOffset[4] = {depthScale, depthOffset, 0.0f, 0.0f};
- bgfx::setUniform(u_depthScaleOffset, depthScaleOffset);
-
- // Vertex declarations.
- bgfx::VertexDecl PosNormalDecl;
- PosNormalDecl.begin()
- .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
- .add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true)
- .end();
-
- // Meshes.
- Mesh* bunny = meshLoad("meshes/bunny.bin");
- Mesh* cube = meshLoad("meshes/cube.bin");
- Mesh* hollowcube = meshLoad("meshes/hollowcube.bin");
-
- bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(
- bgfx::makeRef(s_hplaneVertices, sizeof(s_hplaneVertices) )
- , PosNormalDecl
- );
+public:
+ ExampleShadowmapsSimple(const char* _name, const char* _description)
+ : entry::AppI(_name, _description)
+ {
+ }
- bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(
- bgfx::makeRef(s_planeIndices, sizeof(s_planeIndices) )
- );
+ void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
+ {
+ Args args(_argc, _argv);
- // Render targets.
- uint16_t shadowMapSize = 512;
+ m_width = _width;
+ m_height = _height;
+ m_debug = BGFX_DEBUG_NONE;
+ m_reset = BGFX_RESET_VSYNC;
- // Get renderer capabilities info.
- const bgfx::Caps* caps = bgfx::getCaps();
- // Shadow samplers are supported at least partially supported if texture
- // compare less equal feature is supported.
- bool shadowSamplerSupported = 0 != (caps->supported & BGFX_CAPS_TEXTURE_COMPARE_LEQUAL);
+ bgfx::init(args.m_type, args.m_pciId);
+ bgfx::reset(m_width, m_height, m_reset);
- bgfx::ProgramHandle progShadow;
- bgfx::ProgramHandle progMesh;
- bgfx::TextureHandle shadowMapTexture;
- bgfx::FrameBufferHandle shadowMapFB;
+ // Enable debug text.
+ bgfx::setDebug(m_debug);
- if (shadowSamplerSupported)
- {
- // Depth textures and shadow samplers are supported.
- progShadow = loadProgram("vs_sms_shadow", "fs_sms_shadow");
- progMesh = loadProgram("vs_sms_mesh", "fs_sms_mesh");
+ // Uniforms.
+ s_shadowMap = bgfx::createUniform("s_shadowMap", bgfx::UniformType::Int1);
+ u_lightPos = bgfx::createUniform("u_lightPos", bgfx::UniformType::Vec4);
+ u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Mat4);
- shadowMapTexture = bgfx::createTexture2D(shadowMapSize, shadowMapSize, false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT | BGFX_TEXTURE_COMPARE_LEQUAL);
- bgfx::TextureHandle fbtextures[] = { shadowMapTexture };
- shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
- }
- else
- {
- // Depth textures and shadow samplers are not supported. Use float
- // depth packing into color buffer instead.
- progShadow = loadProgram("vs_sms_shadow_pd", "fs_sms_shadow_pd");
- progMesh = loadProgram("vs_sms_mesh", "fs_sms_mesh_pd");
+ // When using GL clip space depth range [-1, 1] and packing depth into color buffer, we need to
+ // adjust the depth range to be [0, 1] for writing to the color buffer
+ u_depthScaleOffset = bgfx::createUniform("u_depthScaleOffset", bgfx::UniformType::Vec4);
+
+ // Get renderer capabilities info.
+ const bgfx::Caps* caps = bgfx::getCaps();
- shadowMapTexture = bgfx::createTexture2D(shadowMapSize, shadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT);
- bgfx::TextureHandle fbtextures[] =
+ float depthScaleOffset[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
+ if (caps->homogeneousDepth)
{
- shadowMapTexture,
- bgfx::createTexture2D(shadowMapSize, shadowMapSize, false, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_WRITE_ONLY),
- };
- shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
- }
+ depthScaleOffset[0] = 0.5f;
+ depthScaleOffset[1] = 0.5f;
+ }
+ bgfx::setUniform(u_depthScaleOffset, depthScaleOffset);
- MeshState* state[2];
- state[0] = meshStateCreate();
- state[0]->m_state = 0
- | BGFX_STATE_RGB_WRITE
- | BGFX_STATE_ALPHA_WRITE
- | BGFX_STATE_DEPTH_WRITE
- | BGFX_STATE_DEPTH_TEST_LESS
- | BGFX_STATE_CULL_CCW
- | BGFX_STATE_MSAA
- ;
- state[0]->m_program = progShadow;
- state[0]->m_viewId = RENDER_SHADOW_PASS_ID;
- state[0]->m_numTextures = 0;
-
- state[1] = meshStateCreate();
- state[1]->m_state = 0
- | BGFX_STATE_RGB_WRITE
- | BGFX_STATE_ALPHA_WRITE
- | BGFX_STATE_DEPTH_WRITE
- | BGFX_STATE_DEPTH_TEST_LESS
- | BGFX_STATE_CULL_CCW
- | BGFX_STATE_MSAA
- ;
- state[1]->m_program = progMesh;
- state[1]->m_viewId = RENDER_SCENE_PASS_ID;
- state[1]->m_numTextures = 1;
- state[1]->m_textures[0].m_flags = UINT32_MAX;
- state[1]->m_textures[0].m_stage = 0;
- state[1]->m_textures[0].m_sampler = u_shadowMap;
- state[1]->m_textures[0].m_texture = shadowMapTexture;
-
- // Set view and projection matrices.
- float view[16];
- float proj[16];
-
- float eye[3] = { 0.0f, 30.0f, -60.0f };
- float at[3] = { 0.0f, 5.0f, 0.0f };
- bx::mtxLookAt(view, eye, at);
-
- const float aspect = float(int32_t(width) ) / float(int32_t(height) );
- bx::mtxProj(proj, 60.0f, aspect, 0.1f, 1000.0f, bgfx::getCaps()->homogeneousDepth);
-
- // Time acumulators.
- float timeAccumulatorLight = 0.0f;
- float timeAccumulatorScene = 0.0f;
-
- entry::MouseState mouseState;
- while (!entry::processEvents(width, height, debug, reset, &mouseState) )
- {
- // 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 deltaTime = float(frameTime/freq);
-
- // Update time accumulators.
- timeAccumulatorLight += deltaTime;
- timeAccumulatorScene += deltaTime;
-
- // Use debug font to print information about this example.
- bgfx::dbgTextClear();
- bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/15-shadowmaps-simple");
- bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow maps example (technique: %s).", shadowSamplerSupported ? "depth texture and shadow samplers" : "shadow depth packed into color texture");
- bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
- // Setup lights.
- float lightPos[4];
- lightPos[0] = -bx::fcos(timeAccumulatorLight);
- lightPos[1] = -1.0f;
- lightPos[2] = -bx::fsin(timeAccumulatorLight);
- lightPos[3] = 0.0f;
-
- bgfx::setUniform(u_lightPos, lightPos);
-
- // Setup instance matrices.
- float mtxFloor[16];
- bx::mtxSRT(mtxFloor
- , 30.0f, 30.0f, 30.0f
- , 0.0f, 0.0f, 0.0f
- , 0.0f, 0.0f, 0.0f
- );
+ // Create vertex stream declaration.
+ PosNormalVertex::init();
- float mtxBunny[16];
- bx::mtxSRT(mtxBunny
- , 5.0f, 5.0f, 5.0f
- , 0.0f, bx::pi - timeAccumulatorScene, 0.0f
- , 15.0f, 5.0f, 0.0f
- );
+ // Meshes.
+ m_bunny = meshLoad("meshes/bunny.bin");
+ m_cube = meshLoad("meshes/cube.bin");
+ m_hollowcube = meshLoad("meshes/hollowcube.bin");
- float mtxHollowcube[16];
- bx::mtxSRT(mtxHollowcube
- , 2.5f, 2.5f, 2.5f
- , 0.0f, 1.56f - timeAccumulatorScene, 0.0f
- , 0.0f, 10.0f, 0.0f
+ m_vbh = bgfx::createVertexBuffer(
+ bgfx::makeRef(s_hplaneVertices, sizeof(s_hplaneVertices) )
+ , PosNormalVertex::ms_decl
);
- float mtxCube[16];
- bx::mtxSRT(mtxCube
- , 2.5f, 2.5f, 2.5f
- , 0.0f, 1.56f - timeAccumulatorScene, 0.0f
- , -15.0f, 5.0f, 0.0f
+ m_ibh = bgfx::createIndexBuffer(
+ bgfx::makeRef(s_planeIndices, sizeof(s_planeIndices) )
);
- // Define matrices.
- float lightView[16];
- float lightProj[16];
+ // Render targets.
+ m_shadowMapSize = 512;
+
+ // Shadow samplers are supported at least partially supported if texture
+ // compare less equal feature is supported.
+ m_shadowSamplerSupported = 0 != (caps->supported & BGFX_CAPS_TEXTURE_COMPARE_LEQUAL);
+
+ bgfx::TextureHandle shadowMapTexture;
+
+ if (m_shadowSamplerSupported)
+ {
+ // Depth textures and shadow samplers are supported.
+ m_progShadow = loadProgram("vs_sms_shadow", "fs_sms_shadow");
+ m_progMesh = loadProgram("vs_sms_mesh", "fs_sms_mesh");
+
+ bgfx::TextureHandle fbtextures[] =
+ {
+ bgfx::createTexture2D(
+ m_shadowMapSize
+ , m_shadowMapSize
+ , false
+ , 1
+ , bgfx::TextureFormat::D16
+ , BGFX_TEXTURE_RT | BGFX_TEXTURE_COMPARE_LEQUAL
+ ),
+ };
+ shadowMapTexture = fbtextures[0];
+ m_shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ }
+ else
+ {
+ // Depth textures and shadow samplers are not supported. Use float
+ // depth packing into color buffer instead.
+ m_progShadow = loadProgram("vs_sms_shadow_pd", "fs_sms_shadow_pd");
+ m_progMesh = loadProgram("vs_sms_mesh", "fs_sms_mesh_pd");
+
+ bgfx::TextureHandle fbtextures[] =
+ {
+ bgfx::createTexture2D(
+ m_shadowMapSize
+ , m_shadowMapSize
+ , false
+ , 1
+ , bgfx::TextureFormat::BGRA8
+ , BGFX_TEXTURE_RT
+ ),
+ bgfx::createTexture2D(
+ m_shadowMapSize
+ , m_shadowMapSize
+ , false
+ , 1
+ , bgfx::TextureFormat::D16
+ , BGFX_TEXTURE_RT_WRITE_ONLY
+ ),
+ };
+ shadowMapTexture = fbtextures[0];
+ m_shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ }
+
+ m_state[0] = meshStateCreate();
+ m_state[0]->m_state = 0
+ | BGFX_STATE_RGB_WRITE
+ | BGFX_STATE_ALPHA_WRITE
+ | BGFX_STATE_DEPTH_WRITE
+ | BGFX_STATE_DEPTH_TEST_LESS
+ | BGFX_STATE_CULL_CCW
+ | BGFX_STATE_MSAA
+ ;
+ m_state[0]->m_program = m_progShadow;
+ m_state[0]->m_viewId = RENDER_SHADOW_PASS_ID;
+ m_state[0]->m_numTextures = 0;
+
+ m_state[1] = meshStateCreate();
+ m_state[1]->m_state = 0
+ | BGFX_STATE_RGB_WRITE
+ | BGFX_STATE_ALPHA_WRITE
+ | BGFX_STATE_DEPTH_WRITE
+ | BGFX_STATE_DEPTH_TEST_LESS
+ | BGFX_STATE_CULL_CCW
+ | BGFX_STATE_MSAA
+ ;
+ m_state[1]->m_program = m_progMesh;
+ m_state[1]->m_viewId = RENDER_SCENE_PASS_ID;
+ m_state[1]->m_numTextures = 1;
+ m_state[1]->m_textures[0].m_flags = UINT32_MAX;
+ m_state[1]->m_textures[0].m_stage = 0;
+ m_state[1]->m_textures[0].m_sampler = s_shadowMap;
+ m_state[1]->m_textures[0].m_texture = shadowMapTexture;
+
+ // Set view and projection matrices.
+
+ float eye[3] = { 0.0f, 30.0f, -60.0f };
+ float at[3] = { 0.0f, 5.0f, 0.0f };
+ bx::mtxLookAt(m_view, eye, at);
+
+ const float aspect = float(int32_t(m_width) ) / float(int32_t(m_height) );
+ bx::mtxProj(m_proj, 60.0f, aspect, 0.1f, 1000.0f, bgfx::getCaps()->homogeneousDepth);
+
+ m_timeOffset = bx::getHPCounter();
+
+ imguiCreate();
+ }
- eye[0] = -lightPos[0];
- eye[1] = -lightPos[1];
- eye[2] = -lightPos[2];
+ virtual int shutdown() override
+ {
+ imguiDestroy();
- at[0] = 0.0f;
- at[1] = 0.0f;
- at[2] = 0.0f;
+ meshUnload(m_bunny);
+ meshUnload(m_cube);
+ meshUnload(m_hollowcube);
- bx::mtxLookAt(lightView, eye, at);
+ meshStateDestroy(m_state[0]);
+ meshStateDestroy(m_state[1]);
- const float area = 30.0f;
- bx::mtxOrtho(lightProj, -area, area, -area, area, -100.0f, 100.0f, 0.0f, flipV);
+ bgfx::destroy(m_vbh);
+ bgfx::destroy(m_ibh);
- bgfx::setViewRect(RENDER_SHADOW_PASS_ID, 0, 0, shadowMapSize, shadowMapSize);
- bgfx::setViewFrameBuffer(RENDER_SHADOW_PASS_ID, shadowMapFB);
- bgfx::setViewTransform(RENDER_SHADOW_PASS_ID, lightView, lightProj);
+ bgfx::destroy(m_progShadow);
+ bgfx::destroy(m_progMesh);
- bgfx::setViewRect(RENDER_SCENE_PASS_ID, 0, 0, uint16_t(width), uint16_t(height) );
- bgfx::setViewTransform(RENDER_SCENE_PASS_ID, view, proj);
+ bgfx::destroy(m_shadowMapFB);
- // Clear backbuffer and shadowmap framebuffer at beginning.
- bgfx::setViewClear(RENDER_SHADOW_PASS_ID
- , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
- , 0x303030ff, 1.0f, 0
- );
+ bgfx::destroy(s_shadowMap);
+ bgfx::destroy(u_lightPos);
+ bgfx::destroy(u_lightMtx);
+ bgfx::destroy(u_depthScaleOffset);
- bgfx::setViewClear(RENDER_SCENE_PASS_ID
- , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
- , 0x303030ff, 1.0f, 0
- );
+ // Shutdown bgfx.
+ bgfx::shutdown();
- // Render.
- float mtxShadow[16];
- float lightMtx[16];
+ return 0;
+ }
- const float sy = flipV ? 0.5f : -0.5f;
- const float mtxCrop[16] =
- {
- 0.5f, 0.0f, 0.0f, 0.0f,
- 0.0f, sy, 0.0f, 0.0f,
- 0.0f, 0.0f, depthScale, 0.0f,
- 0.5f, 0.5f, depthOffset, 1.0f,
- };
-
- float mtxTmp[16];
- bx::mtxMul(mtxTmp, lightProj, mtxCrop);
- bx::mtxMul(mtxShadow, lightView, mtxTmp);
-
- // Floor.
- bx::mtxMul(lightMtx, mtxFloor, mtxShadow);
- uint32_t cached = bgfx::setTransform(mtxFloor);
- for (uint32_t pass = 0; pass < 2; ++pass)
+ bool update() override
+ {
+ if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
{
- const MeshState& st = *state[pass];
- bgfx::setTransform(cached);
- for (uint8_t tex = 0; tex < st.m_numTextures; ++tex)
+ 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_width)
+ , uint16_t(m_height)
+ );
+
+ showExampleDialog(this);
+
+ imguiEndFrame();
+
+ int64_t now = bx::getHPCounter();
+ const double freq = double(bx::getHPFrequency() );
+ float time = float( (now-m_timeOffset)/freq);
+
+ // Setup lights.
+ float lightPos[4];
+ lightPos[0] = -bx::fcos(time);
+ lightPos[1] = -1.0f;
+ lightPos[2] = -bx::fsin(time);
+ lightPos[3] = 0.0f;
+
+ bgfx::setUniform(u_lightPos, lightPos);
+
+ // Setup instance matrices.
+ float mtxFloor[16];
+ bx::mtxSRT(mtxFloor
+ , 30.0f, 30.0f, 30.0f
+ , 0.0f, 0.0f, 0.0f
+ , 0.0f, 0.0f, 0.0f
+ );
+
+ float mtxBunny[16];
+ bx::mtxSRT(mtxBunny
+ , 5.0f, 5.0f, 5.0f
+ , 0.0f, bx::kPi - time, 0.0f
+ , 15.0f, 5.0f, 0.0f
+ );
+
+ float mtxHollowcube[16];
+ bx::mtxSRT(mtxHollowcube
+ , 2.5f, 2.5f, 2.5f
+ , 0.0f, 1.56f - time, 0.0f
+ , 0.0f, 10.0f, 0.0f
+ );
+
+ float mtxCube[16];
+ bx::mtxSRT(mtxCube
+ , 2.5f, 2.5f, 2.5f
+ , 0.0f, 1.56f - time, 0.0f
+ , -15.0f, 5.0f, 0.0f
+ );
+
+ // Define matrices.
+ float lightView[16];
+ float lightProj[16];
+
+ float eye[3] = { -lightPos[0], -lightPos[1], -lightPos[2] };
+ float at[3] = { 0.0f, 0.0f, 0.0f };
+
+ bx::mtxLookAt(lightView, eye, at);
+
+ const bgfx::Caps* caps = bgfx::getCaps();
+ const float area = 30.0f;
+ bx::mtxOrtho(lightProj, -area, area, -area, area, -100.0f, 100.0f, 0.0f, caps->homogeneousDepth);
+
+ bgfx::setViewRect(RENDER_SHADOW_PASS_ID, 0, 0, m_shadowMapSize, m_shadowMapSize);
+ bgfx::setViewFrameBuffer(RENDER_SHADOW_PASS_ID, m_shadowMapFB);
+ bgfx::setViewTransform(RENDER_SHADOW_PASS_ID, lightView, lightProj);
+
+ bgfx::setViewRect(RENDER_SCENE_PASS_ID, 0, 0, uint16_t(m_width), uint16_t(m_height) );
+ bgfx::setViewTransform(RENDER_SCENE_PASS_ID, m_view, m_proj);
+
+ // Clear backbuffer and shadowmap framebuffer at beginning.
+ bgfx::setViewClear(RENDER_SHADOW_PASS_ID
+ , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+ , 0x303030ff, 1.0f, 0
+ );
+
+ bgfx::setViewClear(RENDER_SCENE_PASS_ID
+ , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+ , 0x303030ff, 1.0f, 0
+ );
+
+ // Render.
+ float mtxShadow[16];
+ float lightMtx[16];
+
+ const float sy = caps->originBottomLeft ? 0.5f : -0.5f;
+ const float sz = caps->homogeneousDepth ? 0.5f : 1.0f;
+ const float tz = caps->homogeneousDepth ? 0.5f : 0.0f;
+ const float mtxCrop[16] =
+ {
+ 0.5f, 0.0f, 0.0f, 0.0f,
+ 0.0f, sy, 0.0f, 0.0f,
+ 0.0f, 0.0f, sz, 0.0f,
+ 0.5f, 0.5f, tz, 1.0f,
+ };
+
+ float mtxTmp[16];
+ bx::mtxMul(mtxTmp, lightProj, mtxCrop);
+ bx::mtxMul(mtxShadow, lightView, mtxTmp);
+
+ // Floor.
+ bx::mtxMul(lightMtx, mtxFloor, mtxShadow);
+ uint32_t cached = bgfx::setTransform(mtxFloor);
+ for (uint32_t pass = 0; pass < 2; ++pass)
{
- const MeshState::Texture& texture = st.m_textures[tex];
- bgfx::setTexture(texture.m_stage
+ const MeshState& st = *m_state[pass];
+ bgfx::setTransform(cached);
+ for (uint8_t tex = 0; tex < st.m_numTextures; ++tex)
+ {
+ const MeshState::Texture& texture = st.m_textures[tex];
+ bgfx::setTexture(texture.m_stage
, texture.m_sampler
, texture.m_texture
, texture.m_flags
);
+ }
+ bgfx::setUniform(u_lightMtx, lightMtx);
+ bgfx::setIndexBuffer(m_ibh);
+ bgfx::setVertexBuffer(0, m_vbh);
+ bgfx::setState(st.m_state);
+ bgfx::submit(st.m_viewId, st.m_program);
}
+
+ // Bunny.
+ bx::mtxMul(lightMtx, mtxBunny, mtxShadow);
+ bgfx::setUniform(u_lightMtx, lightMtx);
+ meshSubmit(m_bunny, &m_state[0], 1, mtxBunny);
+ bgfx::setUniform(u_lightMtx, lightMtx);
+ meshSubmit(m_bunny, &m_state[1], 1, mtxBunny);
+
+ // Hollow cube.
+ bx::mtxMul(lightMtx, mtxHollowcube, mtxShadow);
+ bgfx::setUniform(u_lightMtx, lightMtx);
+ meshSubmit(m_hollowcube, &m_state[0], 1, mtxHollowcube);
+ bgfx::setUniform(u_lightMtx, lightMtx);
+ meshSubmit(m_hollowcube, &m_state[1], 1, mtxHollowcube);
+
+ // Cube.
+ bx::mtxMul(lightMtx, mtxCube, mtxShadow);
+ bgfx::setUniform(u_lightMtx, lightMtx);
+ meshSubmit(m_cube, &m_state[0], 1, mtxCube);
bgfx::setUniform(u_lightMtx, lightMtx);
- bgfx::setIndexBuffer(ibh);
- bgfx::setVertexBuffer(vbh);
- bgfx::setState(st.m_state);
- bgfx::submit(st.m_viewId, st.m_program);
+ meshSubmit(m_cube, &m_state[1], 1, mtxCube);
+
+ // Advance to next frame. Rendering thread will be kicked to
+ // process submitted rendering primitives.
+ bgfx::frame();
+
+ return true;
}
- // Bunny.
- bx::mtxMul(lightMtx, mtxBunny, mtxShadow);
- bgfx::setUniform(u_lightMtx, lightMtx);
- meshSubmit(bunny, &state[0], 1, mtxBunny);
- bgfx::setUniform(u_lightMtx, lightMtx);
- meshSubmit(bunny, &state[1], 1, mtxBunny);
-
- // Hollow cube.
- bx::mtxMul(lightMtx, mtxHollowcube, mtxShadow);
- bgfx::setUniform(u_lightMtx, lightMtx);
- meshSubmit(hollowcube, &state[0], 1, mtxHollowcube);
- bgfx::setUniform(u_lightMtx, lightMtx);
- meshSubmit(hollowcube, &state[1], 1, mtxHollowcube);
-
- // Cube.
- bx::mtxMul(lightMtx, mtxCube, mtxShadow);
- bgfx::setUniform(u_lightMtx, lightMtx);
- meshSubmit(cube, &state[0], 1, mtxCube);
- bgfx::setUniform(u_lightMtx, lightMtx);
- meshSubmit(cube, &state[1], 1, mtxCube);
-
- // Advance to next frame. Rendering thread will be kicked to
- // process submitted rendering primitives.
- bgfx::frame();
+ return false;
}
- meshUnload(bunny);
- meshUnload(cube);
- meshUnload(hollowcube);
+ entry::MouseState m_mouseState;
+ uint32_t m_width;
+ uint32_t m_height;
+ uint32_t m_debug;
+ uint32_t m_reset;
+
+ bgfx::UniformHandle s_shadowMap;
+ bgfx::UniformHandle u_lightPos;
+ bgfx::UniformHandle u_lightMtx;
+
+ bgfx::UniformHandle u_depthScaleOffset;
- meshStateDestroy(state[0]);
- meshStateDestroy(state[1]);
+ Mesh* m_bunny;
+ Mesh* m_cube;
+ Mesh* m_hollowcube;
- bgfx::destroyVertexBuffer(vbh);
- bgfx::destroyIndexBuffer(ibh);
+ bgfx::VertexBufferHandle m_vbh;
+ bgfx::IndexBufferHandle m_ibh;
- bgfx::destroyProgram(progShadow);
- bgfx::destroyProgram(progMesh);
+ uint16_t m_shadowMapSize;
- bgfx::destroyFrameBuffer(shadowMapFB);
+ bgfx::ProgramHandle m_progShadow;
+ bgfx::ProgramHandle m_progMesh;
+ bgfx::FrameBufferHandle m_shadowMapFB;
- bgfx::destroyUniform(u_shadowMap);
- bgfx::destroyUniform(u_lightPos);
- bgfx::destroyUniform(u_lightMtx);
- bgfx::destroyUniform(u_depthScaleOffset);
+ bool m_shadowSamplerSupported;
+
+ MeshState* m_state[2];
+
+ float m_view[16];
+ float m_proj[16];
+
+ int64_t m_timeOffset;
+};
- // Shutdown bgfx.
- bgfx::shutdown();
+} // namespace
- return 0;
-}
+ENTRY_IMPLEMENT_MAIN(ExampleShadowmapsSimple, "15-shadowmaps-simple", "Shadow maps example");