52 lines
1.6 KiB
C++
52 lines
1.6 KiB
C++
#pragma once
|
||
|
||
#include <string>
|
||
#include <unordered_map>
|
||
|
||
#include <osg/ref_ptr>
|
||
#include <osg/Program>
|
||
#include <osg/Node>
|
||
#include <osg/StateSet>
|
||
|
||
/**
|
||
* ShaderManager
|
||
* -------------
|
||
* Loads, caches, and applies GLSL shader programs to OSG nodes.
|
||
*
|
||
* Supported modes (toggled at runtime via applyTo):
|
||
* "flat" – unlit, texture/vertex colour only
|
||
* "cel" – quantised diffuse bands
|
||
* "toon" – cel + hard specular + rim light + outline shell
|
||
*
|
||
* Shaders are loaded from `shaderDir` (default: assets/shaders/).
|
||
* Editing the .glsl files and calling reload() hot-reloads them.
|
||
*/
|
||
class ShaderManager {
|
||
public:
|
||
explicit ShaderManager(const std::string& shaderDir = "assets/shaders");
|
||
|
||
/// Apply a named shader mode to `node`'s StateSet.
|
||
/// Also sets sensible default uniforms.
|
||
void applyTo(osg::Node* node, const std::string& mode);
|
||
|
||
/// Re-read all .glsl files from disk (call after editing shaders).
|
||
void reload();
|
||
|
||
/// Update the light direction uniform on an already-shaded node
|
||
/// (call when the light moves). `dirVS` should be in view space.
|
||
static void setLightDir(osg::StateSet* ss, const osg::Vec3f& dirVS);
|
||
|
||
private:
|
||
osg::ref_ptr<osg::Program> buildProgram(const std::string& vertFile,
|
||
const std::string& fragFile);
|
||
|
||
void setCommonUniforms(osg::StateSet* ss);
|
||
void setCelUniforms (osg::StateSet* ss);
|
||
void setToonUniforms (osg::StateSet* ss);
|
||
|
||
std::string m_shaderDir;
|
||
|
||
// Cache: mode name → compiled program
|
||
std::unordered_map<std::string, osg::ref_ptr<osg::Program>> m_programs;
|
||
};
|