-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathgeneric_shader_program.h
190 lines (159 loc) · 7.62 KB
/
generic_shader_program.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Copyright (C) 2020-2025 Sami Väisänen
// Copyright (C) 2020-2025 Ensisoft http://www.ensisoft.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include "config.h"
#include "warnpush.h"
# include <glm/vec3.hpp>
#include "warnpop.h"
#include <string>
#include <vector>
#include <memory>
#include "base/bitflag.h"
#include "graphics/enum.h"
#include "graphics/types.h"
#include "graphics/shader_program.h"
namespace gfx
{
//
// Light Types and Components:
// -----------------------------------------------------------------------------------------------------------
// | Light Type | Description | Ambient | Diffuse | Specular |
// |------------------|-------------------------------------------------------|---------|---------|----------|
// | Ambient Light | Simulates global illumination, uniform lighting. | Yes | No | No |
// | Directional Light| Parallel rays, simulates distant sources (e.g., sun). | Yes | Yes | Yes |
// | Point Light | Emits light from a point source in all directions. | Yes | Yes | Yes |
// | Spotlight | Point light constrained to a cone, with attenuation. | Yes | Yes | Yes |
// -----------------------------------------------------------------------------------------------------------
//
// Light Components Description:
// - Ambient Component:
// * A constant illumination applied equally to all objects.
// * Simulates indirect lighting, ensuring no part of the scene is completely dark.
//
// - Diffuse Component:
// * Illumination depends on the angle between the light direction and surface normal.
// * Creates shading that gives objects a sense of shape and depth.
//
// - Specular Component:
// * A shiny highlight dependent on view direction and light reflection.
// * Simulates reflective properties of materials.
//
// Light Types Description:
// - Ambient Light:
// * A global light source that evenly illuminates all objects without direction or distance considerations.
//
// - Directional Light:
// * Light with parallel rays, typically used to simulate sunlight.
// * Does not attenuate with distance as the source is infinitely far away.
//
// - Point Light:
// * Emits light in all directions from a single point in 3D space.
// * Includes attenuation to simulate the light weakening over distance.
//
// - Spotlight:
// * A point light constrained to a cone.
// * Includes direction, cutoff angle (cone angle), and attenuation for realistic spotlight effects.
//
class GenericShaderProgram : public ShaderProgram
{
public:
static constexpr auto MAX_LIGHTS = 10;
enum class ShadingFeatures {
BasicLight, BasicFog
};
enum class OutputFeatures {
WriteColorTarget, WriteBloomTarget
};
using LightType = BasicLightType;
using FogMode = BasicFogMode;
using Light = BasicLight;
using Fog = BasicFog;
GenericShaderProgram() noexcept
{
mOutputFeatures.set(OutputFeatures::WriteColorTarget, true);
}
explicit GenericShaderProgram(std::string name, RenderPass renderPass) noexcept
: mName(std::move(name))
{
mOutputFeatures.set(OutputFeatures::WriteColorTarget, true);
}
inline auto GetLightCount() const noexcept
{ return mLights.size(); }
inline const auto& GetLight(size_t index) const noexcept
{ return base::SafeIndex(mLights, index); }
inline auto GetLight(size_t index) noexcept
{ return *base::SafeIndex(mLights, index); }
inline void AddLight(const Light& light)
{ mLights.push_back(MakeSharedLight(light)); }
inline void AddLight(Light&& light)
{ mLights.push_back(MakeSharedLight(std::move(light))); }
inline void AddLight(std::shared_ptr<const Light> light)
{ mLights.push_back(std::move(light)); }
inline void SetLight(const Light& light, size_t index) noexcept
{ base::SafeIndex(mLights, index) = MakeSharedLight(light); }
inline void SetLight(Light&& light, size_t index) noexcept
{ base::SafeIndex(mLights, index) = MakeSharedLight(std::move(light)); }
inline void ClearLights() noexcept
{ mLights.clear(); }
inline void SetFog(const Fog& fog) noexcept
{ mFog = fog; }
inline void SetBloomColor(const gfx::Color4f& color) noexcept
{ mBloomColor = color; }
inline void SetBloomThreshold(float threshold) noexcept
{ mBloomThreshold = threshold; }
inline void SetCameraCenter(glm::vec3 center) noexcept
{ mCameraCenter = center; }
inline void SetCameraCenter(float x, float y, float z) noexcept
{ mCameraCenter = glm::vec3 {x, y, z }; }
inline void EnableFeature(ShadingFeatures feature, bool on_off) noexcept
{ mShadingFeatures.set(feature, on_off); }
inline void EnableFeature(OutputFeatures features, bool on_off) noexcept
{ mOutputFeatures.set(features, on_off); }
inline bool TestFeature(ShadingFeatures feature) const noexcept
{ return mShadingFeatures.test(feature); }
inline bool TestFeature(OutputFeatures feature) const noexcept
{ return mOutputFeatures.test(feature); }
std::string GetName() const override
{ return mName; }
RenderPass GetRenderPass() const override
{ return mRenderPass; }
std::string GetShaderId(const Material& material, const Material::Environment& env) const override;
std::string GetShaderId(const Drawable& drawable, const Drawable::Environment& env) const override;
ShaderSource GetShader(const Material& material, const Material::Environment& env, const Device& device) const override;
ShaderSource GetShader(const Drawable& drawable, const Drawable::Environment& env, const Device& device) const override;
void ApplyDynamicState(const Device& device, ProgramState& program) const override;
void ApplyLightState(const Device& device, ProgramState& program) const;
void ApplyFogState(const Device& device, ProgramState& program) const;
static std::shared_ptr<const Light> MakeSharedLight(const Light& data)
{
return std::make_shared<Light>(data);
}
static std::shared_ptr<const Light> MakeSharedLight(Light&& light)
{
return std::make_shared<Light>(std::move(light));
}
private:
std::string mName;
std::vector<std::shared_ptr<const Light>> mLights;
glm::vec3 mCameraCenter = {0.0f, 0.0f, 0.0f};
gfx::Color4f mBloomColor;
float mBloomThreshold = 0.0f;
base::bitflag<ShadingFeatures> mShadingFeatures;
base::bitflag<OutputFeatures> mOutputFeatures;
RenderPass mRenderPass = RenderPass::ColorPass;
Fog mFog;
};
} // namespace