mirror of
https://github.com/Ed94/DuctTaped_GL.git
synced 2024-12-21 22:44:47 -08:00
Translated to standard c++ after big clean of adhesive from non-standard branch
This commit is contained in:
parent
c46f44a8d8
commit
da17f52c9d
408
Actions.hpp
Normal file
408
Actions.hpp
Normal 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
76
Cpp_Alias.hpp
Normal 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
20
DGL/DGL.hpp
Normal 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
139
DGL/DGL_Buffers.hpp
Normal 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
292
DGL/DGL_Entity.hpp
Normal 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
326
DGL/DGL_Enum.hpp
Normal 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
467
DGL/DGL_Model.hpp
Normal 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
435
DGL/DGL_Shader.hpp
Normal 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
283
DGL/DGL_Space.hpp
Normal 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
117
DGL/DGL_Types.hpp
Normal 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
248
DGL/DGL_Utilities.hpp
Normal 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
693
Execution.cpp
Normal 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
24
Models/blenderCube2.obj
Normal 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
37502
Models/bunny.obj
Normal file
File diff suppressed because it is too large
Load Diff
35
Models/cube.obj
Normal file
35
Models/cube.obj
Normal 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
32
Models/cubeNoNormals.obj
Normal 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
9214
Models/eight.obj
Normal file
File diff suppressed because it is too large
Load Diff
30002
Models/gargoyle.obj
Normal file
30002
Models/gargoyle.obj
Normal file
File diff suppressed because it is too large
Load Diff
114657
Models/hand.obj
Normal file
114657
Models/hand.obj
Normal file
File diff suppressed because it is too large
Load Diff
59549
Models/horse.obj
Normal file
59549
Models/horse.obj
Normal file
File diff suppressed because it is too large
Load Diff
76166
Models/sculpture.obj
Normal file
76166
Models/sculpture.obj
Normal file
File diff suppressed because it is too large
Load Diff
19896
Models/topology.obj
Normal file
19896
Models/topology.obj
Normal file
File diff suppressed because it is too large
Load Diff
3072
Models/torus.obj
Normal file
3072
Models/torus.obj
Normal file
File diff suppressed because it is too large
Load Diff
14
Shaders/BasicLight.frag
Normal file
14
Shaders/BasicLight.frag
Normal 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
14
Shaders/BasicLight.vert
Normal 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
48
Shaders/PhongShader.frag
Normal 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
34
Shaders/PhongShader.vert
Normal 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));
|
||||
}
|
Loading…
Reference in New Issue
Block a user