Skip to content

Commit f6e2e75

Browse files
committed
Extend ch10_ltc GUI to switch between application modes.
1 parent c2abd14 commit f6e2e75

File tree

3 files changed

+153
-55
lines changed

3 files changed

+153
-55
lines changed

src/apps/ch10_ltc/ch10_ltc/Scene.cpp

Lines changed: 114 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,18 @@ void validateVertexAttributes(const renderer::IntrospectProgram & aProgram)
8484
}
8585

8686

87-
// This program replicates the results from figure 2
88-
//const std::filesystem::path gProgramPath = "programs/ch10_ltc_ShowBasicLtc.prog";
87+
std::array<const std::filesystem::path, 3> gProgramPaths = {{
88+
// The integration demo, lighting a sphere from a polygon
89+
"programs/ch10_ltc_PolygonLight.prog",
90+
//"programs/RenderModel_PlainColor.prog",
91+
// This program replicates the plots from the ltc_code repository
92+
// (and lower line of Figure 5 in the paper).
93+
// Use controls alpha and view polar angle, and the sphere show resulting LTC.
94+
"programs/ch10_ltc_ShowGgxLtc.prog",
95+
// This program replicates the results from figure 2
96+
"programs/ch10_ltc_ShowBasicLtc.prog",
97+
}};
8998

90-
// This program replicates the plots from the ltc_code repository
91-
// (and lower line of Figure 5 in the paper).
92-
// Use controls alpha and view polar angle, and the sphere show resulting LTC.
93-
//const std::filesystem::path gProgramPath = "programs/ch10_ltc_ShowGgxLtc.prog";
94-
95-
96-
// The integration demo, lighting a sphere from a polygon
97-
const std::filesystem::path gProgramPath = "programs/ch10_ltc_PolygonLight.prog";
9899

99100
const std::filesystem::path gLightProgramPath = "programs/RenderModel_PlainColor.prog";
100101

@@ -125,12 +126,13 @@ Scene::Scene(graphics::AppInterface & aAppInterface, const imguiui::ImguiUi & aI
125126
//std::span{scenic::icosahedron::gIndices},
126127
std::span{mSphere.mIndices},
127128
graphics::BufferHint::StaticDraw)},
128-
mSurfaceProgram{mEngine.loadProgram(renderer::ReferencePath{gProgramPath})},
129129
mLightProgram{mEngine.loadProgram(renderer::ReferencePath{gLightProgramPath})},
130130
mLtcColorMap{GL_TEXTURE_1D},
131131
mLtc_1{ mEngine.loadDds(renderer::ReferencePath{"textures/ltc_1.dds"}) },
132132
mLtc_2{ mEngine.loadDds(renderer::ReferencePath{"textures/ltc_2.dds"}) }
133133
{
134+
loadPrograms();
135+
134136
graphics::attachIndexBuffer(mSphereIndexBuffer, mSphereVertexSpecification.mVertexArray);
135137

136138
graphics::appendToVertexSpecification(
@@ -221,8 +223,12 @@ void Scene::loadPrograms()
221223
{
222224
mLightProgram =
223225
mEngine.loadProgram(renderer::ReferencePath{ gLightProgramPath });
224-
mSurfaceProgram =
225-
mEngine.loadProgram(renderer::ReferencePath{ gProgramPath });
226+
mSurfacePrograms.clear();
227+
for (std::size_t i = 0; i != (std::size_t)FrameControl::AppMode::_End; ++i)
228+
{
229+
mSurfacePrograms.push_back(
230+
mEngine.loadProgram(renderer::ReferencePath{gProgramPaths[i]}));
231+
}
226232
}
227233

228234

@@ -300,29 +306,39 @@ void Scene::render(math::Size<2, int> aRenderResolution)
300306
mOrbitalCamera.getViewProjectionBlock(),
301307
graphics::BufferHint::StreamDraw);
302308

309+
310+
renderer::IntrospectProgram & program =
311+
mSurfacePrograms[(std::size_t)mFrameControl.mAppMode];
303312
//
304313
// Textures
305314
//
306315
{
307316
GLint unitIdx = 1;
308317
glBindTextureUnit(unitIdx, mLtcColorMap);
309-
graphics::setUniform(mSurfaceProgram, "u_LtcColorMap", unitIdx);
318+
graphics::setUniform(program, "u_LtcColorMap", unitIdx);
310319

311320
++unitIdx;
312321
glBindTextureUnit(unitIdx, mLtc_1);
313-
graphics::setUniform(mSurfaceProgram, "u_Ltc_1", unitIdx);
322+
graphics::setUniform(program, "u_Ltc_1", unitIdx);
314323

315324
++unitIdx;
316325
glBindTextureUnit(unitIdx, mLtc_2);
317-
graphics::setUniform(mSurfaceProgram, "u_Ltc_2", unitIdx);
326+
graphics::setUniform(program, "u_Ltc_2", unitIdx);
318327
}
319328

320329
//
321330
// LTC
322331
//
323332
{
324-
graphics::setUniform(mSurfaceProgram, "u_alpha", mLtcControl.mAlpha);
325-
graphics::setUniform(mSurfaceProgram, "u_thetaViewDir", mLtcControl.mViewAngle.data());
333+
graphics::setUniform(program, "u_alpha", mLtcControl.mAlpha);
334+
graphics::setUniform(program, "u_thetaViewDir", mLtcControl.mViewAngle.data());
335+
}
336+
337+
//
338+
// Figure 2 (see paper "Real-Time Polygonal-Light Shading with Linearly Transformed Cosines")
339+
//
340+
{
341+
graphics::setUniform(program, "u_Letter", mFigureControl.mLetter);
326342
}
327343

328344
//
@@ -349,8 +365,8 @@ void Scene::render(math::Size<2, int> aRenderResolution)
349365
const GLuint sphereCount = 1;
350366

351367
// TODO: should be done only once for each pair of VAO-program
352-
validateVertexAttributes(mSurfaceProgram);
353-
glUseProgram(mSurfaceProgram);
368+
validateVertexAttributes(program);
369+
glUseProgram(program);
354370

355371
glDrawElementsInstancedBaseInstance(
356372
GL_PATCHES,
@@ -361,17 +377,51 @@ void Scene::render(math::Size<2, int> aRenderResolution)
361377
0);
362378

363379

364-
glDisable(GL_CULL_FACE);
365-
glBindVertexArray(mCardLightVertexSpecification.mVertexArray);
366-
// TODO: should be done only once for each pair of VAO-program
367-
validateVertexAttributes(mLightProgram);
368-
glUseProgram(mLightProgram);
369-
glDrawArraysInstancedBaseInstance(
370-
GL_TRIANGLE_STRIP,
371-
0,
372-
std::size(scenic::quad::gVertices),
373-
mLights.mPlanarCount,
374-
sphereCount);
380+
if (mFrameControl.mAppMode == FrameControl::AppMode::Shaded_scene)
381+
{
382+
glDisable(GL_CULL_FACE);
383+
glBindVertexArray(mCardLightVertexSpecification.mVertexArray);
384+
// TODO: should be done only once for each pair of VAO-program
385+
validateVertexAttributes(mLightProgram);
386+
glUseProgram(mLightProgram);
387+
glDrawArraysInstancedBaseInstance(
388+
GL_TRIANGLE_STRIP,
389+
0,
390+
std::size(scenic::quad::gVertices),
391+
mLights.mPlanarCount,
392+
sphereCount);
393+
}
394+
}
395+
396+
397+
std::string to_string(Scene::FrameControl::AppMode aValue)
398+
{
399+
#define STR(enumerator) case Scene::FrameControl::AppMode::##enumerator: return #enumerator
400+
switch (aValue)
401+
{
402+
STR(Fig2);
403+
STR(Ltc_viewer);
404+
STR(Shaded_scene);
405+
default:
406+
throw std::logic_error{ "Unhandled AppMode." };
407+
}
408+
#undef STR
409+
}
410+
411+
412+
std::string to_string(Scene::FigureControl::Letter aValue)
413+
{
414+
#define STR(enumerator) case Scene::FigureControl::##enumerator: return #enumerator
415+
switch (aValue)
416+
{
417+
STR(a);
418+
STR(b);
419+
STR(c);
420+
STR(d);
421+
default:
422+
throw std::logic_error{ "Unhandled figure." };
423+
}
424+
#undef STR
375425
}
376426

377427

@@ -392,6 +442,9 @@ void Scene::presentUi(bool * aOpen)
392442
}
393443
}
394444

445+
imguiui::addComboContinuousEnum<FrameControl::AppMode::_End>(
446+
"App mode", mFrameControl.mAppMode);
447+
395448
imguiui::addCombo("Polygon mode",
396449
mFrameControl.mPolygonMode,
397450
FrameControl::gPolygonModes.begin(),
@@ -401,25 +454,41 @@ void Scene::presentUi(bool * aOpen)
401454
DearImguiWitness witness;
402455

403456
ImGui::Spacing();
404-
describe(witness, mTessControl);
405457

406-
ImGui::Spacing();
407-
if (ImGui::CollapsingHeader("Ltc"))
458+
if (ImGui::CollapsingHeader("Tessellation"))
408459
{
409-
ImGui::DragFloat("Alpha", &mLtcControl.mAlpha, 0.005, 0.f, 1.f);
410-
ImGui::SliderAngle("View polar angle", &mLtcControl.mViewAngle.data(), 0.f, 90.f);
460+
describe(witness, mTessControl);
411461
}
412462

413-
//ImGui::Spacing();
414-
if (ImGui::CollapsingHeader("Materials"))
463+
switch (mFrameControl.mAppMode)
415464
{
416-
describe(witness, mMaterials);
417-
}
418-
419-
ImGui::Spacing();
420-
if (ImGui::CollapsingHeader("Lights"))
421-
{
422-
describe(witness, mLights);
465+
case FrameControl::AppMode::Shaded_scene:
466+
{
467+
if (ImGui::CollapsingHeader("Materials"))
468+
{
469+
describe(witness, mMaterials);
470+
}
471+
if (ImGui::CollapsingHeader("Lights"))
472+
{
473+
describe(witness, mLights);
474+
}
475+
break;
476+
}
477+
case FrameControl::AppMode::Ltc_viewer:
478+
{
479+
if (ImGui::CollapsingHeader("Ltc"))
480+
{
481+
ImGui::DragFloat("Alpha", &mLtcControl.mAlpha, 0.005, 0.f, 1.f);
482+
ImGui::SliderAngle("View polar angle", &mLtcControl.mViewAngle.data(), 0.f, 90.f);
483+
}
484+
break;
485+
}
486+
case FrameControl::AppMode::Fig2:
487+
{
488+
imguiui::addComboContinuousEnum<FigureControl::Letter::_End>(
489+
"Figure", mFigureControl.mLetter);
490+
break;
491+
}
423492
}
424493

425494
ImGui::End();

src/apps/ch10_ltc/ch10_ltc/Scene.h

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,22 @@ struct Scene
6363

6464
struct FrameControl
6565
{
66-
inline static constexpr std::array<GLenum, 3> gPolygonModes{
67-
GL_POINT,
68-
GL_LINE,
69-
GL_FILL,
70-
};
71-
72-
decltype(gPolygonModes)::const_iterator mPolygonMode = gPolygonModes.begin() + 2;
66+
enum class AppMode
67+
{
68+
Shaded_scene,
69+
Ltc_viewer,
70+
Fig2,
71+
_End/*keep last*/
72+
};
73+
74+
inline static constexpr std::array<GLenum, 3> gPolygonModes{
75+
GL_POINT,
76+
GL_LINE,
77+
GL_FILL,
78+
};
79+
80+
AppMode mAppMode = AppMode::Shaded_scene;
81+
decltype(gPolygonModes)::const_iterator mPolygonMode = gPolygonModes.begin() + 2;
7382
};
7483

7584
struct LtcControl
@@ -80,6 +89,20 @@ struct Scene
8089
math::Radian<float> mViewAngle{ math::Degree<float>{45.f} };
8190
};
8291

92+
struct FigureControl
93+
{
94+
enum Letter : GLuint
95+
{
96+
a,
97+
b,
98+
c,
99+
d,
100+
_End/*keep last*/
101+
};
102+
103+
Letter mLetter = c;
104+
};
105+
83106
Scene(graphics::AppInterface & aAppInterface, const imguiui::ImguiUi & aImgui);
84107

85108
void loadPrograms();
@@ -104,7 +127,7 @@ struct Scene
104127
graphics::UniformBufferObject mViewProjectionBuffer;
105128
graphics::UniformBufferObject mMaterialsBlockBuffer;
106129
graphics::UniformBufferObject mLightsBlockBuffer;
107-
renderer::IntrospectProgram mSurfaceProgram;
130+
std::vector<renderer::IntrospectProgram> mSurfacePrograms;
108131
renderer::IntrospectProgram mLightProgram;
109132
graphics::Texture mLtcColorMap;
110133
graphics::Texture mLtc_1;
@@ -146,7 +169,13 @@ struct Scene
146169
TessellationControl mTessControl;
147170
FrameControl mFrameControl;
148171
LtcControl mLtcControl;
172+
FigureControl mFigureControl;
149173
};
150174

151175

176+
std::string to_string(Scene::FrameControl::AppMode aValue);
177+
178+
std::string to_string(Scene::FigureControl::Letter aValue);
179+
180+
152181
} // namespace ad

src/apps/ch10_ltc/ch10_ltc/resources/shaders/ch10_ltc_ShowBasicLtc.frag

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ in vec3 ex_Normal_view;
99
in vec3 ex_Position_view;
1010

1111
uniform sampler1D u_LtcColorMap;
12+
uniform uint u_Letter = 2;
1213

1314
out vec4 out_Color;
1415

@@ -43,11 +44,10 @@ void main(void)
4344
// GLSL matrices are column major (so, the first 3 values are the first column)
4445

4546
// Mode 0 to 3 maps to domains a to d in Figure 2.
46-
uint mode = 2;
4747
mat3 M = mat3(1);
4848
vec3 maxDir = vec3(0, 0, 1);
4949

50-
switch (mode)
50+
switch (u_Letter)
5151
{
5252
case 1:
5353
M = mat3(0.3, 0, 0,

0 commit comments

Comments
 (0)