This commit is contained in:
bkaradzic 2013-10-18 23:05:33 -07:00
parent dcd0452d82
commit 49e14b2a54
1 changed files with 542 additions and 557 deletions

View File

@ -15,6 +15,15 @@
#include <string>
#include <vector>
#define RENDER_VIEWID_RANGE1_PASS_0 1
#define RENDER_VIEWID_RANGE1_PASS_1 2
#define RENDER_VIEWID_RANGE1_PASS_2 3
#define RENDER_VIEWID_RANGE1_PASS_3 4
#define RENDER_VIEWID_RANGE1_PASS_4 5
#define RENDER_VIEWID_RANGE1_PASS_5 6
#define RENDER_VIEWID_RANGE5_PASS_6 7
#define RENDER_VIEWID_RANGE1_PASS_7 13
uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w)
{
union
@ -273,10 +282,11 @@ void mtxShadow(float* __restrict _result
, const float* __restrict _light
)
{
float dot = _ground[0] * _light[0] +
_ground[1] * _light[1] +
_ground[2] * _light[2] +
_ground[3] * _light[3];
float dot = _ground[0] * _light[0]
+ _ground[1] * _light[1]
+ _ground[2] * _light[2]
+ _ground[3] * _light[3]
;
_result[ 0] = dot - _light[0] * _ground[0];
_result[ 1] = 0.0f - _light[1] * _ground[0];
@ -322,10 +332,6 @@ void mtxBillboard(float* __restrict _result
_result[15] = 1.0f;
}
//-------------------------------------------------
// Render state
//-------------------------------------------------
struct RenderState
{
enum Enum
@ -934,26 +940,30 @@ int _main_(int /*_argc*/, char** /*_argv*/)
int64_t timeOffset = bx::getHPCounter();
entry::MouseState mouseState;
while (!entry::processEvents(viewState.m_width, viewState.m_height, debug, reset, &mouseState) )
{
//imgui
static float settings_numLights = 4.0f;
static float settings_reflectionValue = 0.8f;
static bool settings_updateLights = true;
static bool settings_updateScene = true;
static enum Scene
enum Scene
{
StencilReflectionScene = 0,
ProjectionShadowsScene,
} scene = StencilReflectionScene;
}
static std::string titles[3] =
Scene scene = StencilReflectionScene;
float settings_numLights = 4.0f;
float settings_reflectionValue = 0.8f;
bool settings_updateLights = true;
bool settings_updateScene = true;
static const char* titles[3] =
{
"Stencil Reflection Scene",
"Projection Shadows Scene",
};
entry::MouseState mouseState;
while (!entry::processEvents(viewState.m_width, viewState.m_height, debug, reset, &mouseState) )
{
//imgui
imguiBeginFrame(mouseState.m_mx
, mouseState.m_my
, (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
@ -966,13 +976,13 @@ int _main_(int /*_argc*/, char** /*_argv*/)
static int32_t scrollArea = 0;
imguiBeginScrollArea("Settings", viewState.m_width - 256 - 10, 10, 256, 215, &scrollArea);
if (imguiCheck(titles[StencilReflectionScene].c_str(), StencilReflectionScene == scene))
if (imguiCheck(titles[StencilReflectionScene], StencilReflectionScene == scene) )
{
scene = StencilReflectionScene;
settings_numLights = 4.0f;
}
if (imguiCheck(titles[ProjectionShadowsScene].c_str(), ProjectionShadowsScene == scene))
if (imguiCheck(titles[ProjectionShadowsScene], ProjectionShadowsScene == scene) )
{
scene = ProjectionShadowsScene;
settings_numLights = 1.0f;
@ -985,20 +995,27 @@ int _main_(int /*_argc*/, char** /*_argv*/)
imguiSlider("Reflection value", &settings_reflectionValue, 0.0f, 1.0f, 0.01f);
}
if (imguiCheck("Update lights", settings_updateLights)) { settings_updateLights = !settings_updateLights; }
if (imguiCheck("Update scene", settings_updateScene)) { settings_updateScene = !settings_updateScene; }
if (imguiCheck("Update lights", settings_updateLights) )
{
settings_updateLights = !settings_updateLights;
}
if (imguiCheck("Update scene", settings_updateScene) )
{
settings_updateScene = !settings_updateScene;
}
imguiEndScrollArea();
imguiEndFrame();
//update settings
// Update settings.
numLights = (uint8_t)settings_numLights;
params.m_ambientPass = 1.0f;
params.m_lightningPass = 1.0f;
params.m_lightCount = settings_numLights;
bgfx::setUniform(u_params, (const void*)&params);
//time
// Time.
int64_t now = bx::getHPCounter();
static int64_t last = now;
const int64_t frameTime = now - last;
@ -1009,13 +1026,13 @@ int _main_(int /*_argc*/, char** /*_argv*/)
const float deltaTime = float(frameTime/freq);
bgfx::setUniform(u_time, &time);
//use debug font to print information about this example.
// Use debug font to print information about this example.
bgfx::dbgTextClear();
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/13-stencil");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Stencil reflections and shadows.");
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
//set view and projection matrices
// Set view and projection matrices.
const float aspect = float(viewState.m_width)/float(viewState.m_height);
mtxProj(viewState.m_proj, 60.0f, aspect, 0.1f, 100.0f);
float at[3] = { 0.0f, 5.0f, 0.0f };
@ -1039,7 +1056,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
for (uint8_t ii = 0; ii < numLights; ++ii)
{
lightPosRadius[ii][0] = sin( (lightTimeAccumulator*(1.1f + ii*0.07f) + float(ii*M_PI_2)*1.07f ) )*25.0f;
lightPosRadius[ii][1] = 7.0f + (1.0f - cos( (lightTimeAccumulator*(1.2f + ii*0.29f) + float(ii*M_PI_2)*1.49f )))*5.0f;
lightPosRadius[ii][1] = 7.0f + (1.0f - cos( (lightTimeAccumulator*(1.2f + ii*0.29f) + float(ii*M_PI_2)*1.49f ) ))*5.0f;
lightPosRadius[ii][2] = cos( (lightTimeAccumulator*(1.3f + ii*0.09f) + float(ii*M_PI_2)*1.79f ) )*20.0f;
lightPosRadius[ii][3] = radius;
}
@ -1131,43 +1148,28 @@ int _main_(int /*_argc*/, char** /*_argv*/)
color[2] = 1.0f;
bgfx::setUniform(u_color, color);
#define RENDER_VIEWID_RANGE1_PASS_0 1
#define RENDER_VIEWID_RANGE1_PASS_1 2
#define RENDER_VIEWID_RANGE1_PASS_2 3
#define RENDER_VIEWID_RANGE1_PASS_3 4
#define RENDER_VIEWID_RANGE1_PASS_4 5
#define RENDER_VIEWID_RANGE1_PASS_5 6
#define RENDER_VIEWID_RANGE5_PASS_6 7
#define RENDER_VIEWID_RANGE1_PASS_7 13
switch (scene)
{
case StencilReflectionScene:
{
/**
* First pass
* Draw plane.
*/
// First pass - Draw plane.
//floor
// Floor
hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
, floorMtx
, programColorBlack
, s_renderStates[RenderState::StencilReflection_CraftStencil]
);
/**
* Second pass
* Draw reflected objects.
*/
// Second pass - Draw reflected objects.
//compute reflected mtx
// Compute reflected matrix.
float reflectMtx[16];
float plane_pos[3] = { 0.0f, 0.01f, 0.0f };
float normal[3] = { 0.0f, 1.0f, 0.0f };
mtxReflected(reflectMtx, plane_pos, normal);
//reflect lights
// Reflect lights.
float reflectedLights[MAX_NUM_LIGHTS][4];
for (uint8_t ii = 0; ii < numLights; ++ii)
{
@ -1176,7 +1178,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
}
bgfx::setUniform(u_lightPosRadius, reflectedLights, numLights);
//reflect and submit bunny
// Reflect and submit bunny.
float mtxReflectedBunny[16];
mtxMul(mtxReflectedBunny, bunnyMtx, reflectMtx);
bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_1
@ -1185,7 +1187,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, s_renderStates[RenderState::StencilReflection_DrawReflected]
);
//reflect and submit columns
// Reflect and submit columns.
float mtxReflectedColumn[16];
for (uint8_t ii = 0; ii < 4; ++ii)
{
@ -1197,13 +1199,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
);
}
//set lights back
// Set lights back.
bgfx::setUniform(u_lightPosRadius, lightPosRadius, numLights);
/**
* Third pass
* Darken reflected objects
*/
// Third pass - Darken reflected objects.
uint8_t val = uint8_t(settings_reflectionValue * UINT8_MAX);
uint32_t factor = (val << 24)
@ -1213,19 +1212,16 @@ int _main_(int /*_argc*/, char** /*_argv*/)
;
s_renderStates[RenderState::StencilReflection_DarkenReflections].m_blendFactorRgba = factor;
//floor
// Floor.
hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_2
, floorMtx
, programColorBlack
, s_renderStates[RenderState::StencilReflection_DarkenReflections]
);
/**
* Fourth pass
* Draw plane. (blend plane with what's behind it)
*/
// Fourth pass - Draw plane. (blend plane with what's behind it)
//floor
// Floor.
hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_3
, floorMtx
, programTextureLightning
@ -1233,19 +1229,16 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, fieldstoneTex
);
/**
* Fifth pass
* Draw everything else but the plane.
*/
// Fifth pass - Draw everything else but the plane.
//bunny
// Bunny.
bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_4
, bunnyMtx
, programColorLightning
, s_renderStates[RenderState::StencilReflection_DrawScene]
);
//columns
// Columns.
for (uint8_t ii = 0; ii < 4; ++ii)
{
columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_4
@ -1256,24 +1249,22 @@ int _main_(int /*_argc*/, char** /*_argv*/)
}
}
break;
case ProjectionShadowsScene:
{
/**
* First pass
* Draw entire scene. (ambient only)
*/
// First pass - Draw entire scene. (ambient only).
params.m_ambientPass = 1.0f;
params.m_lightningPass = 1.0f;
bgfx::setUniform(u_params, (const void*)&params);
//bunny
// Bunny.
bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
, bunnyMtx
, programColorLightning
, s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
);
//floor
// Floor.
hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
, floorMtx
, programTextureLightning
@ -1281,7 +1272,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, fieldstoneTex
);
//cubes
// Cubes.
for (uint8_t ii = 0; ii < numCubes; ++ii)
{
cubeMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
@ -1292,36 +1283,31 @@ int _main_(int /*_argc*/, char** /*_argv*/)
);
}
//ground plane
// Ground plane.
float ground[4];
float plane_pos[3] = { 0.0f, 0.0f, 0.0f };
float normal[3] = { 0.0f, 1.0f, 0.0f };
memcpy(ground, normal, sizeof(float) * 3);
ground[3] = -vec3Dot(plane_pos, normal) - 0.01f; // - 0.01 against z-fighting
/**
* For each light:
*/
for (uint8_t ii = 0; ii < numLights; ++ii)
{
uint8_t viewId = RENDER_VIEWID_RANGE5_PASS_6+ii;
clearView(viewId, BGFX_CLEAR_STENCIL_BIT, clearValues);
/**
* Draw shadow projection of scene objects.
*/
// Draw shadow projection of scene objects.
//get homogeneous light pos
// Get homogeneous light pos.
float* lightPos = lightPosRadius[ii];
float pos[4];
memcpy(pos, lightPos, sizeof(float) * 3);
pos[3] = 1.0f;
//calculate shadow mtx for current light
// Calculate shadow mtx for current light.
float shadowMtx[16];
mtxShadow(shadowMtx, ground, pos);
//submit bunny's shadow
// Submit bunny's shadow.
float mtxShadowedBunny[16];
mtxMul(mtxShadowedBunny, bunnyMtx, shadowMtx);
bunnyMesh.submit(viewId
@ -1330,7 +1316,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, s_renderStates[RenderState::ProjectionShadows_CraftStencil]
);
//submit cube shadows
// Submit cube shadows.
float mtxShadowedCube[16];
for (uint8_t ii = 0; ii < numCubes; ++ii)
{
@ -1342,14 +1328,13 @@ int _main_(int /*_argc*/, char** /*_argv*/)
);
}
/**
* Draw entire scene. (lightning pass only. blending is on)
*/
// Draw entire scene. (lightning pass only. blending is on)
params.m_ambientPass = 0.0f;
params.m_lightningPass = 1.0f;
bgfx::setUniform(u_params, (const void*)&params);
//set blending factor based on number of lights
// Set blending factor based on number of lights.
uint32_t factor = 0xff / (numLights < 1 ? 1 : numLights);
factor = (factor << 24)
| (factor << 16)
@ -1358,14 +1343,14 @@ int _main_(int /*_argc*/, char** /*_argv*/)
;
s_renderStates[RenderState::ProjectionShadows_DrawDiffuse].m_blendFactorRgba = factor;
//bunny
// Bunny.
bunnyMesh.submit(viewId
, bunnyMtx
, programColorLightning
, s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
);
//floor
// Floor.
hplaneMesh.submit(viewId
, floorMtx
, programTextureLightning
@ -1373,7 +1358,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, fieldstoneTex
);
//cubes
// Cubes.
for (uint8_t ii = 0; ii < numCubes; ++ii)
{
cubeMesh.submit(viewId
@ -1385,7 +1370,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
}
}
//reset these to default
// Reset these to default..
params.m_ambientPass = 1.0f;
params.m_lightningPass = 1.0f;
bgfx::setUniform(u_params, (const void*)&params);
@ -1412,7 +1397,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
);
}
//draw floor bottom
// Draw floor bottom.
float floorBottomMtx[16];
mtxScaleRotateTranslate(floorBottomMtx
, 20.0f //scaleX
@ -1433,7 +1418,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, figureTex
);
//setup view rect and transform for all used views
// Setup view rect and transform for all used views.
setViewRectTransformMask(s_viewMask, viewState);
s_viewMask = 0;
@ -1446,7 +1431,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
s_clearMask = 0;
}
// Cleanup
// Cleanup.
bunnyMesh.unload();
columnMesh.unload();
cubeMesh.unload();