adding Light class in model and the shader in render utils

This commit is contained in:
Sam Gateau 2015-01-27 15:45:10 -08:00
parent ae3233b119
commit db427cdf5e
3 changed files with 306 additions and 0 deletions

View file

@ -0,0 +1,94 @@
//
// Light.cpp
// libraries/model/src/model
//
// Created by Sam Gateau on 1/26/2014.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "Light.h"
using namespace model;
Light::Light() :
_flags(0),
_schemaBuffer(),
_transform() {
// only if created from nothing shall we create the Buffer to store the properties
Schema schema;
_schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Buffer::Byte*) &schema));
}
Light::Light(const Light& light) :
_flags(light._flags),
_schemaBuffer(light._schemaBuffer),
_transform(light._transform) {
}
Light& Light::operator= (const Light& light) {
_flags = (light._flags);
_schemaBuffer = (light._schemaBuffer);
_transform = (light._transform);
return (*this);
}
Light::~Light() {
}
void Light::setPosition(const Vec3& position) {
_transform.setTranslation(position);
_transform.getMatrix(editSchema()._transform);
}
void Light::setOrientation(const glm::quat& orientation) {
_transform.setRotation(orientation);
_transform.getMatrix(editSchema()._transform);
}
void Light::setDirection(const Vec3& direction) {
glm::mat3 rotation(
Vec3(1.0f, 0.0f, 0.0f),
Vec3(0.0f, 1.0f, 0.0f),
-direction);
setOrientation(glm::quat(rotation));
}
const Vec3& Light::getDirection() const {
return Vec3(_transform.transform(Vec4(0.0f, 0.0f, 1.0f, 0.0f)));
}
void Light::setColor(const Color& color) {
editSchema()._color = color;
}
void Light::setIntensity(float intensity) {
editSchema()._intensity = intensity;
}
void Light::setAttenuationRadius(float radius) {
if (radius <= 0.f) {
radius = 1.0f;
}
editSchema()._attenuation = Vec4(1.0f, 2.0f/radius, 1.0f/(radius*radius), radius);
}
void Light::setSpotCone(float angle) {
if (angle <= 0.f) {
angle = 0.0f;
}
editSchema()._spot.x = cos(angle);
editSchema()._spot.z = angle;
}
void Light::setSpotConeExponent(float exponent) {
if (exponent <= 0.f) {
exponent = 1.0f;
}
editSchema()._spot.y = exponent;
editSchema()._spot.w = exponent;
}

124
libraries/model/src/model/Light.h Executable file
View file

@ -0,0 +1,124 @@
//
// Light.h
// libraries/model/src/model
//
// Created by Sam Gateau on 12/10/2014.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_model_Light_h
#define hifi_model_Light_h
#include <bitset>
#include <map>
#include <glm/glm.hpp>
#include "Transform.h"
#include "gpu/Resource.h"
#include "gpu/Texture.h"
namespace model {
typedef gpu::BufferView UniformBufferView;
typedef gpu::TextureView TextureView;
typedef glm::vec3 Vec3;
typedef glm::vec4 Vec4;
typedef glm::quat Quat;
class Light {
public:
enum Type {
SUN = 0,
POINT,
SPOT,
NUM_TYPES,
};
typedef Vec3 Color;
enum FlagBit {
COLOR_BIT = 0,
INTENSITY_BIT,
RANGE_BIT,
SPOT_BIT,
TRANSFORM_BIT,
NUM_FLAGS,
};
typedef std::bitset<NUM_FLAGS> Flags;
Light();
Light(const Light& light);
Light& operator= (const Light& light);
virtual ~Light();
void setType(Type type) { editSchema()._control.x = float(type); }
Type getType() const { return Type((int) getSchema()._control.x); }
void setPosition(const Vec3& position);
const Vec3& getPosition() const { return _transform.getTranslation(); }
void setDirection(const Vec3& direction);
const Vec3& getDirection() const;
void setOrientation(const Quat& orientation);
const glm::quat& getOrientation() const { return _transform.getRotation(); }
const Color& getColor() const { return getSchema()._color; }
void setColor(const Color& color);
float getIntensity() const { return getSchema()._intensity; }
void setIntensity(float intensity);
bool isRanged() const { return (getType() == POINT) || (getType() == SPOT ); }
void setAttenuationRadius(float radius);
float getAttenuationRadius() const { return getSchema()._attenuation.w; }
// Spot properties
bool isSpot() const { return getType() == SPOT; }
void setSpotCone(float angle);
void setSpotConeExponent(float exponent);
float getSpotConeAngle() const { return getSchema()._spot.z; }
float getSpotConeExponent() const { return getSchema()._spot.w; }
// Schema to access the attribute values of the light
class Schema {
public:
glm::mat4 _transform;
Color _color;
float _intensity;
Vec4 _attenuation;
Vec4 _spot;
Vec4 _shadow;
Vec4 _control;
Schema() :
_transform(),
_color(1.0f),
_intensity(1.0f),
_attenuation(1.0f, 2.0f, 1.0f, 1.0f),
_spot(0.0f, 0.0f, 0.0f, 0.0f),
_control(0.0f)
{}
};
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
protected:
Flags _flags;
UniformBufferView _schemaBuffer;
Transform _transform;
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
};
typedef QSharedPointer< Light > LightPointer;
};
#endif

View file

@ -0,0 +1,88 @@
<!
// Light.slh
// fragment shader
//
// Created by Sam Gateau on 1/25/14.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
!>
<@if not LIGHT_SLH@>
<@def LIGHT_SLH@>
struct Light {
mat4 _transform;
vec4 _color;
vec4 _attenuation;
vec4 _spot;
vec4 _shadow;
vec4 _control;
};
vec3 getLightPosition(Light l) { return l._transform[3].xyz; }
vec3 getLightDirection(Light l) { return -l._transform[2].xyz; } // direction is -Z axis
vec3 getLightColor(Light l) { return l._color.rgb; }
float getLightIntensity(Light l) { return l._color.w; }
float evalLightAttenuation(Light l, float r) {
return clamp(1.0/(l._attenuation.x + l._attenuation.y * r + l._attenuation.z * r * r), 0.0, 1.0);
}
float evalLightSpotAttenuation(Light l, float cosA) {
if (cosA > l._spot.x) {
return 0.0;
}
return clamp(pow(cosA / l._spot.x, l._spot.w), 0.0, 1.0);
}
<@if GLPROFILE == PC_GL@>
uniform lightBuffer {
Light light;
};
Light getLight() {
return light;
}
<@elif GLPROFILE == MAC_GL@>
uniform vec4 lightBuffer[9];
Light getLight() {
Light light;
light._transform[0] = lightBuffer[0];
light._transform[1] = lightBuffer[1];
light._transform[2] = lightBuffer[2];
light._transform[3] = lightBuffer[3];
light._color = lightBuffer[4];
light._range = lightBuffer[5];
light._spot = lightBuffer[6];
light._shadow = lightBuffer[7];
light._control = lightBuffer[8];
return light;
}
<@else@>
uniform vec4 lightBuffer[9];
Light getLight() {
Light light;
light._transform[0] = lightBuffer[0];
light._transform[1] = lightBuffer[1];
light._transform[2] = lightBuffer[2];
light._transform[3] = lightBuffer[3];
light._color = lightBuffer[4];
light._range = lightBuffer[5];
light._spot = lightBuffer[6];
light._shadow = lightBuffer[7];
light._control = lightBuffer[8];
return light;
}
<@endif@>
<@endif@>