Reworked material

This commit is contained in:
Robert 2021-01-29 17:28:48 +01:00
parent 5c51de37a6
commit bf751c6c69
12 changed files with 251 additions and 32 deletions

View file

@ -12,12 +12,12 @@
#pragma warning(disable : 4251)
#include <memory>
#include <iostream>
#include <stdexcept>
#include <string>
#include <glad/glad.h>
#ifdef OGLU_WIN32
#ifdef OGLU_BUILD_DLL
#define OGLU_API __declspec(dllexport)
@ -28,4 +28,30 @@
#define OGLU_API
#endif //OGLU_WIN32
namespace oglu
{
class NullBuffer : public std::streambuf
{
public:
int overflow(int c) { return c; }
};
class NullStream : public std::ostream
{
public:
NullStream() : std::ostream(&buf) {}
private:
NullBuffer buf;
};
extern OGLU_API NullStream cnull;
}
#ifndef NDEBUG
#define OGLU_ERROR_STREAM std::cerr
#else
#define OGLU_ERROR_STREAM oglu::cnull
#endif
#endif

View file

@ -1,3 +1,10 @@
/*****************************************************************//**
* @file ambient.hpp
* @brief Anything related to ambient/environmental lighting
*
* @author Lauchmelder
* @date January 2021
*********************************************************************/
#ifndef AMBIENT_HPP
#define AMBIENT_HPP
@ -6,16 +13,46 @@
namespace oglu
{
/**
* @brief A class holding information needed for ambient lighting.
*/
class OGLU_API AmbientLight
{
public:
/**
* @brief Create default ambient light.
*
* By default, this creates a white light at full intensity
*/
AmbientLight();
/**
* @brief Create a custom ambient light.
*
* @param r Red component
* @param r Green component
* @param r Blue component
* @param intensity Intensity of the lighting
*/
AmbientLight(GLfloat r, GLfloat g, GLfloat b, GLfloat intensity);
/**
* @brief Create a custom ambient light.
*
* @param color Color of the lighting
* @param intensity Intensity of the lighting
*/
AmbientLight(const Color& color, GLfloat intensity);
/**
* @brief Copy another ambient light.
*
* @param other The light to copy from
*/
AmbientLight(const AmbientLight& other);
GLfloat intensity;
Color color;
GLfloat intensity; ///< Intensity of the ambient light
Color color; ///< Color of the ambient light
};
}

View file

@ -1,3 +1,10 @@
/*****************************************************************//**
* @file point.hpp
* @brief Anything related to point light sources
*
* @author Lauchmelder
* @date January 2021
*********************************************************************/
#ifndef POINT_HPP
#define POINT_HPP
@ -9,27 +16,74 @@ namespace oglu
{
class Transformable;
/**
* @brief A class containing things related to point lighting.
*/
class OGLU_API PointLight
{
public:
/**
* @brief Create a default point light.
*
* By default the diffusion and specular components are white and
* the light is positioned at the world origin
*/
PointLight();
/**
* @brief Create a new point light.
*
* @param position Position of the light
* @param diffusionColor Color of the diffusion component
* @param specularColor Color of the specular component
*/
PointLight(const glm::vec3& position, const Color& diffusionColor = Color::White, const Color& specularColor = Color::White);
/**
* @brief Copy from another point light.
*
* @param other The point light to copy from
*/
PointLight(const PointLight& other);
~PointLight();
/**
* @brief Link the lights position to a Transformable.
*
* It is possible to link the positions of a Transformable and
* a PointLight. This means that these two objects will always
* have the same position, until they are unlinked. Deleting a
* Transformable before unlinking any linked PointLight causes
* undefined behaviour.
*
* @param link The Transformable to link to
*/
void LinkPositionToTransformable(Transformable& link);
/**
* @brief Unlink a Transformable.
*
* This breaks the link between the two objects.
*/
void UnlinkPositionFromTransformable();
/**
* Get the lights position.
*
* @returns A pointer to the lights position
*/
float* GetPositionPointer();
public:
Color diffusionColor;
Color specularColor;
// TODO: Does this split make sense? I'll keep it for now
Color diffusionColor; ///< Diffusion color of the light
Color specularColor; ///< Specular color of the light
private:
glm::vec3* position;
bool isLinked;
glm::vec3* position; ///< Position of the light
bool isLinked; ///< Wether the position is linked to an object or not
};
}

86
include/material.hpp Normal file
View file

@ -0,0 +1,86 @@
/*****************************************************************//**
* @file material.hpp
* @brief Anything related to materials
*
* @author Lauchmelder
* @date January 2021
*********************************************************************/
#ifndef MATERIAL_HPP
#define MATERIAL_HPP
#include <map>
#include <any>
#include <iostream>
#include <core.hpp>
namespace oglu
{
/**
* @brief A structure representing an object's material.
*
* This object is dynamic and can contain any data that you want
*/
class OGLU_API Material
{
public:
/**
* @brief Adds a new material property.
*
* @param name The name of the property
* @param value The value of the property
*/
void AddProperty(const std::string& name, const std::any& value);
/**
* @brief Remove the given property from the material.
*/
void RemoveProperty(const std::string& name);
/**
* @brief Get a property from the material.
*
* Should the material property not be present in the material this function
* will attempt to add it, using the default constructor of the supplied class.
* You should not rely on this failsafe working properly all the time.
*
* @tparam T The type of the stores property
* @param name The name of the property
* @returns A pointer to the stored property
*/
template<typename T> T* GetProperty(const std::string& name, std::ostream& errorStream = OGLU_ERROR_STREAM)
{
std::map<std::string, std::any>::iterator it = properties.find(name);
if (it == properties.end())
{
errorStream << "Failed to locate material property \"" << name << "\" in " << static_cast<const void*>(this) << ". Trying to construct default property of type \"" << typeid(T).name() << "\" and add it to the material.\n";
it = properties.insert(std::make_pair(name, T())).first;
}
return std::any_cast<T>(&(it->second));
}
/**
* @brief Get a property from the material.
*
* Should the material property not be present in the material this function
* will attempt to add it, using the default constructor of the supplied class.
* You should not rely on this failsafe working properly all the time.
*
* @tparam T The type of the stores property
* @param name The name of the property
* @returns The value of the stored property
*/
template<typename T> inline T GetPropertyValue(const std::string& name, std::ostream& errorStream = OGLU_ERROR_STREAM)
{
return *(GetProperty<T>(name, errorStream));
}
private:
std::map<std::string, std::any> properties;
};
typedef std::shared_ptr<Material> SharedMaterial; ///< A material that can safely be shared between objects
}
#endif

View file

@ -15,18 +15,7 @@
namespace oglu
{
/**
* @brief A structure representing an object's material.
*/
class OGLU_API Material
{
public:
Color ambient = Color::White;
Color diffuse = Color::White;
Color specular = Color::White;
float shininess = 32.0f;
};
class Material;
typedef std::shared_ptr<Material> SharedMaterial;
/**

View file

@ -13,6 +13,7 @@
#include <shader.hpp>
#include <texture.hpp>
#include <object.hpp>
#include <material.hpp>
#include <camera.hpp>
#include <lighting/ambient.hpp>