Translated to standard c++ after big clean of adhesive from non-standard branch

This commit is contained in:
Edward R. Gonzalez 2020-02-21 08:34:43 -05:00
parent c46f44a8d8
commit da17f52c9d
27 changed files with 353763 additions and 0 deletions

408
Actions.hpp Normal file
View File

@ -0,0 +1,408 @@
/*
Title : Actions
Author: Edward R. Gonzalez
Description:
This was a little experiment of mine to mess with action binding...
Allows for non-member functions to be binded to an action, implements a functioning queue as well.
TODO: Possibly add support for member functions. Have it so that deduction of delegate typef is not required to add to queue properly (right now it does, see input procedure for example);
*/
#pragma once
#include "Cpp_Alias.hpp"
namespace Actions
{
struct IAction
{
virtual void DoAction() = NULL;
};
template<typename FunctionType, typename... ActionParams>
struct AAction : IAction
{
public:
using ActionType = function< FunctionType >;
AAction(const ActionType& _actionToAssign, const ActionParams&... _params) :
action(_actionToAssign),
params(_params... ),
done (false )
{};
bool Used()
{
return done;
}
bool IsSame(const ActionType& _action, const ActionParams&... _paramsForAction)
{
tuple<ActionParams...> paramsToCheck(_paramsForAction...);
if (params == paramsToCheck && SameAction(_action))
{
return true;
}
else
{
return false;
}
}
bool SameAction(const ActionType& _action)
{
if (action.target<FunctionType*>() == _action.target<FunctionType*>())
{
return true;
}
else
{
return false;
}
}
void ReInitalize(const ActionParams&... _params)
{
params = tuple<ActionParams...>(_params...);
done = false;
}
protected:
virtual void DoAction_Implementation(const ActionParams&... _params) { action(_params...); }
template<size_t... TuplePackIndex> // TuplePackSequence<TuplePackIndex...>
void ExpandTuple_CallDoActionImplementaiton(const tuple<ActionParams...>& _paramsToExpand, std::index_sequence <TuplePackIndex...>)
{
// ExpandTuplePack<TuplePackIndex>
DoAction_Implementation(std::get<TuplePackIndex>(_paramsToExpand)...);
}
tuple<ActionParams...> params;
const ActionType& action;
bool done;
public: // IAction
virtual void DoAction() override
{
ExpandTuple_CallDoActionImplementaiton
(
params,
// MakeTuplePackSequence <ActionParams...>()
std::index_sequence_for<ActionParams...>()
);
done = true;
};
};
// TODO: This doesn't work yet...
template<typename ObjectType, typename FunctionType, typename... ActionParams>
class AAction_ObjectBound : public AAction<FunctionType, ActionParams...>
{
public:
using Base = AAction<FunctionType, ActionParams...>;
using ActionType = function<FunctionType>;
AAction_ObjectBound(ObjectType& _objectRef, const ActionType& _actionToAssign, const ActionParams&... _params) :
AAction<FunctionType, ActionParams...>::action(_actionToAssign),
AAction<FunctionType, ActionParams...>::params(_params... ),
object (_objectRef )
{}
bool IsSame(const ObjectType& _object, const ActionType& _action, const ActionParams&... _params)
{
if (SameObject(_object) && SameAction(_action))
{
tuple<ActionParams...> paramsToCheck(_params...);
if (AAction<FunctionType, ActionParams...>::params == paramsToCheck)
{
return true;
}
else
{
return false;
}
}
}
bool SameObject(const ObjectType& _object)
{
if (Address(object) == Address(_object))
{
return true;
}
else
{
return false;
}
}
protected:
virtual void DoAction_Implementation(const ActionParams&... _params) override
{
(&object).*AAction<FunctionType, ActionParams...>::action(_params...);
}
template<size_t... TuplePackIndex> // TuplePackSequence<TuplePackIndex...>
void ExpandTuple_CallDoActionImplementaiton(const tuple<ActionParams...>& _paramsToExpand, std::index_sequence <TuplePackIndex...>)
{
// ExpandTuplePack<TuplePackIndex>
DoAction_Implementation(std::get<TuplePackIndex>(_paramsToExpand)...);
}
ObjectType& object;
public: // IAction
virtual void DoAction() override
{
ExpandTuple_CallDoActionImplementaiton
(
AAction<FunctionType, ActionParams...>::params,
// MakeTuplePackSequence <ActionParams...>()
std::index_sequence_for<ActionParams...>()
);
AAction<FunctionType, ActionParams...>::params::done = true;
};
};
struct ActionPool_Dynamic
{
template<typename Type>
using AllocationsOf = std::forward_list<Type>;
using Managed_AAction = shared_ptr < IAction >;
using Managed_AActions = AllocationsOf < Managed_AAction >;
using AActions_Registry = std::map <type_index , Managed_AActions>;
public:
template<typename Entry>
bool Contains(Entry& _entry)
{
return _entry != aActions_Available.end() ? true : false;
}
Managed_AActions& Make_Managed_Actions()
{
mAAaction_Allocations.push_front(make_shared<Managed_AActions>());
return *(mAAaction_Allocations.front().get());
}
template<typename FunctionType, typename... ActionParams>
IAction* Request_AAction(const function< FunctionType>& _actionToQueue, const ActionParams&... _paramsForAction)
{
using ActionType = AAction < FunctionType, ActionParams...>;
type_index AActionID = typeid(ActionType);
auto possibleEntry = aActions_Available.find(AActionID);
if (Contains(possibleEntry))
{
using Element = decltype(possibleEntry->second.begin());
for (Element possibleAction = possibleEntry->second.begin(); possibleAction != possibleEntry->second.end(); possibleAction++)
{
ActionType* castedEntry = static_cast<ActionType*>(possibleAction->get());
if (castedEntry->IsSame(_actionToQueue, _paramsForAction...))
{
return castedEntry;
}
else if (castedEntry->Used() && castedEntry->SameAction(_actionToQueue))
{
castedEntry->ReInitalize(_paramsForAction...);
return castedEntry;
}
}
shared_ptr< IAction> newAction = make_shared< AAction<FunctionType, ActionParams...>>(_actionToQueue, _paramsForAction...);
IAction* returnRef = newAction.get ();
aActions_Available.at(AActionID).push_front(newAction);
return returnRef;
}
shared_ptr< IAction> newAction = make_shared< AAction<FunctionType, ActionParams...>>(_actionToQueue, _paramsForAction...);
IAction* returnRef = newAction.get ();
aActions_Available.insert(make_pair(AActionID, Make_Managed_Actions()));
aActions_Available.at(AActionID).push_front(newAction);
return returnRef;
}
template<typename ObjectType, typename FunctionType, typename... ActionParams>
IAction* Request_AAction(const ObjectType& _objectRef, const function< FunctionType>& _actionToQueue, const ActionParams&... _paramsForAction)
{
using ActionType = AAction_ObjectBound<ObjectType, FunctionType, ActionParams...>;
type_index AActionID = typeid(ActionType);
auto possibleEntry = aActions_Available.find(AActionID);
if (Contains(possibleEntry))
{
using Element = decltype(possibleEntry->second.begin());
for (Element possibleAction = possibleEntry->second.begin(); possibleAction != possibleEntry->second.end(); possibleAction++)
{
ActionType* castedEntry = static_cast<ActionType*>(possibleAction->get());
if (castedEntry->IsSame(_actionToQueue, _paramsForAction...))
{
return castedEntry;
}
else if (castedEntry->Used() && castedEntry->SameAction(_actionToQueue))
{
castedEntry->ReInitalize(_paramsForAction...);
return castedEntry;
}
}
shared_ptr< IAction> newAction = make_shared< AAction<FunctionType, ActionParams...>>(_actionToQueue, _paramsForAction...);
IAction* returnRef = newAction.get ();
aActions_Available.at(AActionID).push_front(newAction);
return returnRef;
}
shared_ptr< IAction> newAction = make_shared< AAction<FunctionType, ActionParams...>>(_actionToQueue, _paramsForAction...);
IAction* returnRef = newAction.get ();
aActions_Available.insert(std::make_pair(AActionID, Make_Managed_Actions()));
aActions_Available.at(AActionID).push_front(newAction);
return returnRef;
}
private:
AllocationsOf< shared_ptr<Managed_AActions> > mAAaction_Allocations;
AActions_Registry aActions_Available;
};
ActionPool_Dynamic DefaultActionPool_Dynamic;
struct ActionQueue
{
using QueueType = std::deque< IAction*>;
public:
template<typename FunctionType, typename... ActionParams>
void AddToQueue(const function< FunctionType>& _actionToQueue, const ActionParams&... _paramsForAction)
{
using GeneratedActionType = AAction<FunctionType, ActionParams...>;
IAction* actionRequested = DefaultActionPool_Dynamic.Request_AAction(_actionToQueue, _paramsForAction...);
if (HasAction())
{
bool found = false;
using Element = decltype(actionQueue.begin());
for (Element element = actionQueue.begin(); element != actionQueue.end(); element++)
{
if ( (*element) == actionRequested )
{
found = true;
}
}
if (not found)
{
actionQueue.push_front(actionRequested);
}
}
else
{
actionQueue.push_front(actionRequested);
}
}
template<typename ObjectType, typename FunctionType, typename... ActionParams>
void AddToQueue(const ObjectType& _objectRef, const function< FunctionType>& _actionToQueue, const ActionParams&... _paramsForAction)
{
using GeneratedActionType = AAction_ObjectBound<ObjectType, FunctionType, ActionParams...>;
IAction* actionRequested = DefaultActionPool_Dynamic.Request_AAction(_objectRef, _actionToQueue, _paramsForAction...);
if (HasAction())
{
bool found = false;
using Element = decltype(actionQueue.begin());
for (Element element = actionQueue.begin(); element != actionQueue.end(); element++)
{
if ((*element) == actionRequested)
{
found = true;
}
}
if (not found)
{
actionQueue.push_front(actionRequested);
}
}
else
{
actionQueue.push_front(actionRequested);
}
}
void DoNextAction()
{
if (actionQueue.size() > 0)
{
actionQueue.back()->DoAction();
actionQueue.pop_back();
}
}
bool HasAction()
{
return actionQueue.size() > 0;
}
private:
QueueType actionQueue;
};
}

76
Cpp_Alias.hpp Normal file
View File

@ -0,0 +1,76 @@
/*
Title: C++ Aliasing Library
Author: Edward R. Gonzalez
Date:
Description:
This is a segment of the C++ Assist Library I use for other code.
This merely removes the need to use operators I don't like and wraps them in easier to manage typedefs, functions or macros
*/
#pragma once
#include <algorithm >
#include <chrono >
#include <cstdarg >
#include <cstddef >
#include <exception >
#include <forward_list>
#include <fstream >
#include <functional >
#include <iostream >
#include <cmath >
#include <map >
#include <memory >
#include <queue >
#include <sstream >
#include <stdexcept >
#include <string >
#include <vector >
#include <thread >
#include <tuple >
#include <typeindex >
#include <utility >
// Aliases
// Fundamental
using uInt64 = unsigned long long int;
// Pointers
using std::shared_ptr;
using std::unique_ptr;
using std::make_shared;
using std::make_unique;
using std::make_pair;
// Delegating
using std::function;
// Strings
using std::cout;
using std::endl;
using std::ifstream ;
using std::ios ;
using std::string ;
using std::stringstream;
using std::size_t;
using std::thread;
using std::tuple;
using std::type_index;

20
DGL/DGL.hpp Normal file
View File

@ -0,0 +1,20 @@
/*
Title : Ducktaped GL: Library Head
Author: Edward R. Gonzalez
Description:
This is the header that should be included into the application using this library.
Includes the rest of the library.
*/
#pragma once
// DGL
#include "DGL_Enum.hpp"
#include "DGL_Types.hpp"
#include "DGL_Buffers.hpp"
#include "DGL_Shader.hpp"
#include "DGL_Space.hpp"
#include "DGL_Model.hpp"
#include "DGL_Entity.hpp"

139
DGL/DGL_Buffers.hpp Normal file
View File

@ -0,0 +1,139 @@
/*
Title : Ducktaped GL: Buffers
Author: Edward R. Gonzalez
Description:
Contains wrappers to buffer related functionality.
*/
#pragma once
// GLEW
#include <glew.h>
// DGL
#include "DGL_Enum.hpp"
#include "DGL_Types.hpp"
// Non-Standard C++
#include "Cpp_Alias.hpp"
namespace DGL
{
void BindBuffer(EBufferTarget _targetType, ID<VertexBuffer> _buffer)
{
glBindBuffer(GLenum(_targetType), _buffer);
return;
}
void BindVertexArray(gUInt _referenceToTrackArray)
{
glBindVertexArray(_referenceToTrackArray);
return;
}
template<typename TypeOfData>
void BufferData(const TypeOfData& _data, EBufferTarget _targetType, EBufferUsage _usageType)
{
glBufferData(GLenum(_targetType), sizeof(TypeOfData), &_data, GLenum(_usageType));
return;
}
template<typename Type>
void BufferData(const Type& _data, gSize _sizeOfData, EBufferTarget _targetType, EBufferUsage _usageType)
{
glBufferData(GLenum(_targetType), _sizeOfData, &_data, GLenum(_usageType));
}
template<typename... Type, typename = EFrameBuffer>
void ClearBuffer(Type... _buffersToClear)
{
glClear( (gBitfield(_buffersToClear) | ...) );
return;
}
void DisableVertexAttributeArray(gInt _vertexAttributeArrayIndex)
{
glDisableVertexAttribArray(_vertexAttributeArrayIndex);
}
void DrawArrays(EPrimitives _primitive, gInt _startingIndex, gInt _numToRender)
{
glDrawArrays(GLenum(_primitive), _startingIndex, _numToRender); // Starting from vertex 0; 3 vertices total -> 1 triangle.
}
void DrawElements(EPrimitives _primitive, gSize _numElements, EDataType _dataType, const DataPtr _offfsetAddressFromFirstIndex)
{
glDrawElements(GLenum(_primitive), _numElements, GLenum(_dataType), _offfsetAddressFromFirstIndex);
}
void EnableVertexAttributeArray(gInt _vertexAttributeArrayIndex)
{
glEnableVertexAttribArray(_vertexAttributeArrayIndex);
}
template<typename VertType>
void FormatVertexAttributes
(
gUInt _attributeIndex ,
EDataType _vertexComponenetType ,
void* const _firstVertexComponentLocation,
gInt _numberOfVertexComponents ,
gBoolean _shouldNormalize
)
{
glVertexAttribPointer
(
_attributeIndex ,
_numberOfVertexComponents ,
GLenum(_vertexComponenetType),
_shouldNormalize ,
sizeof(VertType ),
_firstVertexComponentLocation
);
}
void GenerateBuffers(gUInt& _bufferReferencer, gSize _numberOfBuffersToReserve)
{
glGenBuffers(_numberOfBuffersToReserve, &_bufferReferencer);
return;
}
void GenerateVertexBuffers(gUInt& __referenceRetainerToBuffer, gSize _numOfObjectsToReserveFor)
{
glGenVertexArrays(_numOfObjectsToReserveFor, &__referenceRetainerToBuffer);
return;
}
void GetBufferParameterIV(EBufferTarget _target, EBufferParam _param, gInt& _dataStore)
{
glGetBufferParameteriv(GLenum(_target), GLenum(_param), &_dataStore);
return;
}
// Used to get an offset from a specified location.
DataPtr Offset(uInt64 _offsetAmount)
{
return DataPtr(_offsetAmount);
}
void UnbindVertexArray()
{
BindVertexArray(0);
}
// Provides an zero offset pointer specifier.
constexpr void* ZeroOffset()
{
return 0;
}
}

292
DGL/DGL_Entity.hpp Normal file
View File

@ -0,0 +1,292 @@
/*
Title : Ducktaped GL: Entity
Author: Edward R. Gonzalez
Description:
Contains implementation for useful entity classes that brings together much of the OpenGL functionality to be used as individual objects.
*/
#pragma once
// DGL
#include "DGL_Types.hpp"
#include "DGL_Model.hpp"
#include "DGL_Shader.hpp"
#include "DGL_Utilities.hpp"
// Non-Standard C++
#include "Cpp_Alias.hpp"
namespace DGL
{
namespace Colors
{
LinearColor Coral (1.0f , 0.5f , 0.31f, 1.0f);
LinearColor Grey (0.60f, 0.60f, 0.60f, 1.0f);
LinearColor WarmSphia(0.54f, 0.52f, 0.5f , 1.0f);
LinearColor White (1.0f , 1.0f , 1.0f , 1.0f);
}
class Light_Basic
{
public:
Light_Basic() :
color (Colors::White.Vector()),
position (Vector3 (0.0f) ),
scale (Vector3 (0.2f) ),
transform (CoordSpace(1.0f) ),
translationRadius(4.0f )
{}
VecColor GetColor()
{
return color;
}
Vector3 GetPosition()
{
return position;
}
void Load()
{
GenerateVertexBuffers(modelVAO, 1);
GenerateBuffers (modelVBO, 1);
GenerateBuffers (modelEBO, 1);
BindVertexArray(modelVAO);
BindBuffer(EBufferTarget::VertexAttributes, modelVBO);
BufferData<CubeVerts>(DefaultCube, EBufferTarget::VertexAttributes, EBufferUsage::StaticDraw);
BindBuffer(EBufferTarget::VertexIndices, modelEBO);
BufferData<CubeElements>(DefaultCubeElements, EBufferTarget::VertexIndices, EBufferUsage::StaticDraw);
FormatVertexAttributes<CubeVerts::Vertex3>(0, EDataType::Float, ZeroOffset(), CubeVerts::Vertex3::ValueCount(), false);
UnbindVertexArray();
return;
}
void Update(double _delta)
{
static gFloat valueLoop = 0.0f;
transform = CoordSpace(1.0f);
position.x = translationRadius * sin(valueLoop);
position.z = translationRadius * cos(valueLoop);
transform = Translate(transform, position);
transform = Scale (transform, scale );
valueLoop += 0.31879f * _delta;
return;
}
void Render(const CoordSpace& _projection, const CoordSpace& _viewport)
{
auto screenspaceTransform = _projection * _viewport * transform;
Basic_LightShader::Use(screenspaceTransform);
BindVertexArray(modelVAO);
BindBuffer(EBufferTarget::VertexIndices, modelEBO);
gInt SizeRef; GetBufferParameterIV(EBufferTarget::VertexIndices, DGL::EBufferParam::Size, SizeRef); SizeRef /= sizeof(unsigned int);
DrawElements(EPrimitives::Triangles, SizeRef, EDataType::UnsignedInt, ZeroOffset());
//UnbindVertexArray();
Basic_LightShader::Stop();
return;
}
private:
VecColor color ;
Vector3 position ;
Vector3 scale ;
CoordSpace transform ;
gFloat translationRadius;
// Hardcoded Model
struct CubeVerts
{
struct Vertex3
{
gFloat x, y, z;
static constexpr gSize ValueCount() { return 3; }
};
Vertex3
f1, f2, f3, f4, // Front
b1, b2, b3, b4; // Back
}
DefaultCube =
{
// Front
{-1.0f, -1.0f, 1.0f},
{ 1.0f, -1.0f, 1.0f},
{ 1.0f, 1.0f, 1.0f},
{-1.0f, 1.0f, 1.0f},
// Back
{-1.0f, -1.0f, -1.0f},
{ 1.0f, -1.0f, -1.0f},
{ 1.0f, 1.0f, -1.0f},
{-1.0f, 1.0f, -1.0f}
};
struct CubeElements
{
struct Edge3
{
struct TriIndex
{
gInt a, b, c;
};
TriIndex a, b;
};
Edge3 front, right, back, left, bottom, top;
}
DefaultCubeElements =
{
// Front
{ { 0, 1, 2 }, { 2, 3, 0 } },
// Right
{ { 1, 5, 6 }, { 6, 2, 1 } },
// Back
{ { 7, 6, 5 }, { 5, 4, 7 } },
// Left
{ { 4, 0, 3 }, { 3, 7, 4 } },
// Bottom
{ { 4, 5, 1 }, { 1, 0, 4 } },
// Top
{ { 3, 2, 6 }, { 6, 7, 3 } }
};
ID<VertexArray > modelVAO;
ID<VertexBuffer > modelVBO;
ID<ElementBuffer> modelEBO;
};
class Entity_Basic
{
public:
Entity_Basic() :
position (Vector3(0.0f) ),
scale (Vector3(1.0f) ),
model (NULL ),
transform(CoordSpace(1.0f))
{};
Entity_Basic(Model& _model, Material_Phong& _material) :
position (Vector3(0.0f) ),
scale (Vector3(1.0f) ),
model (&_model ),
transform(CoordSpace(1.0f)),
material (_material )
//type (_type )
{};
void SetModel(Model& _model)
{
model = &_model;
return;
}
void SetScale(gFloat _scaleBy)
{
scale = Vector3(_scaleBy);
transform = CoordSpace(1.0f);
transform = DGL::Translate(transform, position);
transform = DGL::Scale(transform, scale);
return;
}
void SetPosition(const Vector3& _position)
{
position = _position;
transform = CoordSpace(1.0f);
transform = DGL::Translate(transform, position);
transform = DGL::Scale(transform, scale);
return;
}
void Update()
{
}
void Render(const CoordSpace& _projection, const CoordSpace& _viewport, const Vector3& _lightPosition, const VecColor& _lightColor)
{
PhongShader::Use(_projection, _viewport, transform, _lightPosition,_lightColor, material);
(*model).Render();
PhongShader::Stop();
return;
}
Entity_Basic& operator= (const Entity_Basic& _entity)
{
position = _entity.position ;
scale = _entity.scale ;
model = _entity.model ;
transform = _entity.transform;
material = _entity.material ;
return *this;
}
private:
//EEntityType type;
Vector3 position ;
Vector3 scale ;
Model* model ;
CoordSpace transform ;
Material_Phong material ;
};
}

326
DGL/DGL_Enum.hpp Normal file
View File

@ -0,0 +1,326 @@
/*
Title : Ducktaped GL: Enums
Author: Edward R. Gonzalez
Description:
Wraps the currently used enumerated macros used for various GFLW/OpenGL functions into enum classes.
*/
#pragma once
// GLEW
#include <glew.h>
// GLFW
#include <glfw3.h>
namespace DGL
{
enum class EAxis
{
X, Y, Z
};
enum class EBool
{
True = GL_TRUE ,
False = GL_FALSE
};
enum class EBufferParam
{
AccessPolicy = GL_BUFFER_ACCESS,
IsMapped = GL_BUFFER_MAPPED,
Size = GL_BUFFER_SIZE ,
UsagePattern = GL_BUFFER_USAGE
};
enum class EBufferTarget
{
VertexAttributes = GL_ARRAY_BUFFER ,
AtomicCounter = GL_ATOMIC_COUNTER_BUFFER ,
CopySource = GL_COPY_READ_BUFFER ,
CopyDestination = GL_COPY_WRITE_BUFFER ,
IndirectComputeDispatchCommands = GL_DISPATCH_INDIRECT_BUFFER ,
IndirectCommandArguments = GL_DRAW_INDIRECT_BUFFER ,
VertexIndices = GL_ELEMENT_ARRAY_BUFFER ,
PixelReadTarget = GL_PIXEL_PACK_BUFFER ,
TextureDataSource = GL_PIXEL_UNPACK_BUFFER ,
QueryResult = GL_QUERY_BUFFER ,
ReadWriteShaderStorage = GL_SHADER_STORAGE_BUFFER ,
TextureData = GL_TEXTURE_BUFFER ,
TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER,
UniformBlockStorage = GL_UNIFORM_BUFFER
};
enum class EBufferUsage
{
DynamicCopy = GL_DYNAMIC_COPY,
DynamicDraw = GL_DYNAMIC_DRAW,
DynamicRead = GL_DYNAMIC_READ,
StreamCopy = GL_STREAM_COPY,
StreamDraw = GL_STREAM_DRAW,
StreamRead = GL_STREAM_READ,
StaticCopy = GL_STATIC_COPY,
StaticDraw = GL_STATIC_DRAW,
StaticRead = GL_STATIC_READ
};
enum class ECompareMode
{
RefToTexture = GL_COMPARE_REF_TO_TEXTURE,
None = GL_NONE
};
enum class ECursorMode
{
Normal = GLFW_CURSOR_NORMAL ,
Hidden = GLFW_CURSOR_HIDDEN ,
Disable = GLFW_CURSOR_DISABLED
};
enum class EDataType
{
Byte = GL_BYTE ,
UnsignedByte = GL_UNSIGNED_BYTE ,
Short = GL_SHORT ,
UnsignedShort = GL_UNSIGNED_SHORT,
Int = GL_INT ,
UnsignedInt = GL_UNSIGNED_INT ,
Fixed = GL_FIXED ,
Half = GL_HALF_FLOAT ,
Float = GL_FLOAT ,
Double = GL_DOUBLE
};
enum class EDirection
{
Up ,
Down ,
Left ,
Right ,
Forward ,
Backward
};
enum class EFace
{
Front = GL_FRONT ,
Back = GL_BACK ,
Front_and_Back = GL_FRONT_AND_BACK
};
enum class EFrameBuffer
{
Accumulation = GL_ACCUM_BUFFER_BIT ,
Color = GL_COLOR_BUFFER_BIT ,
Depth = GL_DEPTH_BUFFER_BIT ,
Stencil = GL_STENCIL_BUFFER_BIT
};
enum class EKeyCodes
{
F1 = GLFW_KEY_F1 ,
F2 = GLFW_KEY_F2 ,
F3 = GLFW_KEY_F3 ,
A = GLFW_KEY_A ,
D = GLFW_KEY_D ,
E = GLFW_KEY_E ,
H = GLFW_KEY_H ,
I = GLFW_KEY_I ,
J = GLFW_KEY_J ,
K = GLFW_KEY_K ,
L = GLFW_KEY_L ,
M = GLFW_KEY_M ,
Q = GLFW_KEY_Q ,
S = GLFW_KEY_S ,
W = GLFW_KEY_W ,
LeftShift = GLFW_KEY_LEFT_SHIFT,
Escape = GLFW_KEY_ESCAPE ,
UpArrow = GLFW_KEY_UP ,
DnArrow = GLFW_KEY_DOWN
};
enum class EKeyState
{
Pressed = GLFW_PRESS ,
Released = GLFW_RELEASE
};
enum class ELODBias
{
Max = GL_MAX_TEXTURE_LOD_BIAS
};
enum class EMaxFilter
{
Nearest = GL_NEAREST,
Linear = GL_LINEAR
};
enum class EMinFilter
{
Nearest = GL_NEAREST ,
Linear = GL_LINEAR ,
NearestToNearest = GL_NEAREST_MIPMAP_NEAREST,
LinearToNearest = GL_NEAREST_MIPMAP_LINEAR ,
NearestToLinear = GL_NEAREST_MIPMAP_LINEAR ,
LinearToLinear = GL_LINEAR_MIPMAP_LINEAR
};
enum class EMouseMode
{
Cursor = GLFW_CURSOR ,
RawMouse = GLFW_RAW_MOUSE_MOTION ,
StickyKeys = GLFW_STICKY_KEYS ,
StickMouse = GLFW_STICKY_MOUSE_BUTTONS,
LockKey = GLFW_LOCK_KEY_MODS ,
};
enum class ERenderMode
{
Point = GL_POINT,
Line = GL_LINE ,
Fill = GL_FILL
};
enum class ERotationAxis
{
Pitch, Yaw, Roll
};
enum class EPrimitives
{
Points = GL_POINTS,
Lines = GL_LINES ,
LineStrip = GL_LINE_STRIP,
LineLoop = GL_LINE_LOOP ,
Triangles = GL_TRIANGLES ,
TriangleStrip = GL_TRIANGLE_STRIP,
TriangleFan = GL_TRIANGLE_FAN ,
Quads = GL_QUADS ,
QuadsStrip = GL_QUAD_STRIP,
Patches = GL_PATCHES,
Polygon = GL_POLYGON
};
enum class EShaderInfo
{
Type = GL_SHADER_TYPE ,
DeleteStatus = GL_DELETE_STATUS ,
CompileStatus = GL_COMPILE_STATUS ,
InfoLogLength = GL_INFO_LOG_LENGTH ,
ShaderSourceLength = GL_SHADER_SOURCE_LENGTH
};
enum class EShaderProgramInfo
{
DeleteStatus = GL_DELETE_STATUS ,
LinkStatus = GL_LINK_STATUS ,
ValidateStatus = GL_VALIDATE_STATUS ,
InfoLogLength = GL_INFO_LOG_LENGTH ,
AttachedShaders = GL_ATTACHED_SHADERS ,
ActiveAttributes = GL_ACTIVE_ATTRIBUTES ,
ActiveAttributesMaxLength = GL_ACTIVE_ATTRIBUTE_MAX_LENGTH ,
ActiveUniforms = GL_ACTIVE_UNIFORMS ,
TransformFeedbackActive = GL_TRANSFORM_FEEDBACK_BUFFER_MODE ,
TransformFeedbackVaryings = GL_TRANSFORM_FEEDBACK_VARYING ,
TransformFeedbackVaryingsMax = GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH,
ShaderVerticiesMax = GL_GEOMETRY_VERTICES_OUT ,
GeometryInputType = GL_GEOMETRY_INPUT_TYPE ,
GeometryOutputType = GL_GEOMETRY_OUTPUT_TYPE
};
enum class EShaderType
{
Vertex = GL_VERTEX_SHADER ,
Fragment = GL_FRAGMENT_SHADER
};
enum class EStencilMode
{
DepthComponent = GL_DEPTH_COMPONENT,
StencilIndex = GL_STENCIL_INDEX
};
enum class ESWIZZLE
{
Red = GL_RED ,
Green = GL_GREEN,
Blue = GL_BLUE ,
Alpha = GL_ALPHA,
Zero = GL_ZERO ,
One = GL_ONE
};
enum class ETexCompareFuncs
{
LessOrEqual = GL_LEQUAL ,
GreaterOrEqual = GL_GEQUAL ,
Less = GL_LESS ,
Greater = GL_GREATER ,
Equal = GL_EQUAL ,
NotEqual = GL_NOTEQUAL,
Always = GL_ALWAYS ,
Never = GL_NEVER
};
enum class ETextureMode
{
DepthStencil = GL_DEPTH_STENCIL_TEXTURE_MODE,
MipmapLowest = GL_TEXTURE_BASE_LEVEL ,
ComparisonOperator = GL_TEXTURE_COMPARE_FUNC ,
Comparision = GL_TEXTURE_COMPARE_MODE ,
LevelOfDetailBias = GL_TEXTURE_LOD_BIAS ,
MinimizingFilter = GL_TEXTURE_MIN_FILTER ,
MagnificationFilter = GL_TEXTURE_MAG_FILTER ,
MinimumLOD = GL_TEXTURE_MIN_LOD ,
MaximumLOD = GL_TEXTURE_MAX_LOD ,
MipmapMax = GL_TEXTURE_MAX_LEVEL ,
Swizzle_R = GL_TEXTURE_SWIZZLE_R ,
Swizzle_G = GL_TEXTURE_SWIZZLE_G ,
Swizzle_B = GL_TEXTURE_SWIZZLE_B ,
Swizzle_A = GL_TEXTURE_SWIZZLE_A ,
Swizzle_RGBA = GL_TEXTURE_SWIZZLE_RGBA ,
Wrap_S = GL_TEXTURE_WRAP_S ,
Wrap_T = GL_TEXTURE_WRAP_T ,
Wrap_R = GL_TEXTURE_WRAP_R
};
enum class ETextureType
{
_1D = GL_TEXTURE_1D,
_2D = GL_TEXTURE_2D,
_3D = GL_TEXTURE_3D,
Rectangle = GL_TEXTURE_RECTANGLE,
Buffer = GL_TEXTURE_BUFFER ,
CubeMap = GL_TEXTURE_CUBE_MAP ,
CubeMapArray = GL_TEXTURE_CUBE_MAP_ARRAY,
Array1D = GL_TEXTURE_1D_ARRAY,
Array2D = GL_TEXTURE_2D_ARRAY,
Multisample = GL_TEXTURE_2D_MULTISAMPLE ,
Multisample2D = GL_TEXTURE_2D_MULTISAMPLE_ARRAY
};
enum class EWrap
{
ClampToEdge = GL_CLAMP_TO_EDGE ,
ClampToBorder = GL_CLAMP_TO_BORDER ,
MirroredRepeat = GL_MIRRORED_REPEAT ,
Repeat = GL_REPEAT ,
MirrorClampToEdge = GL_MIRROR_CLAMP_TO_EDGE
};
}

467
DGL/DGL_Model.hpp Normal file
View File

@ -0,0 +1,467 @@
/*
Title : Ducktaped GL: Model
Author: Edward R. Gonzalez
Description:
*/
#pragma once
// DGL
#include "DGL_Buffers.hpp"
#include "DGL_Types.hpp"
#include "DGL_Space.hpp"
// Non-Standard C++
#include "Cpp_Alias.hpp"
namespace DGL
{
struct VertexGenerator
{
using ComponentList = std::vector< gFloat>;
public:
void AddComponent(gFloat _float)
{
comp.push_back(_float);
}
// TODO: De-hard-code this generator to do any vector size.
Vector2 GetVector2()
{
return Vector2(comp.at(0), comp.at(1));
}
Vector3 GetVector3()
{
return Vector3(comp.at(0), comp.at(1), comp.at(2));
}
void Normalize()
{
using std::pow ;
using std::sqrt;
using Element = ComponentList::iterator;
gFloat magnitude = 0.0f;
for (Element element = comp.begin(); element != comp.end(); element++)
{
magnitude += pow(*element, 2.0f);
}
magnitude = sqrt(magnitude);
for (Element element = comp.begin(); element != comp.end(); element++)
{
*element /= magnitude;
}
}
private:
ComponentList comp;
};
struct Face
{
Vec3Int Vertexes, Normals;
};
using FaceList = std::vector<Face>;
struct FaceGenerator
{
using ComponentList = std::vector< gUInt>;
ComponentList vertIndexes, uvIndexes, normals;
void AddVertexIndex(gUInt _index)
{
vertIndexes.push_back(_index);
}
void AddUVIndex(gUInt _index)
{
uvIndexes.push_back(_index);
}
void AddNormalIndex(gUInt _index)
{
normals.push_back(_index);
}
Face GetFace()
{
Face generated;// = { {0,0,0}, {0,0,0}, {0,0,0} };
for (int index = 0; index < 3; index++)
{
generated.Vertexes[index] = vertIndexes[index];
if (index < 2)
{
if (uvIndexes.size() > 0)
{
//generated.UVs[index] = uvIndexes[index];
}
}
if (normals.size() > 0)
{
generated.Normals[index] = normals[index];
}
}
if (uvIndexes.size() == 0)
{
//generated.UVs = { 0, 0 };
}
return generated;
}
};
// TODO: Add support for textures...
class Model
{
private:
// Not the most efficient method to do normals, but works.
void generateNormals()
{
normals.resize(verticies.size(), Vector3(0.0f));
for (int faceIndex = 0; faceIndex < faces.size(); faceIndex++)
{
int vertexIndex1 = faces[faceIndex].Vertexes[0],
vertexIndex2 = faces[faceIndex].Vertexes[1],
vertexIndex3 = faces[faceIndex].Vertexes[2];
Vector3 edge1 = verticies[vertexIndex2] - verticies[vertexIndex1],
edge2 = verticies[vertexIndex3] - verticies[vertexIndex1],
normal = GetDirection(GetCrossNormal(edge1, edge2));
faces[faceIndex].Normals[0] = vertexIndex1;
faces[faceIndex].Normals[1] = vertexIndex2;
faces[faceIndex].Normals[2] = vertexIndex3;
normals[vertexIndex1] = normal;
normals[vertexIndex2] = normal;
normals[vertexIndex3] = normal;
}
}
public:
Model(const string& _filePath) :
loaded (false ),
vertexArrayID (0 ),
vertexBufferID (0 ),
normalBuffferID(0 ),
textureBufferID(0 ),
elementBufferID(0 ),
filePath (_filePath ),
verticies (VertexList()),
normals (VertexList()),
textureUVs (UVList ()),
faces (FaceList ())
{}
// Hardcoded to only do the verticies and normals for now...
void Buffer()
{
GenerateVertexBuffers(vertexArrayID , 1);
GenerateBuffers (vertexBufferID , 1);
GenerateBuffers (normalBuffferID, 1);
GenerateBuffers (elementBufferID, 1);
if (normals.size() == 0)
{
generateNormals();
}
BindVertexArray(vertexArrayID);
// Vertex Position Buffering
BindBuffer(EBufferTarget::VertexAttributes, vertexBufferID);
BufferData(verticies[0], gSize(verticies.size() * sizeof(Vector3)), EBufferTarget::VertexAttributes, EBufferUsage::StaticDraw);
FormatVertexAttributes<Vector3>(0, EDataType::Float, ZeroOffset(), 3, false);
EnableVertexAttributeArray(0);
// Normal Buffering
if (normals.size() != 0)
{
BindBuffer(EBufferTarget::VertexAttributes, normalBuffferID);
BufferData(normals[0], gSize(normals.size() * sizeof(Vector3)), EBufferTarget::VertexAttributes, EBufferUsage::StaticDraw);
FormatVertexAttributes<Vector3>(1, EDataType::Float, ZeroOffset(), 3, false);
EnableVertexAttributeArray(1);
}
// Texture buffering
// TODO: Fix this.
if (textureUVs.size() != 0)
{
//glBindTexture(TBO, GL_TEXTURE_2D);
//BufferData(Address(TextureMap[0]), TextureMap.size() * sizeof(Vector2), EBufferTarget::TextureData, EBufferUsage::StaticDraw);
//FormatVertexAttributes<Vector2>(2, EDataType::Float, ZeroOffset(), 2, EBool::False);
//EnableVertexAttributeArray(2);
}
BindBuffer(EBufferTarget::VertexIndices, elementBufferID);
BufferData(faces[0], gSize(faces.size() * sizeof(Face)), EBufferTarget::VertexIndices, EBufferUsage::StaticDraw);
UnbindVertexArray(); // Unbind vertex array.
}
void Load()
{
using std::get ;
using std::getline ;
using std::ifstream ;
using std::ios ;
using std::stringstream;
using std::ws ;
ifstream fileBuffer; fileBuffer.open(filePath);
auto processVertex = [&](stringstream& _vertexStream)
{
VertexGenerator vertex; gFloat componentValue;
while (not _vertexStream.eof())
{
_vertexStream >> componentValue >> ws;
vertex.AddComponent(componentValue);
}
verticies.push_back(vertex.GetVector3());
};
auto processNormals = [&](stringstream& _normalStream)
{
VertexGenerator normal; gFloat componentValue;
while (not _normalStream.eof())
{
_normalStream >> componentValue >> ws;
normal.AddComponent(componentValue);
}
normal.Normalize();
normals.push_back(normal.GetVector3());
};
auto processTexture = [&](stringstream& _normalStream)
{
VertexGenerator texture; gFloat componentValue;
while (not _normalStream.eof())
{
_normalStream >> componentValue >> ws;
texture.AddComponent(componentValue);
}
textureUVs.push_back(texture.GetVector2());
};
auto processFace = [&](stringstream& _faceStream)
{
FaceGenerator faceMade; gUInt vertexIndex, textureIndex, normalIndex;
while (not _faceStream.eof())
{
_faceStream >> vertexIndex >> ws;
faceMade.AddVertexIndex(vertexIndex - 1);
indicies.push_back(vertexIndex - 1);
if (_faceStream.peek() == '/')
{
_faceStream.get();
if (_faceStream.peek() == '/')
{
_faceStream.get();
_faceStream >> normalIndex >> ws;
faceMade.AddNormalIndex(normalIndex -1);
indicies.push_back(normalIndex - 1);
}
else
{
_faceStream >> textureIndex >> ws;
faceMade.AddUVIndex(textureIndex - 1);
if (_faceStream.peek() == '/')
{
_faceStream.get();
_faceStream >> normalIndex >> ws;
faceMade.AddNormalIndex(normalIndex - 1);
indicies.push_back(normalIndex - 1);
}
}
}
}
faces.push_back(faceMade.GetFace());
};
if (fileBuffer.is_open())
{
stringstream stringBuffer;
stringBuffer << fileBuffer.rdbuf();
string line;
while (not stringBuffer.eof())
{
getline(stringBuffer, line);
stringstream lineStream(line);
string lineSig;
lineStream >> lineSig >> ws;
if (lineSig == "v")
{
processVertex(lineStream);
}
else if (lineSig == "vn")
{
processNormals(lineStream);
}
else if (lineSig == "vt")
{
processTexture(lineStream);
}
else if (lineSig == "f")
{
processFace(lineStream);
}
}
fileBuffer.close();
Buffer();
loaded = true;
return;
}
else
{
throw std::runtime_error("Could not open file to load model.");
}
}
bool Ready()
{
return loaded;
}
void Render()
{
BindVertexArray(vertexArrayID);
gInt SizeRef; GetBufferParameterIV(EBufferTarget::VertexIndices, EBufferParam::Size, SizeRef); SizeRef /= sizeof(gUInt);
DrawElements(EPrimitives::Triangles, SizeRef, EDataType::UnsignedInt, ZeroOffset());
UnbindVertexArray();
}
Model& operator= (const Model& _model)
{
vertexArrayID = _model.vertexArrayID ;
vertexBufferID = _model.vertexBufferID ;
normalBuffferID = _model.normalBuffferID;
textureBufferID = _model.textureBufferID;
elementBufferID = _model.elementBufferID;
filePath = _model.filePath;
verticies = _model.verticies ;
normals = _model.normals ;
textureUVs = _model.textureUVs;
faces = _model.faces ;
indicies = _model.indicies ;
return *this;
}
private:
// Components
bool loaded;
ID<VertexArray > vertexArrayID ;
ID<VertexBuffer > vertexBufferID ;
ID<NormalBuffer > normalBuffferID;
ID<TextureBuffer> textureBufferID;
ID<ElementBuffer> elementBufferID;
string filePath;
VertexList verticies ;
VertexList normals ;
UVList textureUVs;
FaceList faces ;
VIndexList indicies ;
};
};

435
DGL/DGL_Shader.hpp Normal file
View File

@ -0,0 +1,435 @@
#pragma once
//DGL
#include "DGL_Enum.hpp"
#include "DGL_Types.hpp"
#include "DGL_Buffers.hpp"
#include "DGL_Space.hpp"
// Non-Standard C++
#include "Cpp_Alias.hpp"
namespace DGL
{
// Forward Declarations
void GetShaderInfo (ID<Shader > _shader , gSize _logLength , gSize* _infoLengthRef , char* _infoLogRef );
void QueryShader (ID<Shader > _shaderToQuery , EShaderInfo _shaderInfoDesired, gInt* const _requestedInfoObject );
void MakeShader (ID<Shader >& _shaderIDHolder , EShaderType _typeOfShader , uInt64 _numberOfStringElements , const char** const _sourceCode, gInt* const _lengthsOfStrings);
void MakeShaderProgram(ID<ShaderProgram>& _shaderProgramIDHolder, ID<Shader> _vertexShader , ID<Shader> _fragShader );
// Functions
GLint ActiveUniforms(ID<Shader> _shaderToQueryForUniforms)
{
GLint uniforms;
glGetProgramiv(_shaderToQueryForUniforms, GL_ACTIVE_UNIFORMS, &uniforms);
for (int uniformIndex = 0; uniformIndex < uniforms; uniformIndex++)
{
int name_len = -1, num = -1;
GLenum type = GL_ZERO;
char name[100];
glGetActiveUniform(_shaderToQueryForUniforms, GLuint(uniformIndex), sizeof(name) - 1, &name_len, &num, &type, name);
name[name_len] = 0;
}
return uniforms;
}
void AttachShader(ID<ShaderProgram> _shaderProgram, ID<Shader> _shaderToAttach)
{
glAttachShader(_shaderProgram, _shaderToAttach);
return;
}
void BindShaderSource(ID<Shader> _shader, gSize _numberOfStringElements, const char** _sourceCode, gInt* const _lengthsOfStrings)
{
glShaderSource(_shader, _numberOfStringElements, _sourceCode, _lengthsOfStrings); //Address(_sourceCode), Address(_lengthsOfStrings));
return;
}
void CompileShader(ID<Shader> _shaderToCompile)
{
glCompileShader(_shaderToCompile);
gInt Result = gInt(EBool::False);
gSize InfoLogLength;
QueryShader(_shaderToCompile, EShaderInfo::CompileStatus, &Result);
if (!Result)
{
QueryShader(_shaderToCompile, EShaderInfo::InfoLogLength, &InfoLogLength);
if (InfoLogLength > 0)
{
std::vector<char> ErrorMessage(InfoLogLength + 1);
GetShaderInfo(_shaderToCompile, InfoLogLength, nullptr, &ErrorMessage.at(0));
throw std::runtime_error(&ErrorMessage.at(0));
}
else
{
throw std::runtime_error("Shader compilation failed and did not get a proper info log.");
}
}
return;
}
ID<Shader> CreateShader(EShaderType _typeOfShader)
{
return glCreateShader(GLenum(_typeOfShader));
}
ID<ShaderProgram> CreateShaderProgram()
{
return glCreateProgram();
}
void DeleteShader(ID<Shader> _shaderToDelete)
{
glDeleteShader(_shaderToDelete);
return;
}
void DetachShader(ID<ShaderProgram> _shaderProgram, ID<Shader> _shaderToDetach)
{
glDetachShader(_shaderProgram, _shaderToDetach);
return;
}
void GetShaderInfo(ID<Shader> _shader, gSize _logLength, gSize* const _infoLengthRef, char* _infoLogRef)
{
glGetShaderInfoLog(_shader, _logLength, _infoLengthRef, _infoLogRef);
return;
}
void GetShaderProgramInfo(ID<ShaderProgram> _shaderProgram, gSize _logLength, gSize* const _infoLengthRef, char* _infoLogRef)
{
glGetProgramInfoLog(_shaderProgram, _logLength, _infoLengthRef, _infoLogRef);
return;
}
ID<Matrix> GetUniformVariable(const ID<ShaderProgram> _programID, const char* _nameOfVariable)
{
return glGetUniformLocation(_programID, _nameOfVariable);
}
void LinkProgramShader(ID<ShaderProgram> _shaderProgramToLink)
{
glLinkProgram(_shaderProgramToLink);
return;
}
void QueryShader(ID<Shader> _shaderToQuery, EShaderInfo _shaderInfoDesired, gInt* const _requestedInfoObject)
{
glGetShaderiv(_shaderToQuery, GLenum(_shaderInfoDesired), _requestedInfoObject);
return;
}
void QueryShaderProgram(ID<ShaderProgram> _shaderToQuery, EShaderProgramInfo _shaderProgramInfoDesired, gInt* _requestedInfoObject)
{
glGetProgramiv(_shaderToQuery, GLenum(_shaderProgramInfoDesired), _requestedInfoObject);
return;
}
ID<ShaderProgram> LoadShaders(const char* const _vertexShaderFilePath, const char* const _fragmentShaderFilePath)
{
using std::vector;
string vertexShaderCode ;
string fragmentShaderCode ;
ifstream vertexShaderFileStream ;
ifstream fragmentShaderFileStream;
vertexShaderFileStream .open(_vertexShaderFilePath);
fragmentShaderFileStream.open(_fragmentShaderFilePath);
if (vertexShaderFileStream.is_open() and fragmentShaderFileStream.is_open())
{
stringstream vertSourceStrStream;
stringstream fragSourceStrStream;
vertSourceStrStream << vertexShaderFileStream .rdbuf();
fragSourceStrStream << fragmentShaderFileStream.rdbuf();
vertexShaderFileStream .close();
fragmentShaderFileStream.close();
vertexShaderCode = vertSourceStrStream.str();
fragmentShaderCode = fragSourceStrStream.str();
}
else
{
throw std::runtime_error("Impossible to open% s.Are you in the right directory ? Don't forget to read the FAQ !");
}
const char* vertexSourcePtr = vertexShaderCode .c_str();
const char* fragmentSourcePtr = fragmentShaderCode.c_str();
cout << "Compiling shader: " << _vertexShaderFilePath << endl;
ID<Shader> vertexShader = CreateShader(EShaderType::Vertex);
BindShaderSource(vertexShader, 1, &vertexSourcePtr, NULL);
CompileShader (vertexShader );
cout << "Compiling shader: " << _fragmentShaderFilePath << endl;
ID<Shader> fragmentShader = CreateShader(EShaderType::Fragment);
BindShaderSource(fragmentShader, 1, &fragmentSourcePtr, NULL);
CompileShader (fragmentShader );
cout << "Making Shader Program and Linking..." << endl;
ID<ShaderProgram> generatedProgram;
MakeShaderProgram(generatedProgram, vertexShader, fragmentShader);
DeleteShader(vertexShader );
DeleteShader(fragmentShader);
return generatedProgram;
}
void MakeShader
(
ID<Shader>& _shaderIDHolder ,
EShaderType _typeOfShader ,
gSize _numberOfStringElements,
const char** const _sourceCode ,
gInt* const _lengthsOfStrings
)
{
_shaderIDHolder = CreateShader(_typeOfShader);
BindShaderSource(_shaderIDHolder, _numberOfStringElements, _sourceCode, _lengthsOfStrings);
CompileShader(_shaderIDHolder);
return;
}
void MakeShaderProgram(ID<ShaderProgram>& _shaderProgramIDHolder, ID<Shader> _vertexShader, ID<Shader> _fragShader)
{
_shaderProgramIDHolder = CreateShaderProgram();
AttachShader(_shaderProgramIDHolder, _vertexShader);
AttachShader(_shaderProgramIDHolder, _fragShader );
LinkProgramShader(_shaderProgramIDHolder);
gInt Result = false;
QueryShaderProgram(_shaderProgramIDHolder, EShaderProgramInfo::LinkStatus, &Result);
if (!Result)
{
gInt infoLogLength;
QueryShaderProgram(_shaderProgramIDHolder, EShaderProgramInfo::InfoLogLength, &infoLogLength);
if (infoLogLength > 0)
{
std::vector<char> ErrorMessage(infoLogLength + 1);
GetShaderProgramInfo(_shaderProgramIDHolder, infoLogLength, NULL, &ErrorMessage.at(0));
cout << (char*)&ErrorMessage[0] << endl;
throw std::runtime_error(&ErrorMessage.at(0));
}
else
{
throw std::runtime_error("ShaderProgram compilation failed and did not get a proper info log.");
}
}
DetachShader(_shaderProgramIDHolder, _vertexShader);
DetachShader(_shaderProgramIDHolder, _fragShader );
return;
}
// MVA: MatrixVariableArray
void SetUniformVariable_MVA(ID<Matrix> _matrixID, gSize _numMatricies, gBoolean _shouldTransposeValues, const gFloat& _dataPtr)
{
glUniformMatrix4fv(_matrixID, _numMatricies, _shouldTransposeValues, &_dataPtr);
return;
}
void SetUniformVariable_Vector3(ID<Vec3> _ID, gSize _num, const gFloat& _dataPtr)
{
glUniform3fv(_ID, _num, &_dataPtr);
return;
}
void SetUniformVariable_Float(ID<gFloat> _ID, gFloat _data)
{
glUniform1f(_ID, _data);
return;
}
void UseProgramShader(ID<ShaderProgram> _shaderProgramToUse)
{
glUseProgram(_shaderProgramToUse);
return;
}
namespace Basic_LightShader
{
ID<ShaderProgram> Shader;
ID<CoordSpace> ScreenSpaceVarID;
void LoadShader()
{
Shader = LoadShaders("./Shaders/BasicLight.vert", "./Shaders/BasicLight.frag");
ScreenSpaceVarID = GetUniformVariable(Shader, "ScreenSpaceTransform");
return;
}
void Use(const CoordSpace& _lampTransform)
{
UseProgramShader(Shader);
SetUniformVariable_MVA(ScreenSpaceVarID, 1, false, _lampTransform[0][0]);
EnableVertexAttributeArray(0);
EnableVertexAttributeArray(1);
return;
}
void Stop()
{
DisableVertexAttributeArray(0);
DisableVertexAttributeArray(1);
return;
}
}
struct Material_Phong
{
VecColor Color ;
gFloat Ambience;
gFloat Diffuse ;
gFloat Specular;
};
namespace PhongShader
{
ID<ShaderProgram> ShaderID;
ID<CoordSpace> ModelSpaceID, InverseModelSpaceID, ViewportID, ProjectionID;
ID<Vec3> LightPositionID, ObjectColorID, LightColorID;
ID<gFloat> AmbientStrengthID, DiffuseStrengthID, SpecularStrengthID;
gInt VertexIndexID, NormalIndexID;
void LoadShader()
{
ShaderID = LoadShaders("./Shaders/PhongShader.vert", "./Shaders/PhongShader.frag");
InverseModelSpaceID = GetUniformVariable(ShaderID, "InverseModelSpace");
ModelSpaceID = GetUniformVariable(ShaderID, "ModelSpace" );
ProjectionID = GetUniformVariable(ShaderID, "Projection" );
ViewportID = GetUniformVariable(ShaderID, "Viewport" );
ObjectColorID = GetUniformVariable(ShaderID, "ObjectColor" );
LightColorID = GetUniformVariable(ShaderID, "LightColor" );
LightPositionID = GetUniformVariable(ShaderID, "LightPosition");
AmbientStrengthID = GetUniformVariable(ShaderID, "AmbientStrength" );
DiffuseStrengthID = GetUniformVariable(ShaderID, "DiffuseStrength" );
SpecularStrengthID = GetUniformVariable(ShaderID, "SpecularStrength");
return;
}
void Use
(
const CoordSpace& _projection ,
const CoordSpace& _viewport ,
const CoordSpace& _objectTransform,
const Vector3& _lightPosition ,
const Vector3& _lightColor ,
const Material_Phong& _material
)
{
CoordSpace inverseTransform = Inverse(_viewport * _objectTransform);
UseProgramShader(ShaderID);
SetUniformVariable_MVA(InverseModelSpaceID, 1, false, inverseTransform[0][0]);
SetUniformVariable_MVA(ModelSpaceID , 1, false, _objectTransform[0][0]);
SetUniformVariable_MVA(ProjectionID , 1, false, _projection [0][0]);
SetUniformVariable_MVA(ViewportID , 1, false, _viewport [0][0]);
SetUniformVariable_Vector3(LightPositionID, 1, _lightPosition[0]);
SetUniformVariable_Vector3(ObjectColorID , 1, _material.Color[0]);
SetUniformVariable_Vector3(LightColorID , 1, _lightColor [0]);
SetUniformVariable_Float(AmbientStrengthID , _material.Ambience);
SetUniformVariable_Float(DiffuseStrengthID , _material.Diffuse );
SetUniformVariable_Float(SpecularStrengthID, _material.Specular);
EnableVertexAttributeArray(0);
EnableVertexAttributeArray(1);
return;
}
void Stop()
{
DisableVertexAttributeArray(1);
DisableVertexAttributeArray(0);
return;
}
}
void LoadDefaultShaders()
{
Basic_LightShader::LoadShader();
PhongShader ::LoadShader();
return;
}
}

283
DGL/DGL_Space.hpp Normal file
View File

@ -0,0 +1,283 @@
#pragma once
// GLM
#include <glm/glm.hpp >
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp >
// DGL
#include "DGL_Types.hpp"
// Non-Standard C++
#include "Cpp_Alias.hpp"
namespace DGL
{
// Function
gFloat Cosine(gFloat _angleInRadians)
{
return glm::cos(_angleInRadians);
}
gFloat Sine(gFloat _angleInRadians)
{
return glm::sin(_angleInRadians);
}
template<typename Type>
Matrix4x4 CreateLookAtView(const Generic::Vector3<Type>& _viewPosition, const Generic::Vector3<Type>& _lookAtPosition, const Generic::Vector3<Type>& _upDirection)
{
return glm::lookAt(_viewPosition, _lookAtPosition, _upDirection);
}
Matrix4x4 CreateOrthographic(gFloat _leftScreenCoord, gFloat _rightScreenCoord, gFloat _bottomScreenCoord, gFloat _topScreenCoord, gFloat _nearPlane, gFloat _farPlane)
{
return glm::ortho(_leftScreenCoord, _rightScreenCoord, _bottomScreenCoord, _topScreenCoord, _nearPlane, _farPlane);
}
template<typename FloatType>
Matrix4x4 CreatePerspective(FloatType _fieldOfView, FloatType _aspectRatio, FloatType _nearPlane, FloatType _farPlane)
{
return glm::perspective(_fieldOfView, _aspectRatio, _nearPlane, _farPlane);
}
Vector3 GetCrossNormal(const Vector3& _subj, const Vector3& _ref)
{
return glm::cross(_subj, _ref);
}
Vector3 GetDirection(const Vector3& _vectorSpecified)
{
return glm::normalize(_vectorSpecified);
}
Matrix4x4 Inverse(const Matrix4x4& _matrix)
{
return glm::inverse(_matrix);
}
Matrix4x4 Rotate(const Matrix4x4& _matrix, gFloat _rotationAngleAmount, const Vector3& _axis)
{
return glm::rotate(_matrix, _rotationAngleAmount, _axis);
}
Matrix4x4 Scale(const Matrix4x4& _matrix, const Vector3& _scaleBy)
{
return glm::scale(_matrix, _scaleBy);
}
template<typename Type>
Type ToRadians(Type _degrees)
{
return glm::radians(_degrees);
}
Matrix4x4 Translate(const Matrix4x4& _matrix, const Vector3& _translationAmount)
{
return glm::translate(_matrix, _translationAmount);
}
struct ClippingPlanes
{
gFloat Near, Far;
ClippingPlanes(gFloat _near, gFloat _far) : Near(_near), Far(_far) {};
};
namespace DefaultSpace
{
gFloat
AspectRatio = 16.0f / 10.0f,
FieldOfView = 90.0f ,
NearClippingPlane = 0.01f ,
FarClippingPlane = 1000.0f ;
Vector3 CameraPosition( 0, 0, 2),
LookAtPosition( 0, 0, 0),
RightDirection( 1, 0, 0),
UpDirection ( 0, 1, 0),
FrontDirection( 0, 0, 1) ;
gInt ScreenWidth = 1280, ScreenHeight = 800, ScreenCenterWidth = ScreenWidth / 2, ScreenCenterHeight = ScreenHeight / 2;
}
struct Camera
{
gFloat AspectRatio, FieldOfView, Yaw, Pitch, Roll;
ClippingPlanes ClipSpace;
CoordSpace Viewport;
Projection Orthographic, Perspective;
Vector3 Position, LookAtPosition, UpDirection, FrontDirection, RightDirection;
Camera
(
gFloat _aspectRatio ,
gFloat _fieldOfView ,
const ClippingPlanes& _clippingPlanes,
const Vector3& _position ,
const Vector3& _lookAtPosition,
const Vector3& _upDirection ,
const Vector3& _frontDirection
) :
AspectRatio (_aspectRatio ),
FieldOfView (_fieldOfView ),
ClipSpace (_clippingPlanes),
Position (_position ),
LookAtPosition(_lookAtPosition),
UpDirection (_upDirection ),
FrontDirection(_frontDirection)
{
Yaw = -90.0f; Pitch = 0.0f; Roll = 0.0f;
UpdateCamera();
Orthographic = CreateOrthographic(0.0f, gFloat(DefaultSpace::ScreenWidth), 0.0f, gFloat(DefaultSpace::ScreenHeight), ClipSpace.Near, ClipSpace.Far);
Perspective = CreatePerspective<gFloat>(ToRadians(FieldOfView), AspectRatio, ClipSpace.Near, ClipSpace.Far);
}
void Move(EDirection _direction, gFloat _translationAmount, gFloat _deltaTime)
{
switch (_direction)
{
case EDirection::Up:
{
Position -= UpDirection * _translationAmount * _deltaTime;
break;
}
case EDirection::Down:
{
Position += UpDirection * _translationAmount * _deltaTime;
break;
}
case EDirection::Left:
{
Position -= GetDirection(GetCrossNormal(FrontDirection, UpDirection)) * _translationAmount * _deltaTime;
break;
}
case EDirection::Right:
{
Position += GetDirection(GetCrossNormal(FrontDirection, UpDirection)) * _translationAmount * _deltaTime;
break;
}
case EDirection::Forward:
{
Position += FrontDirection * _translationAmount * _deltaTime;
break;
}
case EDirection::Backward:
{
Position -= FrontDirection * _translationAmount * _deltaTime;
break;
}
default:
{
throw std::logic_error("Direction move not defined.");
}
}
return;
}
void Move(const Vector3& _translationAmount, gFloat _deltaTime)
{
Position += _translationAmount * _deltaTime;
return;
}
void Rotate(ERotationAxis _pivot, gFloat _rotationAmount, gFloat _deltaTime)
{
switch (_pivot)
{
case ERotationAxis::Pitch:
{
Pitch -= _rotationAmount * _deltaTime;
if (Pitch > 89.9f)
{
Pitch = 89.9f;
}
else if (Pitch < -89.9f)
{
Pitch = -89.9f;
}
return;
}
case ERotationAxis::Roll:
{
Roll += _rotationAmount * _deltaTime;
return;
}
case ERotationAxis::Yaw:
{
Yaw += _rotationAmount * _deltaTime;
return;
}
}
}
void UpdateCamera()
{
FrontDirection.x = Cosine(ToRadians(Yaw )) * Cosine(ToRadians(Pitch));
FrontDirection.y = Sine (ToRadians(Pitch)) ;
FrontDirection.z = Sine (ToRadians(Yaw )) * Cosine(ToRadians(Pitch));
FrontDirection = GetDirection(FrontDirection );
RightDirection = GetDirection(GetCrossNormal(FrontDirection, DefaultSpace::UpDirection ));
UpDirection = GetDirection(GetCrossNormal(RightDirection, FrontDirection));
LookAtPosition = Position + FrontDirection;
Viewport = CreateLookAtView(Position, LookAtPosition, UpDirection);
return;
}
};
namespace DefaultSpace
{
Camera WorldCamera
(
AspectRatio ,
FieldOfView ,
ClippingPlanes(NearClippingPlane, FarClippingPlane),
CameraPosition ,
LookAtPosition ,
UpDirection ,
FrontDirection
);
CoordSpace WorldSpace(Matrix4x4(1.0f));
CoordSpace Screenspace = WorldCamera.Perspective * WorldCamera.Viewport * WorldSpace;
void UpdateScreenspace()
{
Screenspace = WorldCamera.Perspective * WorldCamera.Viewport * WorldSpace;
return;
}
}
}

117
DGL/DGL_Types.hpp Normal file
View File

@ -0,0 +1,117 @@
/*
Title : Ducktaped GL: Types
Author: Edward R. Gonzalez
Description:
Provides type definitions and aliases for the various types used in DGL library.
*/
#pragma once
// GLEW
#include <glew.h>
// GLFW
#include <glfw3.h>
// GLM
#include <glm/glm.hpp>
// C++
#include "Cpp_Alias.hpp"
namespace DGL
{
// OpenGL
// Fundamental Types
using gBitfield = GLbitfield;
using gBoolean = GLboolean ;
using gChar = GLchar ;
using gFloat = GLfloat ;
using gFloatClamped = GLclampf ;
using gInt = GLint ;
using gUInt = GLuint ;
using gSize = GLsizei ;
using gVoid = GLvoid ;
using DataPtr = gVoid*;
// Type used to indicate the context of an integer used as an ID for an object managed by OpenGL.
template<typename ReferenceType>
using ID = gUInt;
// ID Reference Types
class ElementBuffer;
class Matrix ;
class NormalBuffer ;
class Shader ;
class ShaderProgram;
class TextureBuffer;
class Vec3 ;
class VertexArray ;
class VertexBuffer ;
// GLM
namespace Generic
{
template<typename Type>
using Vector3 = glm::tvec3<Type>;
template<typename Type>
using Vector2 = glm::tvec2<Type>;
}
using Matrix4x4 = glm::mat4;
using CoordSpace = Matrix4x4;
using Projection = Matrix4x4;
using Vector2 = glm::vec2;
using Vector3 = glm::vec3;
using Vector4 = glm::vec4;
using UVList = std::vector < Vector2>;
using Vec2Int = Generic::Vector2< gUInt >;
using Vec3Int = Generic::Vector3< gUInt >;
using VertexList = std ::vector < Vector3>;
// GLFW
using Monitor = GLFWmonitor ;
using TimeValInt = uint64_t ;
using TimeValDec = double ;
using Window = GLFWwindow ;
using WindowRefList = std::vector< Window* >;
// DGL
using VecColor = Vector3;
struct LinearColor
{
gFloatClamped Red, Green, Blue, Alpha;
LinearColor(gFloatClamped _red, gFloatClamped _green, gFloatClamped _blue, gFloatClamped _alpha) :
Red(_red), Green(_green), Blue(_blue), Alpha(_alpha) {};
Vector3 Vector()
{
return Vector3(Red, Green, Blue);
}
};
using VIndexList = std::vector< gInt>;
}

248
DGL/DGL_Utilities.hpp Normal file
View File

@ -0,0 +1,248 @@
#pragma once
// GLFW, GLEW, GLM
#include <glew.h >
#include <glfw3.h >
#include <glm/glm.hpp >
#include <glm/gtc/matrix_transform.hpp>
// DGL
#include "DGL_Types.hpp"
#include "DGL_Enum.hpp"
#include "DGL_Shader.hpp"
#include "DGL_Buffers.hpp"
#include "DGL_Space.hpp"
#include "DGL_Model.hpp"
// Non-Standard C+
#include "Cpp_Alias.hpp"
namespace DGL
{
// Object Instances
WindowRefList Windows;
// Constants
constexpr Window* NotShared () { return NULL; }
constexpr Monitor* WindowedMode() { return NULL; }
// Forward Declarations
void SwapBuffers(Window* const _window);
// Functionality
bool CanClose(Window* const _theWindow)
{
return glfwWindowShouldClose(_theWindow);
}
bool CanUseRawMouse()
{
return glfwRawMouseMotionSupported();
}
Window* CreateWindow
(
int _width ,
int _height ,
const char* const _title ,
Monitor* const _monitorToFullscreen ,
Window* const _windowToShareResourcesWith
)
{
Windows.push_back(glfwCreateWindow(_width, _height, _title, _monitorToFullscreen, _windowToShareResourcesWith));
if (Windows.back() == NULL)
{
throw std::runtime_error("Failed to create a window");
}
return Windows.back();
}
void CursorPositionUpdateBind(Window* const _window, void(*_functionToCall)(double, double))
{
glfwSetCursorPosCallback(_window, GLFWcursorposfun(_functionToCall));
}
void DestoryWindow(Window* const _window)
{
using ElementType = decltype(Windows.begin());
for (ElementType element = Windows.begin(); element != Windows.end(); element++)
{
if (*element == _window)
{
glfwDestroyWindow(_window);
Windows.erase(element);
return;
}
}
return;
}
void EnableDepth()
{
// TODO: Clean.
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
return;
}
void GetCursorPosition(Window* const _window, double* const _xAxis, double* const _yAxis)
{
glfwGetCursorPos(_window, _xAxis, _yAxis);
}
gInt GetMouseInputMode(Window* const _contextWindowRef, EMouseMode _mode)
{
return glfwGetInputMode(_contextWindowRef, GLenum(_mode));
}
TimeValInt GetRawTime()
{
return glfwGetTimerValue();
}
TimeValDec GetTime()
{
return glfwGetTime();
}
void InitalizeGLFW()
{
std::cout << "Initializing GLFW Version: " << glfwGetVersionString() << std::endl;
/* Initialize the library */
if (!glfwInit())
{
throw std::runtime_error("Failed to initialize GLFW");
}
return;
}
void InitalizeGLEW()
{
// If using GLEW version 1.13 or earlier
//glewExperimental = true;
std::cout << "Initializing Glew Version: " << glewGetString(GLEW_VERSION) << std::endl;
GLenum err = glewInit();
if (err != GLEW_OK)
{
// Problem: glewInit failed, something is seriously wrong.
std::cout << "glewInit failed: " << glewGetErrorString(err) << std::endl;
throw std::runtime_error("Failed to initialize GLFW");
}
cout << "OpenGL Version: " << glGetString(GL_VERSION) << endl;
}
bool KeyPressed(Window* const _contextWindowRef, EKeyCodes _keyToCheck)
{
return glfwGetKey(_contextWindowRef, int(_keyToCheck));
}
template<typename... CodeType, typename = EKeyCodes>
bool KeysPressed(Window* const _contextWindowRef, CodeType... _otherKeys)
{
return (KeyPressed(_contextWindowRef, _otherKeys) && ...) == true;
}
void PollEvents()
{
glfwPollEvents();
return;
}
void ResetCursor(Window* _window, gUInt _screenCenterWidth, gUInt _screenCenterHeight)
{
//glfwSetCursorPos(_window, _screenCenterWidth, _screenCenterHeight);
ECursorMode cursorMode = ECursorMode(GetMouseInputMode(_window, EMouseMode::Cursor));
if (cursorMode == ECursorMode::Normal || cursorMode == ECursorMode::Hidden) // Normal Cursor Mode
{
glfwSetCursorPos(_window, double(_screenCenterWidth), double(_screenCenterHeight));
}
else // Raw Cursor mode
{
glfwSetCursorPos(_window, 0, 0);
}
return;
}
void SetClearColor(const LinearColor& _colorToSet)
{
glClearColor(_colorToSet.Red, _colorToSet.Green, _colorToSet.Blue, _colorToSet.Alpha);
return;
}
void SetCurrentContext(Window* const _window)
{
glfwMakeContextCurrent(_window);
const char** ErrorMsg = NULL;
int code = glfwGetError(ErrorMsg);
if (code == GLFW_NO_WINDOW_CONTEXT)
{
throw std::runtime_error(*ErrorMsg);
}
return;
}
template<typename ModeParam>
void SetInputMode(Window* const _window, EMouseMode _mouseMode, ModeParam _modeParam)
{
glfwSetInputMode(_window, GLenum(_mouseMode), GLenum(_modeParam));
return;
}
void SetPolygonMode(EFace _desiredFaces, ERenderMode _desiredMode)
{
glPolygonMode(GLenum(_desiredFaces), GLenum(_desiredMode));
return;
}
void SwapBuffers(Window* const _window)
{
glfwSwapBuffers(_window);
return;
}
void TerminateGLFW()
{
glfwTerminate();
return;
}
}

693
Execution.cpp Normal file
View File

@ -0,0 +1,693 @@
/*
Title : Execution
Author: Edward R. Gonzalez
Description:
This brings together the functionality I made in DGL and the Actions libraries to produce an OpenGL Workspace.
Currently the workspace is heavily hardcoded and has one light rotating around the specified object. The material for the object is set during prep as well.
All exposed library references are inside the inline namespace right after declaring the namespace execution.
After I have the global objects used, followed by the functionality implementations, and at the very end the main function running the default execution implementation.
*/
// DGL
#include "DGL/DGL.hpp"
// Utility
#include "Actions.hpp"
// Non-Standard C++
#include "Cpp_Alias.hpp"
namespace Execution
{
inline namespace LibraryReferences
{
// DGL
using DGL::EBool ;
using DGL::ECursorMode ;
using DGL::EDirection ;
using DGL::EFrameBuffer ;
using DGL::EKeyCodes ;
using DGL::EMouseMode ;
using DGL::EPrimitives ;
using DGL::ERotationAxis;
using DGL::Camera ;
using DGL::Entity_Basic ;
using DGL::gFloat ;
using DGL::Light_Basic ;
using DGL::LinearColor ;
using DGL::Material_Phong;
using DGL::Matrix ;
using DGL::Matrix4x4 ;
using DGL::Model ;
using DGL::TimeValDec ;
using DGL::Vector3 ;
using DGL::Window ;
using DGL::BindVertexArray ;
using DGL::CanUseRawMouse ;
using DGL::ClearBuffer ;
using DGL::CreateWindow ;
using DGL::DestoryWindow ;
using DGL::DisableVertexAttributeArray;
using DGL::EnableDepth ;
using DGL::EnableVertexAttributeArray ;
using DGL::GetCursorPosition ;
using DGL::GetTime ;
using DGL::InitalizeGLEW ;
using DGL::InitalizeGLFW ;
using DGL::LoadDefaultShaders ;
using DGL::KeyPressed ;
using DGL::NotShared ;
using DGL::PollEvents ;
using DGL::ResetCursor ;
using DGL::SetClearColor ;
using DGL::SetCurrentContext ;
using DGL::SetInputMode ;
using DGL::SetPolygonMode ;
using DGL::SetUniformVariable_MVA ;
using DGL::SwapBuffers ;
using DGL::UseProgramShader ;
using DGL::TerminateGLFW ;
using DGL::WindowedMode ;
using DGL::DefaultSpace::ScreenWidth ;
using DGL::DefaultSpace::ScreenHeight ;
using DGL::DefaultSpace::ScreenCenterHeight;
using DGL::DefaultSpace::ScreenCenterWidth ;
using DGL::DefaultSpace::Screenspace ;
using DGL::DefaultSpace::WorldCamera ;
using DGL::DefaultSpace::UpdateScreenspace;
// Actions
using Actions::ActionQueue;
}
enum class EModels
{
Bunny ,
Cube ,
Eight ,
Gargoyle ,
Hand ,
Sculpture,
Topology ,
Torus
};
// Globals
bool Exist = true; // Determines if the the execution should exit cycler.
TimeValDec CycleStart , // Snapshot of cycle loop start time.
CycleEnd , // Snapshot of cycle loop end time.
DeltaTime , // Delta between last cycle start and end.
InputInterval = 1.0f / 144.0f, // Interval per second to complete the input process of the cycle.
PhysicsInterval = 1.0f / 144.0f, // Interval per second to complete the physics process of the cycle.
RenderInterval = 1.0f / 144.0f ; // Interval per second to complete the render process of the cycle.
Window* DefaultWindow; // Default window to use for execution.
double CursorX, CursorY; // Cursor axis position on the window.
bool CursorOff = true, ShowLight = true;
gFloat CamMoveSpeed = 7.0f, // Rate at which the camera should move.
CamRotationSpeed = 27.0f ; // Rate at which the camera should rotate.
TimeValDec InputDelta = 0.0, // Current delta since last input process.
PhysicsDelta = 0.0, // Current delta since last physics process.
RenderDelta = 0.0 ; // Current delta since last render process.
ActionQueue ActionsToComplete; // Actions queue to run during the physics process of the cycle.
EModels CurrentModel = EModels::Torus;
Model Bunny ("./Models/bunny.obj" );
Model Cube ("./Models/blenderCube2.obj");
Model Eight ("./Models/eight.obj" );
Model Gargoyle ("./Models/gargoyle.obj" );
Model Hand ("./Models/hand.obj" );
Model Horse ("./Models/horse.obj" );
Model Sculpture("./Models/sculpture.obj" );
Model Topology ("./Models/topology.obj" );
Model Torus ("./Models/Torus.obj" );
Material_Phong ObjectMaterial;
Light_Basic Light ; // Hardcoded light. Rotates around object.
Entity_Basic ObjectToView; // Object that will be currently in the middle with the light source rotating.
string
windowTitle = "Assignment 1" ,
deltaStr = "Delta: " ,
inputDeltaStr = "Input Delta: " ,
physicsDeltaStr = "Physics Delta: " ,
renderDeltaStr = "RenderDeltaStr: " ;
stringstream WindowTitle;
// Functionality
void ChangeModel()
{
if (CurrentModel == EModels::Torus)
{
CurrentModel = EModels::Bunny;
}
else
{
CurrentModel = EModels(int(CurrentModel) + 1);
}
switch (CurrentModel)
{
case EModels::Bunny:
{
if (not Bunny.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Bunny...");
Bunny.Load();
}
ObjectToView.SetModel(Bunny);
ObjectToView.SetScale(4.0f);
ObjectToView.SetPosition(Vector3(-0.05, -4.4f, 0));
return;
}
case EModels::Cube:
{
if (not Cube.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Cube...");
Cube.Load();
}
ObjectToView.SetModel(Cube);
ObjectToView.SetScale(1.0f);
ObjectToView.SetPosition(Vector3(0, -1.0, 0));
return;
}
case EModels::Eight:
{
if (not Eight.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Eight...");
Eight.Load();
}
ObjectToView.SetModel(Eight);
//ObjectToView.Scale(1.0f);
ObjectToView.SetPosition(Vector3(0, -1.0, 0));
return;
}
case EModels::Gargoyle:
{
if (not Gargoyle.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Gargoyle...");
Gargoyle.Load();
}
ObjectToView.SetModel(Gargoyle);
ObjectToView.SetPosition(Vector3(-1, -5.4f, 0));
ObjectToView.SetScale(6.0f);
return;
}
case EModels::Hand:
{
if (not Hand.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Hand...");
Hand.Load();
}
ObjectToView.SetModel(Hand);
ObjectToView.SetScale(0.03f);
ObjectToView.SetPosition(Vector3(0, -1.1f, 0));
return;
}
case EModels::Sculpture:
{
if (not Sculpture.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Sculpture...");
Sculpture.Load();
}
ObjectToView.SetModel(Sculpture);
ObjectToView.SetScale(0.01f);
return;
}
case EModels::Topology:
{
if (not Topology.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Topology...");
Topology.Load();
}
ObjectToView.SetModel(Topology);
ObjectToView.SetScale(0.2f);
return;
}
case EModels::Torus:
{
if (not Torus.Ready())
{
glfwSetWindowTitle(DefaultWindow, "Assignment 1: Loading Torus...");
Torus.Load();
}
ObjectToView.SetModel(Torus);
ObjectToView.SetScale(1.0f);
return;
}
}
}
auto ChangeModelDelegate = function<decltype(ChangeModel)>(ChangeModel);
void ToggleLight()
{
if (ShowLight)
{
ShowLight = false;
return;
}
else
{
ShowLight = true;
return;
}
}
auto ToogleLightDelegate = function<decltype(ToggleLight)>(ToggleLight);
// Input Action common functions...
void RotateCamera(ERotationAxis _rotationAxis, gFloat _rotationAmount, double _delta)
{
WorldCamera.Rotate(_rotationAxis, _rotationAmount, gFloat(_delta));
return;
}
auto RotateCamDelegate = function<decltype(RotateCamera)>(RotateCamera);
void MoveCamera(EDirection _direction, gFloat _translationAmount, double _delta)
{
WorldCamera.Move(_direction, _translationAmount, gFloat(_delta));
return;
}
auto MoveCamDelegate = function<decltype(MoveCamera)>(MoveCamera);
// This is here cause its super repetitive..
void ModifyCamSpeed(bool _isPositive, double _delta)
{
if (_isPositive)
{
CamMoveSpeed += CamMoveSpeed * gFloat(_delta);
return;
}
else
{
CamMoveSpeed -= CamMoveSpeed * gFloat(_delta);
return;
}
}
auto ModifyCamSpeedDelegate = function<decltype(ModifyCamSpeed)>(ModifyCamSpeed);
auto SetPolyModeDelegate = function<decltype(SetPolygonMode)>(SetPolygonMode);
// End of common input functions...
void UpdateWindowDeltaTitle()
{
WindowTitle.str("");
WindowTitle
<< windowTitle << " "
<< deltaStr << DeltaTime << " "
<< inputDeltaStr << InputDelta << " "
<< physicsDeltaStr << PhysicsDelta << " "
<< renderDeltaStr << RenderDelta ;
}
// Currently Does everything required before entering the cycler.
void PrepWorkspace()
{
// Baseline
InitalizeGLFW();
DefaultWindow = CreateWindow(ScreenWidth, ScreenHeight, "Assignment 1: Loading Model...", WindowedMode(), NotShared());
SetCurrentContext(DefaultWindow);
InitalizeGLEW(); // Glew must initialize only after a context is set.
EnableDepth();
SetPolygonMode(DGL::EFace::Front_and_Back, DGL::ERenderMode::Fill);
// Cursor stuff
SetInputMode(DefaultWindow, DGL::EMouseMode::Cursor, DGL::ECursorMode::Disable);
ResetCursor(DefaultWindow, ScreenCenterWidth, ScreenCenterHeight);
if (CanUseRawMouse())
{
SetInputMode(DefaultWindow, DGL::EMouseMode::RawMouse, DGL::EBool::True);
}
// End of cursor stuff...
// Shaders
LoadDefaultShaders();
// Entities
Light.Load();
Torus.Load();
ObjectMaterial.Color = DGL::Colors::WarmSphia.Vector();
ObjectMaterial.Ambience = 0.112f ;
ObjectMaterial.Diffuse = 0.928f ;
ObjectMaterial.Specular = 0.21f ;
ObjectToView = Entity_Basic(Torus, ObjectMaterial);
}
/*
Cycles the process of what to do while a window is open.
The input, physics, and render procedures can be specified with extra functionality by specifying delegates to those procedures.
Cycler is hardcoded to exit if escape key is pressed.
*/
void Cycler(const function< void(Window*)>& _inputProcedure, const function< void()>& _physicsProcedure, const function< void()>& _renderProcedure)
{
while (Exist)
{
CycleStart = GetTime();
if (InputDelta >= InputInterval)
{
PollEvents();
if (KeyPressed(DefaultWindow, EKeyCodes::Escape))
{
Exist = false;
}
GetCursorPosition(DefaultWindow, &CursorX, &CursorY);
_inputProcedure(DefaultWindow);
if (CursorOff)
{
ResetCursor(DefaultWindow, ScreenCenterWidth, ScreenCenterHeight);
}
}
if (PhysicsDelta >= PhysicsInterval)
{
while (ActionsToComplete.HasAction())
{
ActionsToComplete.DoNextAction();
}
_physicsProcedure();
PhysicsDelta = 0.0;
}
if (RenderDelta >= RenderInterval)
{
ClearBuffer(EFrameBuffer::Color, EFrameBuffer::Depth);
SetClearColor(LinearColor(0.02f, 0.02f, 0.02f, 1.0f));
_renderProcedure();
SwapBuffers(DefaultWindow);
RenderDelta = 0.0;
}
if (InputDelta >= InputInterval)
{
InputDelta = 0.0;
}
CycleEnd = GetTime();
DeltaTime = CycleEnd - CycleStart;
InputDelta += DeltaTime;
PhysicsDelta += DeltaTime;
RenderDelta += DeltaTime;
}
return;
}
void InputProcedure(Window* _currentWindowContext)
{
if (KeyPressed(_currentWindowContext, EKeyCodes::F1))
{
ECursorMode cursorMode = ECursorMode(GetMouseInputMode(DefaultWindow, EMouseMode::Cursor));
auto delegate = function<decltype(SetInputMode<ECursorMode>)>(SetInputMode<ECursorMode>);
auto delegateRaw = function<decltype(SetInputMode<EBool >)>(SetInputMode<EBool >);
if (cursorMode == ECursorMode::Normal || cursorMode == ECursorMode::Hidden)
{
ActionsToComplete.AddToQueue(delegate , _currentWindowContext, EMouseMode::Cursor , ECursorMode::Disable);
ActionsToComplete.AddToQueue(delegateRaw, _currentWindowContext, EMouseMode::RawMouse, EBool ::True );
CursorOff = true;
}
else
{
ActionsToComplete.AddToQueue(delegate , _currentWindowContext, EMouseMode::Cursor , ECursorMode::Normal);
ActionsToComplete.AddToQueue(delegateRaw, _currentWindowContext, EMouseMode::RawMouse, EBool ::False );
CursorOff = false;
}
}
if (KeyPressed(_currentWindowContext, EKeyCodes::H))
{
ActionsToComplete.AddToQueue(ToogleLightDelegate);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::M))
{
ActionsToComplete.AddToQueue(ChangeModelDelegate);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::UpArrow))
{
ActionsToComplete.AddToQueue(ModifyCamSpeedDelegate, true, PhysicsDelta);
}
if (KeysPressed(_currentWindowContext, EKeyCodes::DnArrow))
{
ActionsToComplete.AddToQueue(ModifyCamSpeedDelegate, false, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::F2))
{
ActionsToComplete.AddToQueue(SetPolyModeDelegate, DGL::EFace::Front_and_Back, DGL::ERenderMode::Line);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::F3))
{
ActionsToComplete.AddToQueue(SetPolyModeDelegate, DGL::EFace::Front_and_Back, DGL::ERenderMode::Fill);
}
if (CursorOff)
{
if (CursorX != 0)
{
ActionsToComplete.AddToQueue(RotateCamDelegate, ERotationAxis::Yaw, gFloat(CursorX) * CamRotationSpeed, PhysicsDelta);
}
if (CursorY != 0)
{
ActionsToComplete.AddToQueue(RotateCamDelegate, ERotationAxis::Pitch, gFloat(CursorY) * CamRotationSpeed, PhysicsDelta);
}
}
if (KeyPressed(_currentWindowContext, EKeyCodes::E))
{
ActionsToComplete.AddToQueue(MoveCamDelegate, EDirection::Up, CamMoveSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::Q))
{
ActionsToComplete.AddToQueue(MoveCamDelegate, EDirection::Down, CamMoveSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::A))
{
ActionsToComplete.AddToQueue(MoveCamDelegate, EDirection::Left, CamMoveSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::D))
{
ActionsToComplete.AddToQueue(MoveCamDelegate, EDirection::Right, CamMoveSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::W))
{
ActionsToComplete.AddToQueue(MoveCamDelegate, EDirection::Forward, CamMoveSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::S))
{
ActionsToComplete.AddToQueue(MoveCamDelegate, EDirection::Backward, CamMoveSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::I))
{
ActionsToComplete.AddToQueue(RotateCamDelegate, ERotationAxis::Pitch, -6.0f * CamRotationSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::K))
{
ActionsToComplete.AddToQueue(RotateCamDelegate, ERotationAxis::Pitch, 6.0f * CamRotationSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::J))
{
ActionsToComplete.AddToQueue(RotateCamDelegate, ERotationAxis::Yaw, -6.0f * CamRotationSpeed, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::L))
{
ActionsToComplete.AddToQueue(RotateCamDelegate, ERotationAxis::Yaw, 6.0f * CamRotationSpeed, PhysicsDelta);
}
return;
}
void PhysicsProcedure()
{
WorldCamera.UpdateCamera();
UpdateScreenspace();
Light.Update(gFloat(PhysicsDelta));
ObjectToView.Update();
UpdateWindowDeltaTitle();
return;
}
void RenderProcedure()
{
glfwSetWindowTitle(DefaultWindow, WindowTitle.str().c_str());
if (ShowLight)
{
Light.Render(WorldCamera.Perspective, WorldCamera.Viewport);
}
ObjectToView.Render(WorldCamera.Perspective, WorldCamera.Viewport, Light.GetPosition(), Light.GetColor());
return;
}
// Runtime Execution: Default Execution
int Execute()
{
PrepWorkspace();
Cycler(InputProcedure, PhysicsProcedure, RenderProcedure);
// TODO: There should be more to properly close...
DestoryWindow(DefaultWindow);
TerminateGLFW();
return EXIT_SUCCESS;
}
}
// Currently only can do one execution route.
int main(void)
{
return Execution::Execute();
}

24
Models/blenderCube2.obj Normal file
View File

@ -0,0 +1,24 @@
# Blender v2.80 (sub 74) OBJ File: ''
# www.blender.org
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
s off
f 5 3 1
f 3 8 4
f 7 6 8
f 2 8 6
f 1 4 2
f 5 2 6
f 5 7 3
f 3 7 8
f 7 5 6
f 2 4 8
f 1 3 4
f 5 1 2

37502
Models/bunny.obj Normal file

File diff suppressed because it is too large Load Diff

35
Models/cube.obj Normal file
View File

@ -0,0 +1,35 @@
#
#
#
#
# cube Mesh
#
g cube Mesh
v 0.022541 0.000000 0.000000
v 1.022541 1.000000 0.000000
v 1.022541 0.000000 0.000000
v 0.022541 1.000000 0.000000
v 0.022541 1.000000 1.000000
v 0.022541 0.000000 1.000000
v 1.022541 1.000000 1.000000
v 1.022541 0.000000 1.000000
vn 0.000000 0.000000 -1.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 0.000000 1.000000
f 1//1 2//1 3//1
f 1//1 4//1 2//1
f 1//2 5//2 4//2
f 1//2 6//2 5//2
f 4//3 7//3 2//3
f 4//3 5//3 7//3
f 3//4 2//4 7//4
f 3//4 7//4 8//4
f 1//5 3//5 8//5
f 1//5 8//5 6//5
f 6//6 8//6 7//6
f 6//6 7//6 5//6

32
Models/cubeNoNormals.obj Normal file
View File

@ -0,0 +1,32 @@
#
#
#
mtllib cube.mtl
#
# cube Mesh
#
g cube Mesh
v 0.022541 0.000000 0.000000
v 1.022541 1.000000 0.000000
v 1.022541 0.000000 0.000000
v 0.022541 1.000000 0.000000
v 0.022541 1.000000 1.000000
v 0.022541 0.000000 1.000000
v 1.022541 1.000000 1.000000
v 1.022541 0.000000 1.000000
f 1 2 3
f 1 4 2
f 1 5 4
f 1 6 5
f 4 7 2
f 4 5 7
f 3 2 7
f 3 7 8
f 1 3 8
f 1 8 6
f 6 8 7
f 6 7 5

9214
Models/eight.obj Normal file

File diff suppressed because it is too large Load Diff

30002
Models/gargoyle.obj Normal file

File diff suppressed because it is too large Load Diff

114657
Models/hand.obj Normal file

File diff suppressed because it is too large Load Diff

59549
Models/horse.obj Normal file

File diff suppressed because it is too large Load Diff

76166
Models/sculpture.obj Normal file

File diff suppressed because it is too large Load Diff

19896
Models/topology.obj Normal file

File diff suppressed because it is too large Load Diff

3072
Models/torus.obj Normal file

File diff suppressed because it is too large Load Diff

14
Shaders/BasicLight.frag Normal file
View File

@ -0,0 +1,14 @@
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0); // set all 4 vector values to 1.0
}

14
Shaders/BasicLight.vert Normal file
View File

@ -0,0 +1,14 @@
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 ScreenSpaceTransform;
void main()
{
gl_Position = ScreenSpaceTransform * vec4(aPos, 1.0);
}

48
Shaders/PhongShader.frag Normal file
View File

@ -0,0 +1,48 @@
#version 330 core
out vec4 FragColor;
in vec3 FragPosition ;
in vec3 Normal ;
in vec3 LightViewPosition;
uniform vec3 ObjectColor ;
uniform vec3 LightColor ;
uniform float AmbientStrength ;
uniform float DiffuseStrength ;
uniform float SpecularStrength;
void main()
{
// Ambient
vec3 ambient = AmbientStrength * LightColor ;
// Diffuse
vec3 direction = normalize(Normal );
vec3 lightDirection = normalize(LightViewPosition - FragPosition);
float diffuseMagnitude = max(dot(direction, lightDirection), 0.0);
vec3 diffuse = DiffuseStrength * diffuseMagnitude * LightColor;
// Specular
vec3 viewDirection = normalize(-FragPosition);
vec3 reflectionDirection = reflect(-lightDirection, direction);
float spec = pow(max(dot(viewDirection, reflectionDirection), 0.0), 32);
vec3 specular = SpecularStrength * spec * LightColor;
// Combining
vec3 result = (ambient + diffuse + specular) * ObjectColor;
FragColor = vec4(result, 1.0);
}

34
Shaders/PhongShader.vert Normal file
View File

@ -0,0 +1,34 @@
#version 330 core
#define VertexIndex 0
#define NormalIndex 1
#define TextureIndex 2
layout (location = VertexIndex ) in vec3 VertPosition;
layout (location = NormalIndex ) in vec3 VertNormal ;
layout (location = TextureIndex) in vec3 VertTexture ;
out vec3 FragPosition ;
out vec3 Normal ;
out vec3 LightViewPosition;
uniform mat4 InverseModelSpace;
uniform mat4 ModelSpace;
uniform mat4 Viewport ;
uniform mat4 Projection;
uniform vec3 LightPosition;
void main()
{
gl_Position = Projection * Viewport * ModelSpace * vec4(VertPosition, 1.0);
FragPosition = vec3(Viewport * ModelSpace * vec4(VertPosition, 1.0));
Normal = mat3(transpose(InverseModelSpace)) * VertNormal;
LightViewPosition = vec3(Viewport * vec4(LightPosition, 1.0));
}