Last active
April 6, 2022 14:25
-
-
Save FrankRicharrd/3b94939748cf5c7c494fbd41c7e67285 to your computer and use it in GitHub Desktop.
Multiple lights in openscenegraph using GLSL shaders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//multiplelights.vert | |
#version 330 core | |
layout (location = 0) in vec3 aPos; | |
layout (location = 1) in vec3 aNormal; | |
layout (location = 3) in vec4 aTexCoords; | |
out vec3 FragPos; | |
out vec3 Normal; | |
out vec2 TexCoords; | |
uniform mat4 osg_ModelViewProjectionMatrix; | |
uniform mat4 osg_ModelViewMatrix; | |
uniform mat4 osg_ViewMatrixInverse; | |
uniform mat3 osg_NormalMatrix; | |
uniform mat4 osg_ViewMatrix; | |
void main() | |
{ | |
mat4 newModel = osg_ViewMatrixInverse * osg_ModelViewMatrix; | |
FragPos = vec3(newModel * vec4(aPos, 1.0)); | |
Normal = mat3(transpose(inverse(newModel))) * aNormal; | |
TexCoords = aTexCoords.xy; | |
gl_Position = osg_ModelViewProjectionMatrix * vec4(aPos, 1.0); | |
} | |
//multiplelights.frag | |
#version 330 core | |
out vec4 FragColor; | |
struct Material { | |
sampler2D diffuse; | |
sampler2D specular; | |
float shininess; | |
}; | |
struct DirLight { | |
vec3 direction; | |
vec3 ambient; | |
vec3 diffuse; | |
vec3 specular; | |
}; | |
struct PointLight { | |
vec3 position; | |
float constant; | |
float linear; | |
float quadratic; | |
vec3 ambient; | |
vec3 diffuse; | |
vec3 specular; | |
}; | |
struct SpotLight { | |
vec3 position; | |
vec3 direction; | |
float cutOff; | |
float outerCutOff; | |
float constant; | |
float linear; | |
float quadratic; | |
vec3 ambient; | |
vec3 diffuse; | |
vec3 specular; | |
}; | |
#define NR_POINT_LIGHTS 4 | |
in vec3 FragPos; | |
in vec3 Normal; | |
in vec2 TexCoords; | |
uniform vec3 viewPos; | |
uniform DirLight dirLight; | |
uniform PointLight pointLights[NR_POINT_LIGHTS]; | |
uniform SpotLight spotLight; | |
uniform Material material; | |
// function prototypes | |
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); | |
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); | |
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); | |
void main() | |
{ | |
// properties | |
vec3 norm = normalize(Normal); | |
vec3 viewDir = normalize(viewPos - FragPos); | |
// == ===================================================== | |
// Our lighting is set up in 3 phases: directional, point lights and an optional flashlight | |
// For each phase, a calculate function is defined that calculates the corresponding color | |
// per lamp. In the main() function we take all the calculated colors and sum them up for | |
// this fragment's final color. | |
// == ===================================================== | |
// phase 1: directional lighting | |
vec3 result = CalcDirLight(dirLight, norm, viewDir); | |
// phase 2: point lights | |
for(int i = 0; i < NR_POINT_LIGHTS; i++) | |
result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); | |
// phase 3: spot light | |
result += CalcSpotLight(spotLight, norm, FragPos, viewDir); | |
FragColor = vec4(result, 1.0); | |
} | |
// calculates the color when using a directional light. | |
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir) | |
{ | |
vec3 lightDir = normalize(-light.direction); | |
// diffuse shading | |
float diff = max(dot(normal, lightDir), 0.0); | |
// specular shading | |
vec3 reflectDir = reflect(-lightDir, normal); | |
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); | |
// combine results | |
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); | |
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); | |
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); | |
return (ambient + diffuse + specular); | |
} | |
// calculates the color when using a point light. | |
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) | |
{ | |
vec3 lightDir = normalize(light.position - fragPos); | |
// diffuse shading | |
float diff = max(dot(normal, lightDir), 0.0); | |
// specular shading | |
vec3 reflectDir = reflect(-lightDir, normal); | |
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); | |
// attenuation | |
float distance = length(light.position - fragPos); | |
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); | |
// combine results | |
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); | |
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); | |
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); | |
ambient *= attenuation; | |
diffuse *= attenuation; | |
specular *= attenuation; | |
return (ambient + diffuse + specular); | |
} | |
// calculates the color when using a spot light. | |
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) | |
{ | |
vec3 lightDir = normalize(light.position - fragPos); | |
// diffuse shading | |
float diff = max(dot(normal, lightDir), 0.0); | |
// specular shading | |
vec3 reflectDir = reflect(-lightDir, normal); | |
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); | |
// attenuation | |
float distance = length(light.position - fragPos); | |
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); | |
// spotlight intensity | |
float theta = dot(lightDir, normalize(-light.direction)); | |
float epsilon = light.cutOff - light.outerCutOff; | |
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); | |
// combine results | |
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); | |
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); | |
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); | |
ambient *= attenuation * intensity; | |
diffuse *= attenuation * intensity; | |
specular *= attenuation * intensity; | |
return (ambient + diffuse + specular); | |
} | |
//multiplelights.h | |
#include <osg/Node> | |
class MultipleLights | |
{ | |
public: | |
MultipleLights(osg::Group* root, osg::Camera* camera); | |
~MultipleLights(); | |
osg::Group* _root; osg::Camera* _camera; | |
void CreateModel(); | |
void CreateTextures(osg::Node* node, std::string imagePath, unsigned int unit); | |
void CreateShaders(osg::Node* node, osg::MatrixTransform* rootTransForm); | |
void CreateShadersForLight(osg::Node* node); | |
void CreateLightGeom(osg::MatrixTransform* root, osg::Vec3 lightVecPos, osg::Shape* shape); | |
std::string get_file_string(std::string filePath); | |
}; | |
//multiplelights.cpp | |
#include "stdafx.h" | |
#include "MultipleLights.h" | |
class ViewPosCBMultiLights : public osg::Uniform::Callback | |
{ | |
osg::ref_ptr<osg::Camera> _cam; | |
public: | |
ViewPosCBMultiLights(osg::Camera* cam) | |
{ | |
_cam = cam; | |
} | |
virtual void operator()(osg::Uniform* uniform, | |
osg::NodeVisitor* nv) | |
{ | |
osg::Vec3 eye, center, up; | |
_cam->getViewMatrixAsLookAt(eye, center, up); | |
uniform->set(osg::Vec3(eye.x(), eye.y(), eye.z())); | |
} | |
}; | |
MultipleLights::MultipleLights(osg::Group* root, osg::Camera* camera) : _root(root), _camera(camera) | |
{ | |
} | |
MultipleLights::~MultipleLights() | |
{ | |
} | |
void MultipleLights::CreateModel() | |
{ | |
osg::ref_ptr<osg::Vec3Array> vertexArray = new osg::Vec3Array; | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, -0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, -0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, 0.5f)); | |
vertexArray->push_back(osg::Vec3(-0.5f, 0.5f, -0.5f)); | |
osg::ref_ptr<osg::Vec3Array> normalArray = new osg::Vec3Array; | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); | |
normalArray->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); | |
normalArray->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); | |
osg::ref_ptr<osg::Vec2Array> texCor = new osg::Vec2Array; | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 1.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(1.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 0.0f)); | |
texCor->push_back(osg::Vec2(0.0f, 1.0f)); | |
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry; | |
geom->setVertexArray(vertexArray.get()); | |
geom->setNormalArray(normalArray.get(), osg::Array::Binding::BIND_PER_VERTEX); | |
geom->setTexCoordArray(0, texCor.get(), osg::Array::Binding::BIND_PER_VERTEX); | |
geom->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 36)); | |
osg::ref_ptr<osg::Geode> geode = new osg::Geode; | |
geode->addDrawable(geom); | |
std::string diffuseImagePath = "/container2.png"; | |
std::string specularImagePath = "/container2_specular.png"; | |
CreateTextures(geode, diffuseImagePath, 0); | |
CreateTextures(geode, specularImagePath, 1); | |
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform; | |
trans->addChild(geode); | |
CreateShaders(geode, trans); | |
_root->addChild(trans); | |
} | |
void MultipleLights::CreateTextures(osg::Node * node, std::string imagePath, unsigned int unit) | |
{ | |
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D; | |
osg::ref_ptr<osg::Image> image = | |
osgDB::readImageFile(imagePath); | |
texture->setImage(image.get()); | |
texture->setWrap(osg::Texture::WrapParameter::WRAP_S, osg::Texture::WrapMode::REPEAT); | |
texture->setWrap(osg::Texture::WrapParameter::WRAP_T, osg::Texture::WrapMode::REPEAT); | |
texture->setFilter(osg::Texture::FilterParameter::MIN_FILTER, osg::Texture::FilterMode::LINEAR_MIPMAP_LINEAR); | |
texture->setFilter(osg::Texture::FilterParameter::MAG_FILTER, osg::Texture::FilterMode::LINEAR); | |
node->getOrCreateStateSet()->setTextureAttributeAndModes(unit, texture.get()); | |
} | |
void MultipleLights::CreateShaders(osg::Node * node, osg::MatrixTransform * rootTransForm) | |
{ | |
std::string vertSource = get_file_string("/multiplelights.vert"); | |
std::string fragSource = get_file_string("/multiplelights.frag"); | |
osg::ref_ptr<osg::Program> program = new osg::Program; | |
program->addShader(new osg::Shader(osg::Shader::VERTEX, | |
vertSource)); | |
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, | |
fragSource)); | |
osg::StateSet* stateset = node->getOrCreateStateSet(); // replace inst with your osg::node | |
stateset->setAttributeAndModes(program.get()); | |
osg::Vec3 eye, center, up; | |
_camera->getViewMatrixAsLookAt(eye, center, up); | |
osg::ref_ptr<osg::Uniform> viewPos = new osg::Uniform( | |
"viewPos", eye); | |
viewPos->setUpdateCallback(new ViewPosCBMultiLights(_camera)); | |
stateset->addUniform(viewPos.get()); | |
osg::Uniform* diffuseUniform = new osg::Uniform(osg::Uniform::SAMPLER_2D, "material.diffuse"); | |
diffuseUniform->set(0); | |
stateset->addUniform(diffuseUniform); | |
osg::Uniform* specularUniform = new osg::Uniform(osg::Uniform::SAMPLER_2D, "material.specular"); | |
specularUniform->set(1); | |
stateset->addUniform(specularUniform); | |
stateset->addUniform(new osg::Uniform("material.shininess", 32.0f)); | |
osg::Vec3 pointLightPositions[] = { | |
osg::Vec3(0.7f, 0.2f, 2.0f), | |
osg::Vec3(2.3f, -3.3f, -4.0f), | |
osg::Vec3(-4.0f, 2.0f, -12.0f), | |
osg::Vec3(0.0f, 0.0f, -3.0f) | |
}; | |
CreateLightGeom(rootTransForm, pointLightPositions[0], new osg::Sphere(osg::Vec3(0, 0, 0), 0.5)); | |
CreateLightGeom(rootTransForm, pointLightPositions[1], new osg::Sphere(osg::Vec3(0, 0, 0), 0.5)); | |
CreateLightGeom(rootTransForm, pointLightPositions[2], new osg::Sphere(osg::Vec3(0, 0, 0), 0.5)); | |
CreateLightGeom(rootTransForm, pointLightPositions[3], new osg::Sphere(osg::Vec3(0, 0, 0), 0.5)); | |
CreateLightGeom(rootTransForm, osg::Vec3(-0.2f, -1.0f, -0.3f) * 10, new osg::Box(osg::Vec3(0, 0, 0), 0.5)); | |
CreateLightGeom(rootTransForm, osg::Vec3(5, 5, 5), new osg::Cone(osg::Vec3(0, 0, 0), 0.5, 0.5)); | |
// directional light | |
stateset->addUniform(new osg::Uniform("dirLight.direction", osg::Vec3(-0.2f, -1.0f, -0.3f))); | |
stateset->addUniform(new osg::Uniform("dirLight.ambient", osg::Vec3(0.05f, 0.05f, 0.05f))); | |
stateset->addUniform(new osg::Uniform("dirLight.diffuse", osg::Vec3(0.4f, 0.4f, 0.4f))); | |
stateset->addUniform(new osg::Uniform("dirLight.specular", osg::Vec3(0.5f, 0.5f, 0.5f))); | |
// point light 1 | |
stateset->addUniform(new osg::Uniform("pointLights[0].position", pointLightPositions[0])); | |
stateset->addUniform(new osg::Uniform("pointLights[0].ambient", osg::Vec3(0.05f, 0.05f, 0.05f))); | |
stateset->addUniform(new osg::Uniform("pointLights[0].diffuse", osg::Vec3(0.8f, 0.8f, 0.8f))); | |
stateset->addUniform(new osg::Uniform("pointLights[0].specular", osg::Vec3(1.0f, 1.0f, 1.0f))); | |
stateset->addUniform(new osg::Uniform("pointLights[0].constant", 1.0f)); | |
stateset->addUniform(new osg::Uniform("pointLights[0].linear", 0.09)); | |
stateset->addUniform(new osg::Uniform("pointLights[0].quadratic", 0.032)); | |
// point light 2 | |
stateset->addUniform(new osg::Uniform("pointLights[1].position", pointLightPositions[1])); | |
stateset->addUniform(new osg::Uniform("pointLights[1].ambient", osg::Vec3(0.05f, 0.05f, 0.05f))); | |
stateset->addUniform(new osg::Uniform("pointLights[1].diffuse", osg::Vec3(0.8f, 0.8f, 0.8f))); | |
stateset->addUniform(new osg::Uniform("pointLights[1].specular", osg::Vec3(1.0f, 1.0f, 1.0f))); | |
stateset->addUniform(new osg::Uniform("pointLights[1].constant", 1.0f)); | |
stateset->addUniform(new osg::Uniform("pointLights[1].linear", 0.09)); | |
stateset->addUniform(new osg::Uniform("pointLights[1].quadratic", 0.032)); | |
// point light 3 | |
stateset->addUniform(new osg::Uniform("pointLights[2].position", pointLightPositions[2])); | |
stateset->addUniform(new osg::Uniform("pointLights[2].ambient", osg::Vec3(0.05f, 0.05f, 0.05f))); | |
stateset->addUniform(new osg::Uniform("pointLights[2].diffuse", osg::Vec3(0.8f, 0.8f, 0.8f))); | |
stateset->addUniform(new osg::Uniform("pointLights[2].specular", osg::Vec3(1.0f, 1.0f, 1.0f))); | |
stateset->addUniform(new osg::Uniform("pointLights[2].constant", 1.0f)); | |
stateset->addUniform(new osg::Uniform("pointLights[2].linear", 0.09)); | |
stateset->addUniform(new osg::Uniform("pointLights[2].quadratic", 0.032)); | |
// point light 4 | |
stateset->addUniform(new osg::Uniform("pointLights[3].position", pointLightPositions[3])); | |
stateset->addUniform(new osg::Uniform("pointLights[3].ambient", osg::Vec3(0.05f, 0.05f, 0.05f))); | |
stateset->addUniform(new osg::Uniform("pointLights[3].diffuse", osg::Vec3(0.8f, 0.8f, 0.8f))); | |
stateset->addUniform(new osg::Uniform("pointLights[3].specular", osg::Vec3(1.0f, 1.0f, 1.0f))); | |
stateset->addUniform(new osg::Uniform("pointLights[3].constant", 1.0f)); | |
stateset->addUniform(new osg::Uniform("pointLights[3].linear", 0.09)); | |
stateset->addUniform(new osg::Uniform("pointLights[3].quadratic", 0.032)); | |
// spotLight | |
osg::Vec3 spotLightPosition = osg::Vec3(5, 5,5); | |
osg::Vec3 spotLightdirection = osg::Vec3() - spotLightPosition; | |
spotLightdirection.normalize(); | |
stateset->addUniform(new osg::Uniform("spotLight.position", spotLightPosition)); | |
stateset->addUniform(new osg::Uniform("spotLight.direction", spotLightdirection)); | |
stateset->addUniform(new osg::Uniform("spotLight.ambient", osg::Vec3(0.0f, 0.0f, 0.0f))); | |
stateset->addUniform(new osg::Uniform("spotLight.diffuse", osg::Vec3(1.0f, 1.0f, 1.0f))); | |
stateset->addUniform(new osg::Uniform("spotLight.specular", osg::Vec3(1.0f, 1.0f, 1.0f))); | |
stateset->addUniform(new osg::Uniform("spotLight.constant", 1.0f)); | |
stateset->addUniform(new osg::Uniform("spotLight.linear", 0.09)); | |
stateset->addUniform(new osg::Uniform("spotLight.quadratic", 0.032)); | |
/*stateset->addUniform(new osg::Uniform("spotLight.cutOff", glm::cos(glm::radians(12.5f)))); | |
stateset->addUniform(new osg::Uniform("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)))); | |
*/ | |
stateset->addUniform(new osg::Uniform("spotLight.cutOff", 0.9762959977)); | |
stateset->addUniform(new osg::Uniform("spotLight.outerCutOff", 0.96592592665)); | |
} | |
void MultipleLights::CreateLightGeom(osg::MatrixTransform* root, osg::Vec3 lightVecPos, osg::Shape* shape) | |
{ | |
osg::ref_ptr<osg::MatrixTransform> lightObj = new osg::MatrixTransform; | |
osg::ref_ptr<osg::Geode> bxGeode = new osg::Geode; | |
bxGeode->addDrawable(new osg::ShapeDrawable(shape)); | |
lightObj->addChild(bxGeode); | |
lightObj->setMatrix(osg::Matrix::translate(lightVecPos)); | |
root->addChild(lightObj); | |
CreateShadersForLight(lightObj); | |
} | |
void MultipleLights::CreateShadersForLight(osg::Node * node) | |
{ | |
std::string vertSource = get_file_string("/lightshader.vert"); | |
std::string fragSource = get_file_string("/lightshader.frag"); | |
osg::ref_ptr<osg::Program> program = new osg::Program; | |
program->addShader(new osg::Shader(osg::Shader::VERTEX, | |
vertSource)); | |
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, | |
fragSource)); | |
osg::StateSet* stateset = node->getOrCreateStateSet(); // replace inst with your osg::node | |
stateset->setAttributeAndModes(program.get()); | |
} | |
std::string MultipleLights::get_file_string(std::string filePath) { | |
std::ifstream ifs(filePath); | |
return std::string((std::istreambuf_iterator<char>(ifs)), | |
(std::istreambuf_iterator<char>())); | |
} | |
//shaders for light objects | |
//lightshader.vert | |
#version 330 core | |
layout(location = 0) in vec3 aPos; | |
uniform mat4 osg_ModelViewProjectionMatrix; | |
uniform mat4 osg_ModelViewMatrix; | |
uniform mat4 osg_ViewMatrixInverse; | |
uniform mat3 osg_NormalMatrix; | |
uniform mat4 osg_ViewMatrix; | |
void main() | |
{ | |
gl_Position = osg_ModelViewProjectionMatrix * vec4(aPos, 1.0); | |
} | |
//lightshader.frag | |
#version 330 core | |
out vec4 FragColor; | |
void main() | |
{ | |
FragColor = vec4(1.0); | |
} | |
//main.cpp | |
int main() | |
{ | |
#ifdef _WIN32 | |
::SetProcessDPIAware(); // if Windows | |
#endif // _WIN32 | |
osgViewer::Viewer viewer; | |
osg::DisplaySettings::instance()->setNumMultiSamples(4); | |
osg::ref_ptr<osg::Group> root = new osg::Group(); | |
camera = viewer.getCamera(); | |
MultipleLights l(root.get(), camera); | |
l.CreateModel(); | |
viewer.setSceneData(root.get()); | |
viewer.setUpViewInWindow(100, 100, OSG_WIDTH, OSG_HEIGHT); | |
/* depth settings */ | |
osg::StateSet* state = root->getOrCreateStateSet(); | |
state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); | |
camera->setClearColor(osg::Vec4(0, 0, 0, 1)); | |
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
auto manip = new osgGA::TrackballManipulator(); | |
manip->setVerticalAxisFixed(true); | |
manip->setAllowThrow(false); | |
camera->getGraphicsContext()->getState()->setUseModelViewAndProjectionUniforms(true); | |
camera->getGraphicsContext()->getState()->setUseVertexAttributeAliasing(true); | |
viewer.setCameraManipulator(manip); | |
osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator(viewer.getCamera()->getStateSet()); | |
viewer.addEventHandler(statesetManipulator.get()); | |
viewer.realize(); | |
while (!viewer.done()) { | |
viewer.frame(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment