diff options
Diffstat (limited to 'src/libjin')
124 files changed, 11160 insertions, 11160 deletions
diff --git a/src/libjin/ai/behavior_tree.h b/src/libjin/ai/behavior_tree.h index eb36e9f..8e59e29 100644 --- a/src/libjin/ai/behavior_tree.h +++ b/src/libjin/ai/behavior_tree.h @@ -8,51 +8,51 @@ namespace JinEngine { - namespace AI - { - - /// - /// - /// - class BehaviorTree : public Object - { - public: - BehaviorTree(void* userData) : mUserData(userData){} - - class Node : public Object - { - public: - enum Type - { - - }; - - enum Status - { - Running, - Success, - Failure - }; - - Status status; - }; - - typedef std::function<Node::Status(void*)> UpdateCallback; - - Node makeNode(Node::Type type, UpdateCallback callback); - - private: - - /// - /// - /// - void* const mUserData; - - }; - - typedef BehaviorTree::Node::Status BahaviorNodeStatus; - - } // namespace AI + namespace AI + { + + /// + /// + /// + class BehaviorTree : public Object + { + public: + BehaviorTree(void* userData) : mUserData(userData){} + + class Node : public Object + { + public: + enum Type + { + + }; + + enum Status + { + Running, + Success, + Failure + }; + + Status status; + }; + + typedef std::function<Node::Status(void*)> UpdateCallback; + + Node makeNode(Node::Type type, UpdateCallback callback); + + private: + + /// + /// + /// + void* const mUserData; + + }; + + typedef BehaviorTree::Node::Status BahaviorNodeStatus; + + } // namespace AI } // namespace JinEngine #endif // jin_ai diff --git a/src/libjin/ai/state_machine.cpp b/src/libjin/ai/state_machine.cpp index cefd0b9..96450ae 100644 --- a/src/libjin/ai/state_machine.cpp +++ b/src/libjin/ai/state_machine.cpp @@ -6,440 +6,440 @@ using namespace std; namespace JinEngine { - namespace AI - { - - StateMachine::StateMachine(Mode mode, void* userdata) - : mCurrentState(0) - , mUserData(userdata) - , mMode(mode) - { - addState(0); - } - - StateMachine::~StateMachine() - { - } - - void StateMachine::invokeCallback(int from, int to) - { - if (mExitCallback != nullptr) - mExitCallback(from, mUserData); - if (mTraslateCallback != nullptr) - mTraslateCallback(from, to, mUserData); - if (mEnterCallback != nullptr) - mEnterCallback(to, mUserData); - map<int, StateChangeCallback>::iterator it = mOnExitState.find(from); - if (it != mOnExitState.end()) - it->second(mUserData); - map<pair<int, int>, StateTranslateCallback>::iterator transItr - = mOnStateTranslate.find(pair<int, int>(from, to)); - if (transItr != mOnStateTranslate.end()) - transItr->second(mUserData); - it = mOnEnterState.find(to); - if (it != mOnEnterState.end()) - it->second(mUserData); - } - - void StateMachine::stepwiseProcess() - { - map<int, State>::iterator it = mStates.find(mCurrentState); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", mCurrentState); - return; - } - State& state = it->second; - for (int i = 0; i < state.transitions.size(); ++i) - { - Conditions conditions = state.transitions[i].conditions; - bool isActive = true; - for (int j = 0; j < conditions.conditions.size(); ++j) - { - isActive &= processCondition(conditions.conditions[j]); - if (!isActive) - break; - } - if (isActive) - { - // Traslate - mCurrentState = state.transitions[i].state; - invokeCallback(state.name, mCurrentState); - break; - } - } - // Call update - if (mUpdateCallback != nullptr) - mUpdateCallback(mCurrentState, mUserData); - map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); - if (uit != mOnUpdateState.end()) - uit->second(mUserData); - } - - void StateMachine::iterativeProcess() - { - map<int, State>::iterator it = mStates.find(mCurrentState); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", mCurrentState); - return; - } - State& state = it->second; - bool isActive = true; - for (int i = 0; i < state.transitions.size(); ++i) - { - Conditions conditions = state.transitions[i].conditions; - isActive = true; - for (int j = 0; j < conditions.conditions.size(); ++j) - { - isActive &= processCondition(conditions.conditions[j]); - if (!isActive) - break; - } - if (isActive) - { - // Traslate - mCurrentState = state.transitions[i].state; - invokeCallback(state.name, mCurrentState); - break; - } - } - // Call update - if (mUpdateCallback != nullptr) - mUpdateCallback(mCurrentState, mUserData); - map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); - if (uit != mOnUpdateState.end()) - uit->second(mUserData); - // Recursive. - if(isActive) - return iterativeProcess(); - } - - void StateMachine::setMode(Mode mode) - { - mMode = mode; - } - - void StateMachine::update() - { - switch (mMode) - { - case Mode::Iterative: iterativeProcess(); break; - case Mode::Stepwise: stepwiseProcess(); break; - } - } - - bool StateMachine::processCondition(const Condition& condition) - { - map<int, Parameter>::iterator it = mParameters.find(condition.parameter); - if (it == mParameters.end()) - { - jin_log_error("The parameter <%d> is not exist", condition.parameter); - return false; - } - Parameter& p = it->second; - switch (p.type) - { - case ParameterType::Int: - { - int value = p.value._int; - int cvalue = condition.value._int; - bool is = false; - is |= ((condition.expression & ParameterExpression::INT_GREATER) ? value > cvalue : false); - is |= ((condition.expression & ParameterExpression::INT_EQUAL) ? value == cvalue : false); - is |= ((condition.expression & ParameterExpression::INT_LESS) ? value < cvalue : false); - return is; - } - case ParameterType::Float: - { - float value = p.value._float; - float cvalue = condition.value._float; - bool is = false; - is |= ((condition.expression & ParameterExpression::FLOAT_GREATER) ? value > cvalue : false); - is |= ((condition.expression & ParameterExpression::FLOAT_EQUAL) ? value == cvalue : false); - is |= ((condition.expression & ParameterExpression::FLOAT_LESS) ? value < cvalue : false); - return is; - } - case ParameterType::Bool: - { - bool value = p.value._bool; - bool cvalue = condition.value._bool; - bool is = false; - is |= ((condition.expression & ParameterExpression::BOOL_IS) ? value == cvalue : false); - is |= ((condition.expression & ParameterExpression::BOOL_NOT) ? value != cvalue : false); - return is; - } - case ParameterType::Trigger: - { - bool is = p.value._trigger; - // Close trigger. - p.value._trigger = false; - return is; - } - } - return false; - } - - int StateMachine::getCurrentState() - { - return mCurrentState; - } - - void StateMachine::addParameteri(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Int; - p.value._int = 0; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addParameterf(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Float; - p.value._float = 0.0f; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addParameterb(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Bool; - p.value._bool = false; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addParametert(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Trigger; - p.value._trigger = false; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addState(int name) - { - if (mStates.find(name) != mStates.end()) - { - jin_log_error("The state [%d] is already exist.", name); - return; - } - State state; - state.name = name; - mStates.insert(pair<int, State>(name, state)); - } - - const char* StateMachine::parameterTypeString(ParameterType type) - { - switch (type) - { - case ParameterType::Int: return "int"; - case ParameterType::Float: return "float"; - case ParameterType::Bool: return "bool"; - case ParameterType::Trigger: return "trigger"; - } - } - - void StateMachine::addTransition(int from, int to, const Conditions& conditions) - { - map<int, State>::iterator it; - it = mStates.find(from); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", from); - return; - } - State& fromState = it->second; - it = mStates.find(to); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", to); - return; - } - // Check condtion correctness. - for (int i = 0; i < conditions.conditions.size(); ++i) - { - const Condition& condition = conditions.conditions[i]; - map<int, Parameter>::iterator itp; - itp = mParameters.find(condition.parameter); - if (itp == mParameters.end()) - { - jin_log_error("The parameter <%d> is not exist.", condition.parameter); - return; - } - Parameter& p = itp->second; - if (p.type != condition.type) - { - jin_log_error("The type of parameter <%d> is a %s, but the transition gives a %s value." - , condition.parameter, parameterTypeString(p.type), parameterTypeString(condition.type)); - return; - } - } - // Add transition. - Transition transition; - transition.conditions = conditions; - transition.state = to; - fromState.transitions.push_back(transition); - } - - void StateMachine::setParameteri(int name, int value) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state [%d] is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Int) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a int value to it", name, parameterTypeString(p.type)); - return; - } - p.value._int = value; - } - - void StateMachine::setParameterf(int name, float value) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state [%d] is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Float) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a float value to it", name, parameterTypeString(p.type)); - return; - } - p.value._float = value; - } - - void StateMachine::setParameterb(int name, bool value) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state %s is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Bool) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a bool value to it", name, parameterTypeString(p.type)); - return; - } - p.value._bool = value; - } - - void StateMachine::setParametert(int name) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state %s is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Trigger) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a trigger value to it", name, parameterTypeString(p.type)); - return; - } - p.value._trigger = true; - } - - void StateMachine::forceToState(int name) - { - if (mStates.find(name) == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", name); - return; - } - mCurrentState = name; - } - - void StateMachine::addEnterListener(int state, const StateChangeCallback& callback) - { - if (mOnEnterState.find(state) != mOnEnterState.end()) - { - jin_log_error("The enter listener of [%d] is already exist.", state); - return; - } - mOnEnterState.insert(pair<int, StateChangeCallback>(state, callback)); - } - - void StateMachine::addUpdateListener(int state, const StateUpdateCallback& callback) - { - if (mOnUpdateState.find(state) != mOnUpdateState.end()) - { - jin_log_error("The update listener of [%d] is already exist.", state); - return; - } - mOnUpdateState.insert(pair<int, StateUpdateCallback>(state, callback)); - } - - void StateMachine::addExitListener(int state, const StateChangeCallback& callback) - { - if (mOnExitState.find(state) != mOnExitState.end()) - { - jin_log_error("The exit listener of [%d] is already exist.", state); - return; - } - mOnExitState.insert(pair<int, StateChangeCallback>(state, callback)); - } - - void StateMachine::addTranslateListener(int from, int to, const StateChangeCallback& callback) - { - if (mOnStateTranslate.find(pair<int, int>(from, to)) != mOnStateTranslate.end()) - { - jin_log_error("The traslate listener of [%d] to [%d] is already exist.", from, to); - return; - } - pair<int, int> key(from, to); - mOnStateTranslate.insert(pair<pair<int, int>, StateTranslateCallback>(key, callback)); - } - - void StateMachine::setUpdateListener(const SingleStateCallback& callback) - { - mUpdateCallback = callback; - } - - void StateMachine::setEnterListener(const SingleStateCallback& callback) - { - mEnterCallback = callback; - } - - void StateMachine::setExitListener(const SingleStateCallback& callback) - { - mExitCallback = callback; - } - - void StateMachine::setTranslateListener(const DoubleStateCallback& callback) - { - mTraslateCallback = callback; - } - - } // namespace AI + namespace AI + { + + StateMachine::StateMachine(Mode mode, void* userdata) + : mCurrentState(0) + , mUserData(userdata) + , mMode(mode) + { + addState(0); + } + + StateMachine::~StateMachine() + { + } + + void StateMachine::invokeCallback(int from, int to) + { + if (mExitCallback != nullptr) + mExitCallback(from, mUserData); + if (mTraslateCallback != nullptr) + mTraslateCallback(from, to, mUserData); + if (mEnterCallback != nullptr) + mEnterCallback(to, mUserData); + map<int, StateChangeCallback>::iterator it = mOnExitState.find(from); + if (it != mOnExitState.end()) + it->second(mUserData); + map<pair<int, int>, StateTranslateCallback>::iterator transItr + = mOnStateTranslate.find(pair<int, int>(from, to)); + if (transItr != mOnStateTranslate.end()) + transItr->second(mUserData); + it = mOnEnterState.find(to); + if (it != mOnEnterState.end()) + it->second(mUserData); + } + + void StateMachine::stepwiseProcess() + { + map<int, State>::iterator it = mStates.find(mCurrentState); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", mCurrentState); + return; + } + State& state = it->second; + for (int i = 0; i < state.transitions.size(); ++i) + { + Conditions conditions = state.transitions[i].conditions; + bool isActive = true; + for (int j = 0; j < conditions.conditions.size(); ++j) + { + isActive &= processCondition(conditions.conditions[j]); + if (!isActive) + break; + } + if (isActive) + { + // Traslate + mCurrentState = state.transitions[i].state; + invokeCallback(state.name, mCurrentState); + break; + } + } + // Call update + if (mUpdateCallback != nullptr) + mUpdateCallback(mCurrentState, mUserData); + map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); + if (uit != mOnUpdateState.end()) + uit->second(mUserData); + } + + void StateMachine::iterativeProcess() + { + map<int, State>::iterator it = mStates.find(mCurrentState); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", mCurrentState); + return; + } + State& state = it->second; + bool isActive = true; + for (int i = 0; i < state.transitions.size(); ++i) + { + Conditions conditions = state.transitions[i].conditions; + isActive = true; + for (int j = 0; j < conditions.conditions.size(); ++j) + { + isActive &= processCondition(conditions.conditions[j]); + if (!isActive) + break; + } + if (isActive) + { + // Traslate + mCurrentState = state.transitions[i].state; + invokeCallback(state.name, mCurrentState); + break; + } + } + // Call update + if (mUpdateCallback != nullptr) + mUpdateCallback(mCurrentState, mUserData); + map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); + if (uit != mOnUpdateState.end()) + uit->second(mUserData); + // Recursive. + if(isActive) + return iterativeProcess(); + } + + void StateMachine::setMode(Mode mode) + { + mMode = mode; + } + + void StateMachine::update() + { + switch (mMode) + { + case Mode::Iterative: iterativeProcess(); break; + case Mode::Stepwise: stepwiseProcess(); break; + } + } + + bool StateMachine::processCondition(const Condition& condition) + { + map<int, Parameter>::iterator it = mParameters.find(condition.parameter); + if (it == mParameters.end()) + { + jin_log_error("The parameter <%d> is not exist", condition.parameter); + return false; + } + Parameter& p = it->second; + switch (p.type) + { + case ParameterType::Int: + { + int value = p.value._int; + int cvalue = condition.value._int; + bool is = false; + is |= ((condition.expression & ParameterExpression::INT_GREATER) ? value > cvalue : false); + is |= ((condition.expression & ParameterExpression::INT_EQUAL) ? value == cvalue : false); + is |= ((condition.expression & ParameterExpression::INT_LESS) ? value < cvalue : false); + return is; + } + case ParameterType::Float: + { + float value = p.value._float; + float cvalue = condition.value._float; + bool is = false; + is |= ((condition.expression & ParameterExpression::FLOAT_GREATER) ? value > cvalue : false); + is |= ((condition.expression & ParameterExpression::FLOAT_EQUAL) ? value == cvalue : false); + is |= ((condition.expression & ParameterExpression::FLOAT_LESS) ? value < cvalue : false); + return is; + } + case ParameterType::Bool: + { + bool value = p.value._bool; + bool cvalue = condition.value._bool; + bool is = false; + is |= ((condition.expression & ParameterExpression::BOOL_IS) ? value == cvalue : false); + is |= ((condition.expression & ParameterExpression::BOOL_NOT) ? value != cvalue : false); + return is; + } + case ParameterType::Trigger: + { + bool is = p.value._trigger; + // Close trigger. + p.value._trigger = false; + return is; + } + } + return false; + } + + int StateMachine::getCurrentState() + { + return mCurrentState; + } + + void StateMachine::addParameteri(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Int; + p.value._int = 0; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addParameterf(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Float; + p.value._float = 0.0f; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addParameterb(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Bool; + p.value._bool = false; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addParametert(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Trigger; + p.value._trigger = false; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addState(int name) + { + if (mStates.find(name) != mStates.end()) + { + jin_log_error("The state [%d] is already exist.", name); + return; + } + State state; + state.name = name; + mStates.insert(pair<int, State>(name, state)); + } + + const char* StateMachine::parameterTypeString(ParameterType type) + { + switch (type) + { + case ParameterType::Int: return "int"; + case ParameterType::Float: return "float"; + case ParameterType::Bool: return "bool"; + case ParameterType::Trigger: return "trigger"; + } + } + + void StateMachine::addTransition(int from, int to, const Conditions& conditions) + { + map<int, State>::iterator it; + it = mStates.find(from); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", from); + return; + } + State& fromState = it->second; + it = mStates.find(to); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", to); + return; + } + // Check condtion correctness. + for (int i = 0; i < conditions.conditions.size(); ++i) + { + const Condition& condition = conditions.conditions[i]; + map<int, Parameter>::iterator itp; + itp = mParameters.find(condition.parameter); + if (itp == mParameters.end()) + { + jin_log_error("The parameter <%d> is not exist.", condition.parameter); + return; + } + Parameter& p = itp->second; + if (p.type != condition.type) + { + jin_log_error("The type of parameter <%d> is a %s, but the transition gives a %s value." + , condition.parameter, parameterTypeString(p.type), parameterTypeString(condition.type)); + return; + } + } + // Add transition. + Transition transition; + transition.conditions = conditions; + transition.state = to; + fromState.transitions.push_back(transition); + } + + void StateMachine::setParameteri(int name, int value) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state [%d] is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Int) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a int value to it", name, parameterTypeString(p.type)); + return; + } + p.value._int = value; + } + + void StateMachine::setParameterf(int name, float value) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state [%d] is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Float) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a float value to it", name, parameterTypeString(p.type)); + return; + } + p.value._float = value; + } + + void StateMachine::setParameterb(int name, bool value) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state %s is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Bool) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a bool value to it", name, parameterTypeString(p.type)); + return; + } + p.value._bool = value; + } + + void StateMachine::setParametert(int name) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state %s is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Trigger) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a trigger value to it", name, parameterTypeString(p.type)); + return; + } + p.value._trigger = true; + } + + void StateMachine::forceToState(int name) + { + if (mStates.find(name) == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", name); + return; + } + mCurrentState = name; + } + + void StateMachine::addEnterListener(int state, const StateChangeCallback& callback) + { + if (mOnEnterState.find(state) != mOnEnterState.end()) + { + jin_log_error("The enter listener of [%d] is already exist.", state); + return; + } + mOnEnterState.insert(pair<int, StateChangeCallback>(state, callback)); + } + + void StateMachine::addUpdateListener(int state, const StateUpdateCallback& callback) + { + if (mOnUpdateState.find(state) != mOnUpdateState.end()) + { + jin_log_error("The update listener of [%d] is already exist.", state); + return; + } + mOnUpdateState.insert(pair<int, StateUpdateCallback>(state, callback)); + } + + void StateMachine::addExitListener(int state, const StateChangeCallback& callback) + { + if (mOnExitState.find(state) != mOnExitState.end()) + { + jin_log_error("The exit listener of [%d] is already exist.", state); + return; + } + mOnExitState.insert(pair<int, StateChangeCallback>(state, callback)); + } + + void StateMachine::addTranslateListener(int from, int to, const StateChangeCallback& callback) + { + if (mOnStateTranslate.find(pair<int, int>(from, to)) != mOnStateTranslate.end()) + { + jin_log_error("The traslate listener of [%d] to [%d] is already exist.", from, to); + return; + } + pair<int, int> key(from, to); + mOnStateTranslate.insert(pair<pair<int, int>, StateTranslateCallback>(key, callback)); + } + + void StateMachine::setUpdateListener(const SingleStateCallback& callback) + { + mUpdateCallback = callback; + } + + void StateMachine::setEnterListener(const SingleStateCallback& callback) + { + mEnterCallback = callback; + } + + void StateMachine::setExitListener(const SingleStateCallback& callback) + { + mExitCallback = callback; + } + + void StateMachine::setTranslateListener(const DoubleStateCallback& callback) + { + mTraslateCallback = callback; + } + + } // namespace AI } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/ai/state_machine.h b/src/libjin/ai/state_machine.h index d70563d..151853c 100644 --- a/src/libjin/ai/state_machine.h +++ b/src/libjin/ai/state_machine.h @@ -14,399 +14,399 @@ namespace JinEngine { - namespace AI - { - - /// - /// A single layer statemachine. - /// - class StateMachine : public Object - { - public: - /// - /// - /// - enum ParameterExpression - { - INT_GREATER = 0x02, - INT_LESS = 0x04, - INT_EQUAL = 0x08, - - FLOAT_GREATER = 0x10, - FLOAT_LESS = 0x20, - FLOAT_EQUAL = 0x40, - - BOOL_IS = 0x80, - BOOL_NOT = 0x100, - }; - - private: - /// - /// - /// - enum ParameterType - { - Int, ///< A integer value. - Float, ///< A float value. - Bool, ///< A bool value. - Trigger ///< A trigger will be reset to false after activated. - }; - - /// - /// - /// - union ParameterValue - { - int _int; ///< 0 by default. - float _float; ///< 0 by default. - bool _bool; ///< false by default. - bool _trigger; ///< false by default. - }; - - /// - /// Traslation's condition. - /// - struct Condition - { - int parameter; - ParameterExpression expression; - ParameterType type; - ParameterValue value; - }; - - public: - /// - /// - /// - enum Mode - { - Iterative, ///< Process until reach condition failed.(May cause endless loop) - Stepwise ///< Process one state each update. - }; - - struct Conditions : Temporary - { - Conditions() - { - } - - Conditions(const Conditions& condition) - { - conditions = condition.conditions; - } - - void operator = (const Conditions& condition) - { - conditions = condition.conditions; - } - - inline Conditions& andi(int parameter, ParameterExpression expression, int value) - { - Condition condition; - condition.expression = expression; - condition.parameter = parameter; - condition.value._int = value; - condition.type = ParameterType::Int; - conditions.push_back(condition); - return *this; - } - - inline Conditions& andf(int parameter, ParameterExpression expression , float value) - { - Condition condition; - condition.expression = expression; - condition.parameter = parameter; - condition.value._int = value; - condition.type = ParameterType::Float; - conditions.push_back(condition); - return *this; - } - - inline Conditions& andb(int parameter, ParameterExpression expression, bool value) - { - Condition condition; - condition.expression = expression; - condition.parameter = parameter; - condition.value._int = value; - condition.type = ParameterType::Bool; - conditions.push_back(condition); - return *this; - } - - inline Conditions& andt(int parameter) - { - Condition condition; - condition.parameter = parameter; - condition.type = ParameterType::Trigger; - conditions.push_back(condition); - return *this; - } - - private: - friend class StateMachine; - std::vector<Condition> conditions; - }; - - /// - /// - /// - typedef std::function<void(void*)> StateChangeCallback; - - /// - /// - /// - typedef std::function<void(void*)> StateUpdateCallback; - - /// - /// - /// - typedef std::function<void(void*)> StateTranslateCallback; - - /// - /// - /// - typedef std::function<void(int, void*)> SingleStateCallback; - - /// - /// - /// - typedef std::function<void(int, const int, void*)> DoubleStateCallback; - - /// - /// State machine constructor. - /// - StateMachine(Mode mode = Mode::Stepwise, void* userdata = nullptr); - - /// - /// State machine destructor. - /// - ~StateMachine(); - - /// - /// - /// - void setMode(Mode mode); - - /// - /// Process current state.. - /// - void update(); - - /// - /// Get current state name. - /// - int getCurrentState(); - - /// - /// Add a integer parameter. - /// - void addParameteri(int name); - - /// - /// - /// - void addParameterf(int name); - - /// - /// - /// - void addParameterb(int name); - - /// - /// - /// - void addParametert(int name); - - /// - /// Add a state. - /// - void addState(int name); - - /// - /// - /// - void addTransition(int from, int to, const Conditions& conditions); - - /// - /// Set parameter value. - /// - void setParameteri(int name, int value); - - /// - /// Set parameter value. - /// - void setParameterf(int name, float value); - - /// - /// Set parameter value. - /// - void setParameterb(int name, bool value); - - /// - /// Set parameter value. - /// - void setParametert(int name); - - /// - /// Force change to state. - /// - void forceToState(int name); - - /// - /// - /// - void addEnterListener(int state, const StateChangeCallback& callback); - - /// - /// Call state update function. - /// - void addUpdateListener(int state, const StateUpdateCallback& callback); - - /// - /// - /// - void addExitListener(int state, const StateChangeCallback& callback); - - /// - /// - /// - void addTranslateListener(int from, int to, const StateChangeCallback& callback); - - /// - /// - /// - void setEnterListener(const SingleStateCallback& callback); - - /// - /// - /// - void setUpdateListener(const SingleStateCallback& callback); - - /// - /// - /// - void setExitListener(const SingleStateCallback& callback); - - /// - /// - /// - void setTranslateListener(const DoubleStateCallback& callback); - - private: - - /// - /// - /// - struct Parameter - { - ParameterType type; - ParameterValue value; - }; - - /// - /// Translate to another state. - /// - struct Transition - { - Conditions conditions; ///< Condition to active transition. - int state; ///< State to translate to. - }; - - /// - /// A single state. - /// - struct State - { - int name; ///< Name of state. - std::vector<Transition> transitions; ///< All transitions this state have. - }; - - const char* parameterTypeString(ParameterType type); - - /// - /// Check if condition is full filled. - /// - /// @param condition Condition to check. - /// - bool processCondition(const Condition& condition); - - /// - /// - /// - void stepwiseProcess(); - - /// - /// - /// - void iterativeProcess(); - - /// - /// - /// - void invokeCallback(int from, int to); - - /// - /// All state this state machine keeps. - /// - std::map<int, State> mStates; - - /// - /// - /// - std::map<int, StateChangeCallback> mOnEnterState; - - /// - /// - /// - std::map<int, StateUpdateCallback> mOnUpdateState; - - /// - /// - /// - std::map<int, StateChangeCallback> mOnExitState; - - /// - /// From first to second. - /// - std::map<std::pair<int, int>, StateTranslateCallback> mOnStateTranslate; - - /// - /// - /// - SingleStateCallback mEnterCallback; - - /// - /// - /// - SingleStateCallback mUpdateCallback; - - /// - /// - /// - SingleStateCallback mExitCallback; - - /// - /// - /// - DoubleStateCallback mTraslateCallback; - - /// - /// Current state. - /// - int mCurrentState; - - /// - /// All parameters. - /// - std::map<int, Parameter> mParameters; - - Mode mMode; - - void* const mUserData; - - }; - - } // namespace Graphics + namespace AI + { + + /// + /// A single layer statemachine. + /// + class StateMachine : public Object + { + public: + /// + /// + /// + enum ParameterExpression + { + INT_GREATER = 0x02, + INT_LESS = 0x04, + INT_EQUAL = 0x08, + + FLOAT_GREATER = 0x10, + FLOAT_LESS = 0x20, + FLOAT_EQUAL = 0x40, + + BOOL_IS = 0x80, + BOOL_NOT = 0x100, + }; + + private: + /// + /// + /// + enum ParameterType + { + Int, ///< A integer value. + Float, ///< A float value. + Bool, ///< A bool value. + Trigger ///< A trigger will be reset to false after activated. + }; + + /// + /// + /// + union ParameterValue + { + int _int; ///< 0 by default. + float _float; ///< 0 by default. + bool _bool; ///< false by default. + bool _trigger; ///< false by default. + }; + + /// + /// Traslation's condition. + /// + struct Condition + { + int parameter; + ParameterExpression expression; + ParameterType type; + ParameterValue value; + }; + + public: + /// + /// + /// + enum Mode + { + Iterative, ///< Process until reach condition failed.(May cause endless loop) + Stepwise ///< Process one state each update. + }; + + struct Conditions : Temporary + { + Conditions() + { + } + + Conditions(const Conditions& condition) + { + conditions = condition.conditions; + } + + void operator = (const Conditions& condition) + { + conditions = condition.conditions; + } + + inline Conditions& andi(int parameter, ParameterExpression expression, int value) + { + Condition condition; + condition.expression = expression; + condition.parameter = parameter; + condition.value._int = value; + condition.type = ParameterType::Int; + conditions.push_back(condition); + return *this; + } + + inline Conditions& andf(int parameter, ParameterExpression expression , float value) + { + Condition condition; + condition.expression = expression; + condition.parameter = parameter; + condition.value._int = value; + condition.type = ParameterType::Float; + conditions.push_back(condition); + return *this; + } + + inline Conditions& andb(int parameter, ParameterExpression expression, bool value) + { + Condition condition; + condition.expression = expression; + condition.parameter = parameter; + condition.value._int = value; + condition.type = ParameterType::Bool; + conditions.push_back(condition); + return *this; + } + + inline Conditions& andt(int parameter) + { + Condition condition; + condition.parameter = parameter; + condition.type = ParameterType::Trigger; + conditions.push_back(condition); + return *this; + } + + private: + friend class StateMachine; + std::vector<Condition> conditions; + }; + + /// + /// + /// + typedef std::function<void(void*)> StateChangeCallback; + + /// + /// + /// + typedef std::function<void(void*)> StateUpdateCallback; + + /// + /// + /// + typedef std::function<void(void*)> StateTranslateCallback; + + /// + /// + /// + typedef std::function<void(int, void*)> SingleStateCallback; + + /// + /// + /// + typedef std::function<void(int, const int, void*)> DoubleStateCallback; + + /// + /// State machine constructor. + /// + StateMachine(Mode mode = Mode::Stepwise, void* userdata = nullptr); + + /// + /// State machine destructor. + /// + ~StateMachine(); + + /// + /// + /// + void setMode(Mode mode); + + /// + /// Process current state.. + /// + void update(); + + /// + /// Get current state name. + /// + int getCurrentState(); + + /// + /// Add a integer parameter. + /// + void addParameteri(int name); + + /// + /// + /// + void addParameterf(int name); + + /// + /// + /// + void addParameterb(int name); + + /// + /// + /// + void addParametert(int name); + + /// + /// Add a state. + /// + void addState(int name); + + /// + /// + /// + void addTransition(int from, int to, const Conditions& conditions); + + /// + /// Set parameter value. + /// + void setParameteri(int name, int value); + + /// + /// Set parameter value. + /// + void setParameterf(int name, float value); + + /// + /// Set parameter value. + /// + void setParameterb(int name, bool value); + + /// + /// Set parameter value. + /// + void setParametert(int name); + + /// + /// Force change to state. + /// + void forceToState(int name); + + /// + /// + /// + void addEnterListener(int state, const StateChangeCallback& callback); + + /// + /// Call state update function. + /// + void addUpdateListener(int state, const StateUpdateCallback& callback); + + /// + /// + /// + void addExitListener(int state, const StateChangeCallback& callback); + + /// + /// + /// + void addTranslateListener(int from, int to, const StateChangeCallback& callback); + + /// + /// + /// + void setEnterListener(const SingleStateCallback& callback); + + /// + /// + /// + void setUpdateListener(const SingleStateCallback& callback); + + /// + /// + /// + void setExitListener(const SingleStateCallback& callback); + + /// + /// + /// + void setTranslateListener(const DoubleStateCallback& callback); + + private: + + /// + /// + /// + struct Parameter + { + ParameterType type; + ParameterValue value; + }; + + /// + /// Translate to another state. + /// + struct Transition + { + Conditions conditions; ///< Condition to active transition. + int state; ///< State to translate to. + }; + + /// + /// A single state. + /// + struct State + { + int name; ///< Name of state. + std::vector<Transition> transitions; ///< All transitions this state have. + }; + + const char* parameterTypeString(ParameterType type); + + /// + /// Check if condition is full filled. + /// + /// @param condition Condition to check. + /// + bool processCondition(const Condition& condition); + + /// + /// + /// + void stepwiseProcess(); + + /// + /// + /// + void iterativeProcess(); + + /// + /// + /// + void invokeCallback(int from, int to); + + /// + /// All state this state machine keeps. + /// + std::map<int, State> mStates; + + /// + /// + /// + std::map<int, StateChangeCallback> mOnEnterState; + + /// + /// + /// + std::map<int, StateUpdateCallback> mOnUpdateState; + + /// + /// + /// + std::map<int, StateChangeCallback> mOnExitState; + + /// + /// From first to second. + /// + std::map<std::pair<int, int>, StateTranslateCallback> mOnStateTranslate; + + /// + /// + /// + SingleStateCallback mEnterCallback; + + /// + /// + /// + SingleStateCallback mUpdateCallback; + + /// + /// + /// + SingleStateCallback mExitCallback; + + /// + /// + /// + DoubleStateCallback mTraslateCallback; + + /// + /// Current state. + /// + int mCurrentState; + + /// + /// All parameters. + /// + std::map<int, Parameter> mParameters; + + Mode mMode; + + void* const mUserData; + + }; + + } // namespace Graphics } // namespace JinEngine #endif // jin_ai diff --git a/src/libjin/audio/SDL/sdl_audio.cpp b/src/libjin/audio/SDL/sdl_audio.cpp index 4c4bcc2..1592599 100644 --- a/src/libjin/audio/SDL/sdl_audio.cpp +++ b/src/libjin/audio/SDL/sdl_audio.cpp @@ -13,134 +13,134 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Audio - { - namespace SDL - { - - /* עcallbackƵ̵߳ */ - static void defaultCallback(void *userdata, Uint8 *stream, int size) - { - static SDLAudio* audio = static_cast<SDLAudio*>(userdata); - if (!audio->goOnProcess()) - return; - audio->lock(); - audio->processCommands(); - audio->processSources(stream, size); - audio->processBuffer(stream, size); - audio->unlock(); - } - - /*call only once*/ bool SDLAudio::startSystem(const SettingBase* s) - { - jin_log_info("Initialize audio system."); - - if (SDL_Init(SDL_INIT_AUDIO) < 0) - return false; - - SDL_AudioSpec spec; - Setting* setting = (Setting*)s; - if (setting == nullptr) - return false; - - unsigned int samplerate = setting->samplerate; - unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate); - - spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz. - spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order - spec.channels = SDLAUDIO_CHANNELS; // - spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1 - spec.userdata = this; - spec.callback = defaultCallback; - - audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0); - if (audioDevice == 0) - return false; - /* start audio */ - SDL_PauseAudioDevice(audioDevice, 0); - return true; - } - - /*call only once*/ void SDLAudio::quitSystem() - { - jin_log_info("Quit audio system."); - SDL_CloseAudio(); - } - - void SDLAudio::lock() - { - SDL_LockAudioDevice(audioDevice); - } - - void SDLAudio::unlock() - { - SDL_UnlockAudioDevice(audioDevice); - } - - bool SDLAudio::goOnProcess() - { - if (state == SDLAudio::State::STOP) - { - SDLSourceManager::get()->removeAllSource(); - pause(); - return false; - } - else if (state == SDLAudio::State::PAUSE) - return false; - else - return true; - } - - void SDLAudio::processCommands() - { - SDLSourceManager::get()->processCommands(); - } - - void SDLAudio::processSources(void* buffer, size_t len) - { - SDLSourceManager::get()->processSources(buffer, len); - } - - void SDLAudio::processBuffer(void* buff, size_t len) - { - short* buffer = (short*)buff; - int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ - const char L = 0, R = 1; - for (int i = 0; i < samples; ++i) - { - short* clip = buffer + (i << 1); - clip[L] *= volume; - clip[R] *= volume; - } - } - - void SDLAudio::play() - { - state = State::PLAY; - } - - void SDLAudio::stop() - { - state = State::STOP; - } - - void SDLAudio::pause() - { - state = State::PAUSE; - } - - void SDLAudio::resume() - { - state = State::PLAY; - } - - void SDLAudio::setVolume(float volume) - { - this->volume = clamp(volume, 0.0f, 1.0f); - } - - } // namespace SDL - } // namespace Audio + namespace Audio + { + namespace SDL + { + + /* עcallbackƵ̵߳ */ + static void defaultCallback(void *userdata, Uint8 *stream, int size) + { + static SDLAudio* audio = static_cast<SDLAudio*>(userdata); + if (!audio->goOnProcess()) + return; + audio->lock(); + audio->processCommands(); + audio->processSources(stream, size); + audio->processBuffer(stream, size); + audio->unlock(); + } + + /*call only once*/ bool SDLAudio::startSystem(const SettingBase* s) + { + jin_log_info("Initialize audio system."); + + if (SDL_Init(SDL_INIT_AUDIO) < 0) + return false; + + SDL_AudioSpec spec; + Setting* setting = (Setting*)s; + if (setting == nullptr) + return false; + + unsigned int samplerate = setting->samplerate; + unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate); + + spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz. + spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order + spec.channels = SDLAUDIO_CHANNELS; // + spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1 + spec.userdata = this; + spec.callback = defaultCallback; + + audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0); + if (audioDevice == 0) + return false; + /* start audio */ + SDL_PauseAudioDevice(audioDevice, 0); + return true; + } + + /*call only once*/ void SDLAudio::quitSystem() + { + jin_log_info("Quit audio system."); + SDL_CloseAudio(); + } + + void SDLAudio::lock() + { + SDL_LockAudioDevice(audioDevice); + } + + void SDLAudio::unlock() + { + SDL_UnlockAudioDevice(audioDevice); + } + + bool SDLAudio::goOnProcess() + { + if (state == SDLAudio::State::STOP) + { + SDLSourceManager::get()->removeAllSource(); + pause(); + return false; + } + else if (state == SDLAudio::State::PAUSE) + return false; + else + return true; + } + + void SDLAudio::processCommands() + { + SDLSourceManager::get()->processCommands(); + } + + void SDLAudio::processSources(void* buffer, size_t len) + { + SDLSourceManager::get()->processSources(buffer, len); + } + + void SDLAudio::processBuffer(void* buff, size_t len) + { + short* buffer = (short*)buff; + int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ + const char L = 0, R = 1; + for (int i = 0; i < samples; ++i) + { + short* clip = buffer + (i << 1); + clip[L] *= volume; + clip[R] *= volume; + } + } + + void SDLAudio::play() + { + state = State::PLAY; + } + + void SDLAudio::stop() + { + state = State::STOP; + } + + void SDLAudio::pause() + { + state = State::PAUSE; + } + + void SDLAudio::resume() + { + state = State::PLAY; + } + + void SDLAudio::setVolume(float volume) + { + this->volume = clamp(volume, 0.0f, 1.0f); + } + + } // namespace SDL + } // namespace Audio } // namespace JinEngine #endif // (jin_audio) && (jin_audio == jin_audio_sdl)
\ No newline at end of file diff --git a/src/libjin/audio/SDL/sdl_audio.h b/src/libjin/audio/SDL/sdl_audio.h index 4808118..8adbd18 100644 --- a/src/libjin/audio/SDL/sdl_audio.h +++ b/src/libjin/audio/SDL/sdl_audio.h @@ -11,124 +11,124 @@ namespace JinEngine { - namespace Audio - { - namespace SDL - { + namespace Audio + { + namespace SDL + { #define SDLAUDIO_BITDEPTH 16 #define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3) #define SDLAUDIO_CHANNELS 2 - /// - /// Audio system SDL implementation. - /// - class SDLAudio : public AudioManager<SDLAudio> - { - public: - /// - /// SDL audio setting. - /// - struct Setting : SettingBase - { - public: - int samplerate; // Ƶ - int samples; // sample<=samplerate - }; - - /// - /// SDL audio constructor. - /// - SDLAudio() {}; - - /// - /// SDL audio destructor. - /// - ~SDLAudio() {}; - - /// - /// Play all sources whose state is playing. - /// - void play() override; - - /// - /// Stop and remove all sources from the queue. - /// - void stop() override; - - /// - /// Pause audio. - /// - void pause() override; - - /// - /// Resume audio. - /// - void resume() override; - - /// - /// Set global audio volume. - /// - void setVolume(float volume) override; - - /// - /// Process all commands in the queue. - /// - void processCommands(); - - /// - /// Process all sources. - /// - /// @param buffer Source buffer. - /// @param len Source length. - /// - void processSources(void* buffer, size_t len); - - /// - /// Process audio buffer. - /// - /// @param buffer Audio stream buffer. - /// @param len Length of stream buffer. - /// - void processBuffer(void* buffer, size_t len); - - /// - /// Goon process. - /// - /// @return True if sucessful, otherwise return false. - /// - bool goOnProcess(); - - /// - /// Lock audio device. - /// - void lock(); - - /// - /// Unlock audio device. - /// - void unlock(); - - private: - /// - /// Initialize audio system. - /// - /// @param setting Audio setting. - /// - bool startSystem(const SettingBase* setting) override; - - /// - /// Quit audio system. - /// - void quitSystem() override; - - // Audio device id. - unsigned int audioDevice; - - }; - - } // namespace SDL - } // namespace Audio + /// + /// Audio system SDL implementation. + /// + class SDLAudio : public AudioManager<SDLAudio> + { + public: + /// + /// SDL audio setting. + /// + struct Setting : SettingBase + { + public: + int samplerate; // Ƶ + int samples; // sample<=samplerate + }; + + /// + /// SDL audio constructor. + /// + SDLAudio() {}; + + /// + /// SDL audio destructor. + /// + ~SDLAudio() {}; + + /// + /// Play all sources whose state is playing. + /// + void play() override; + + /// + /// Stop and remove all sources from the queue. + /// + void stop() override; + + /// + /// Pause audio. + /// + void pause() override; + + /// + /// Resume audio. + /// + void resume() override; + + /// + /// Set global audio volume. + /// + void setVolume(float volume) override; + + /// + /// Process all commands in the queue. + /// + void processCommands(); + + /// + /// Process all sources. + /// + /// @param buffer Source buffer. + /// @param len Source length. + /// + void processSources(void* buffer, size_t len); + + /// + /// Process audio buffer. + /// + /// @param buffer Audio stream buffer. + /// @param len Length of stream buffer. + /// + void processBuffer(void* buffer, size_t len); + + /// + /// Goon process. + /// + /// @return True if sucessful, otherwise return false. + /// + bool goOnProcess(); + + /// + /// Lock audio device. + /// + void lock(); + + /// + /// Unlock audio device. + /// + void unlock(); + + private: + /// + /// Initialize audio system. + /// + /// @param setting Audio setting. + /// + bool startSystem(const SettingBase* setting) override; + + /// + /// Quit audio system. + /// + void quitSystem() override; + + // Audio device id. + unsigned int audioDevice; + + }; + + } // namespace SDL + } // namespace Audio } // namespace JinEngine #endif // (jin_audio) && (jin_audio == jin_audio_sdl) diff --git a/src/libjin/audio/SDL/sdl_source.cpp b/src/libjin/audio/SDL/sdl_source.cpp index eae3eec..68e66c4 100644 --- a/src/libjin/audio/SDL/sdl_source.cpp +++ b/src/libjin/audio/SDL/sdl_source.cpp @@ -19,376 +19,376 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Audio - { - namespace SDL - { + namespace Audio + { + namespace SDL + { #define BITS 8 - typedef struct SDLSourceCommand - { - typedef enum Action - { - Nothing = 0, - Play, - Stop, - Pause, - Resume, - Rewind, - SetVolume, - SetLoop, - SetRate, - }; - Action action; - union { - int _integer; - float _float; - bool _boolean; - const char* _string; - } parameter; - - SDLSource* source; - }; - - typedef enum CHANNEL - { - MONO = 1, // - STEREO = 2, // - }; - - typedef /*mask*/ enum STATUS - { - PLAYING = 1, - PAUSED = 2, - STOPPED = 4 - }; + typedef struct SDLSourceCommand + { + typedef enum Action + { + Nothing = 0, + Play, + Stop, + Pause, + Resume, + Rewind, + SetVolume, + SetLoop, + SetRate, + }; + Action action; + union { + int _integer; + float _float; + bool _boolean; + const char* _string; + } parameter; + + SDLSource* source; + }; + + typedef enum CHANNEL + { + MONO = 1, // + STEREO = 2, // + }; + + typedef /*mask*/ enum STATUS + { + PLAYING = 1, + PAUSED = 2, + STOPPED = 4 + }; #define Command SDLSourceCommand #define Action Command::Action #define Manager SDLSourceManager - //std::queue<Command*> Manager::commands; - //std::stack<Command*> Manager::commandsPool; - //std::vector<SDLSource*> Manager::sources; - Manager* Manager::manager = nullptr; - - SDLSource::SDLSource() - { - memset(&status, 0, sizeof(status)); - memset(&raw, 0, sizeof(raw)); - status.volume = 1; - } - - SDLSource::SDLSource(const char* file) - : SDLSource() - { - std::ifstream fs; - fs.open(file, std::ios::binary); - if (!fs.is_open()) - { - fs.close(); - return; - } - fs.seekg(0, std::ios::end); - int size = fs.tellg(); - fs.seekg(0, std::ios::beg); - char* buffer = (char*)malloc(size); - memset(buffer, 0, size); - fs.read(buffer, size); - fs.close(); - SDLSource(buffer, size); - free(buffer); - } - - SDLSource::SDLSource(void* mem, size_t size) - : SDLSource() - { - if (mem == nullptr) - return; - SourceType format = getType(mem, size); - switch (format) - { - case OGG: decode_ogg(mem, size); break; - case WAV: decode_wav(mem, size); break; - } - } - - SDLSource::~SDLSource() - { - delete raw.data; - raw.end = 0; - raw.data = 0; - } - - void SDLSource::decode_wav(void* mem, int size) - { - wav_t wav; - if (wav_read(&wav, mem, size) == 0) - { - raw.data = wav.data; - raw.length = wav.length * wav.channels * wav.bitdepth / 8; - raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO); - raw.end = (char*)raw.data + raw.length; - raw.samplerate = wav.samplerate; - raw.bitdepth = wav.bitdepth; - raw.samples = wav.length; - } - else - throw SourceException(); - } - - void SDLSource::decode_ogg(void* _mem, int size) - { - unsigned char* mem = (unsigned char*)_mem; - int channels; - int samplerate; - short* data = (short*)raw.data; - int samples = stb_vorbis_decode_memory( - mem, - size, - &channels, - &samplerate, - &data - ); - const int bitdepth = sizeof(short) * BITS; - raw.channels = channels; - raw.samplerate = samplerate; - raw.data = data; - raw.samples = samples; // һsample - raw.length = samples * channels * sizeof(short); // һsample - raw.bitdepth = bitdepth; - raw.end = (char*)data + raw.length; - } + //std::queue<Command*> Manager::commands; + //std::stack<Command*> Manager::commandsPool; + //std::vector<SDLSource*> Manager::sources; + Manager* Manager::manager = nullptr; + + SDLSource::SDLSource() + { + memset(&status, 0, sizeof(status)); + memset(&raw, 0, sizeof(raw)); + status.volume = 1; + } + + SDLSource::SDLSource(const char* file) + : SDLSource() + { + std::ifstream fs; + fs.open(file, std::ios::binary); + if (!fs.is_open()) + { + fs.close(); + return; + } + fs.seekg(0, std::ios::end); + int size = fs.tellg(); + fs.seekg(0, std::ios::beg); + char* buffer = (char*)malloc(size); + memset(buffer, 0, size); + fs.read(buffer, size); + fs.close(); + SDLSource(buffer, size); + free(buffer); + } + + SDLSource::SDLSource(void* mem, size_t size) + : SDLSource() + { + if (mem == nullptr) + return; + SourceType format = getType(mem, size); + switch (format) + { + case OGG: decode_ogg(mem, size); break; + case WAV: decode_wav(mem, size); break; + } + } + + SDLSource::~SDLSource() + { + delete raw.data; + raw.end = 0; + raw.data = 0; + } + + void SDLSource::decode_wav(void* mem, int size) + { + wav_t wav; + if (wav_read(&wav, mem, size) == 0) + { + raw.data = wav.data; + raw.length = wav.length * wav.channels * wav.bitdepth / 8; + raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO); + raw.end = (char*)raw.data + raw.length; + raw.samplerate = wav.samplerate; + raw.bitdepth = wav.bitdepth; + raw.samples = wav.length; + } + else + throw SourceException(); + } + + void SDLSource::decode_ogg(void* _mem, int size) + { + unsigned char* mem = (unsigned char*)_mem; + int channels; + int samplerate; + short* data = (short*)raw.data; + int samples = stb_vorbis_decode_memory( + mem, + size, + &channels, + &samplerate, + &data + ); + const int bitdepth = sizeof(short) * BITS; + raw.channels = channels; + raw.samplerate = samplerate; + raw.data = data; + raw.samples = samples; // һsample + raw.length = samples * channels * sizeof(short); // һsample + raw.bitdepth = bitdepth; + raw.end = (char*)data + raw.length; + } #define ActionNone(T)\ - do{\ - Command* cmd = Manager::get()->getCommand();\ - cmd->action = Action::T; \ - cmd->source = this; \ - Manager::get()->pushCommand(cmd); \ - } while (0) + do{\ + Command* cmd = Manager::get()->getCommand();\ + cmd->action = Action::T; \ + cmd->source = this; \ + Manager::get()->pushCommand(cmd); \ + } while (0) #define ActionArg(T, ARGT, ARG)\ - do{\ - Command* cmd = Manager::get()->getCommand();\ - cmd->action = Action::T; \ - cmd->parameter.ARGT = ARG; \ - cmd->source = this; \ - Manager::get()->pushCommand(cmd); \ - }while(0) - -#define ActionInt(T, INT) ActionArg(T, _integer, INT) + do{\ + Command* cmd = Manager::get()->getCommand();\ + cmd->action = Action::T; \ + cmd->parameter.ARGT = ARG; \ + cmd->source = this; \ + Manager::get()->pushCommand(cmd); \ + }while(0) + +#define ActionInt(T, INT) ActionArg(T, _integer, INT) #define ActionFloat(T, FLT) ActionArg(T, _float, FLT) #define ActionString(T, STR) ActionArg(T, _string, STR) #define ActionBool(T, BOL) ActionArg(T, _boolean, BOL) - void SDLSource::play() - { - ActionNone(Play); - } - - void SDLSource::stop() - { - ActionNone(Stop); - } - - void SDLSource::pause() - { - ActionNone(Pause); - } - - void SDLSource::resume() - { - ActionNone(Resume); - } - - void SDLSource::rewind() - { - ActionNone(Rewind); - } - - inline bool SDLSource::isStopped() const - { - return is(STOPPED); - } - - bool SDLSource::isPaused() const - { - return is(PAUSED); - } - - void SDLSource::setPitch(float pitch) - { - } - - void SDLSource::setVolume(float volume) - { - ActionFloat(SetVolume, clamp(volume, 0.0f, 1.0f)); - } - - void SDLSource::setLoop(bool loop) - { - ActionBool(SetLoop, loop); - } - - void SDLSource::setRate(float rate) - { - ActionFloat(SetRate, rate); - } - - inline void SDLSource::handle( - SDLSourceManager* manager, - SDLSourceCommand* cmd - ) - { - switch (cmd->action) - { - case Command::Action::Play: - manager->removeSource(this); - manager->pushSource(this); - status.state = PLAYING; - status.pos = 0; // rewind - break; - case Command::Action::Stop: - manager->removeSource(this); - status.state = STOPPED; - status.pos = 0; // rewind - break; - case Command::Action::Pause: - manager->removeSource(this); - status.state = PAUSED; - break; - case Command::Action::Resume: - manager->removeSource(this); - manager->pushSource(this); - status.state = PLAYING; - break; - case Command::Action::Rewind: - status.state = PLAYING; - status.pos = 0; - break; - case Command::Action::SetVolume: - status.volume = cmd->parameter._float; - break; - case Command::Action::SetLoop: - status.loop = cmd->parameter._boolean; - break; - } - } - - inline void SDLSource::process(void* buf, size_t size) - { - short* buffer = (short*)buf; // AUDIO_S16SYS - int samples = (size / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ - const char L = 0, R = 1; - for (int i = 0; i < samples; ++i) - { - char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels; - short l = 0; - short r = 0; - if (raw.bitdepth == 16) - { - l = ((short*)source)[L] * status.volume; - r = ((short*)source)[L + raw.channels - 1] * status.volume; - } - else if (raw.bitdepth == 8) - { - l = source[L] << 8; // << 8 Ŵ16bits - r = source[L + raw.channels - 1] << 8; - } - short* sample = buffer + (i << 1); - sample[L] = clamp(sample[L] + l, SHRT_MIN, SHRT_MAX); // - sample[R] = clamp(sample[R] + r, SHRT_MIN, SHRT_MAX); // - ++status.pos; - if (status.pos > raw.samples && status.loop) - status.pos = 0; // rewind - else if (status.pos > raw.samples && !status.loop) - break; - } - } - - Manager* Manager::get() - { - return (manager == nullptr ? manager = new Manager() : manager); - } - - void Manager::processCommands() - { - Command* cmd = nullptr; - SDLSource* source = nullptr; - while (!commands.empty()) - { - cmd = commands.front(); - if (cmd != nullptr) - { - source = cmd->source; - if (source != nullptr) - source->handle(manager, cmd); - } - commands.pop(); - } - } - - /* AUDIO_S16SYS[size>>1] buffer */ - void Manager::processSources(void* buf, size_t size) - { - /* clear render buffer */ - memset(buf, 0, size); - SDLSource* src = nullptr; - std::vector<SDLSource*>::iterator it = sources.begin(); - for (; it != sources.end();) - { - src = *it; - if (src != nullptr) - src->process(buf, size); - ++it; - } - } - - void Manager::removeSource(SDLSource* source) - { - std::vector<SDLSource*>::iterator it = sources.begin(); - for (it = sources.begin(); it != sources.end(); ) - { - if (*it == source) - { - it = sources.erase(it); - return; - } - ++it; - } - } - - void Manager::removeAllSource() - { - sources.clear(); - } - - void Manager::pushSource(SDLSource* source) - { - if (source != nullptr) - sources.push_back(source); - } - - void Manager::pushCommand(SDLSourceCommand* cmd) - { - commands.push(cmd); - } - - Command* Manager::getCommand() - { - if (!commandsPool.empty()) - { - Command* cmd = commandsPool.top(); - commandsPool.pop(); - return cmd; - } - return new Command(); - } - - } // namespace SDL - } // namespace Audio + void SDLSource::play() + { + ActionNone(Play); + } + + void SDLSource::stop() + { + ActionNone(Stop); + } + + void SDLSource::pause() + { + ActionNone(Pause); + } + + void SDLSource::resume() + { + ActionNone(Resume); + } + + void SDLSource::rewind() + { + ActionNone(Rewind); + } + + inline bool SDLSource::isStopped() const + { + return is(STOPPED); + } + + bool SDLSource::isPaused() const + { + return is(PAUSED); + } + + void SDLSource::setPitch(float pitch) + { + } + + void SDLSource::setVolume(float volume) + { + ActionFloat(SetVolume, clamp(volume, 0.0f, 1.0f)); + } + + void SDLSource::setLoop(bool loop) + { + ActionBool(SetLoop, loop); + } + + void SDLSource::setRate(float rate) + { + ActionFloat(SetRate, rate); + } + + inline void SDLSource::handle( + SDLSourceManager* manager, + SDLSourceCommand* cmd + ) + { + switch (cmd->action) + { + case Command::Action::Play: + manager->removeSource(this); + manager->pushSource(this); + status.state = PLAYING; + status.pos = 0; // rewind + break; + case Command::Action::Stop: + manager->removeSource(this); + status.state = STOPPED; + status.pos = 0; // rewind + break; + case Command::Action::Pause: + manager->removeSource(this); + status.state = PAUSED; + break; + case Command::Action::Resume: + manager->removeSource(this); + manager->pushSource(this); + status.state = PLAYING; + break; + case Command::Action::Rewind: + status.state = PLAYING; + status.pos = 0; + break; + case Command::Action::SetVolume: + status.volume = cmd->parameter._float; + break; + case Command::Action::SetLoop: + status.loop = cmd->parameter._boolean; + break; + } + } + + inline void SDLSource::process(void* buf, size_t size) + { + short* buffer = (short*)buf; // AUDIO_S16SYS + int samples = (size / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ + const char L = 0, R = 1; + for (int i = 0; i < samples; ++i) + { + char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels; + short l = 0; + short r = 0; + if (raw.bitdepth == 16) + { + l = ((short*)source)[L] * status.volume; + r = ((short*)source)[L + raw.channels - 1] * status.volume; + } + else if (raw.bitdepth == 8) + { + l = source[L] << 8; // << 8 Ŵ16bits + r = source[L + raw.channels - 1] << 8; + } + short* sample = buffer + (i << 1); + sample[L] = clamp(sample[L] + l, SHRT_MIN, SHRT_MAX); // + sample[R] = clamp(sample[R] + r, SHRT_MIN, SHRT_MAX); // + ++status.pos; + if (status.pos > raw.samples && status.loop) + status.pos = 0; // rewind + else if (status.pos > raw.samples && !status.loop) + break; + } + } + + Manager* Manager::get() + { + return (manager == nullptr ? manager = new Manager() : manager); + } + + void Manager::processCommands() + { + Command* cmd = nullptr; + SDLSource* source = nullptr; + while (!commands.empty()) + { + cmd = commands.front(); + if (cmd != nullptr) + { + source = cmd->source; + if (source != nullptr) + source->handle(manager, cmd); + } + commands.pop(); + } + } + + /* AUDIO_S16SYS[size>>1] buffer */ + void Manager::processSources(void* buf, size_t size) + { + /* clear render buffer */ + memset(buf, 0, size); + SDLSource* src = nullptr; + std::vector<SDLSource*>::iterator it = sources.begin(); + for (; it != sources.end();) + { + src = *it; + if (src != nullptr) + src->process(buf, size); + ++it; + } + } + + void Manager::removeSource(SDLSource* source) + { + std::vector<SDLSource*>::iterator it = sources.begin(); + for (it = sources.begin(); it != sources.end(); ) + { + if (*it == source) + { + it = sources.erase(it); + return; + } + ++it; + } + } + + void Manager::removeAllSource() + { + sources.clear(); + } + + void Manager::pushSource(SDLSource* source) + { + if (source != nullptr) + sources.push_back(source); + } + + void Manager::pushCommand(SDLSourceCommand* cmd) + { + commands.push(cmd); + } + + Command* Manager::getCommand() + { + if (!commandsPool.empty()) + { + Command* cmd = commandsPool.top(); + commandsPool.pop(); + return cmd; + } + return new Command(); + } + + } // namespace SDL + } // namespace Audio } // namespace JinEngine #endif // (jin_audio) && (jin_audio == jin_audio_sdl)
\ No newline at end of file diff --git a/src/libjin/audio/SDL/sdl_source.h b/src/libjin/audio/SDL/sdl_source.h index 967b0c2..ae634cf 100644 --- a/src/libjin/audio/SDL/sdl_source.h +++ b/src/libjin/audio/SDL/sdl_source.h @@ -12,252 +12,252 @@ namespace JinEngine { - namespace Audio - { - namespace SDL - { - - typedef struct SDLSourceCommand; - - class SDLSourceManager; - - /// - /// Audio source SDL implementation. - /// - class SDLSource : public Source - { - public: - /// - /// Source constructor. - /// - SDLSource(); - - /// - /// - /// - SDLSource(const char* file); - - /// - /// - /// - SDLSource(void* mem, size_t size); - - /// - /// Source destructor. - /// - ~SDLSource(); - - /// - /// Play source. - /// - void play() override; - - /// - /// Stop source. - /// - void stop() override; - - /// - /// Pause source. - /// - void pause() override; - - /// - /// Resume source. - /// - void resume() override; - - /// - /// Rewind source. - /// - void rewind() override; - - /// - /// Return if the source is stopped. - /// - /// @return True if the source is stopped, otherwise return false. - /// - bool isStopped() const override; - - /// - /// Return if the source is paused. - /// - /// @return True if the source is paused(, otherwise return false. - /// - bool isPaused() const override; - - /// - /// Set pitch. - /// - /// @param pitch Pitch of source. - /// - void setPitch(float pitch) override; - - /// - /// Set volume. - /// - /// @param volume Volume of source. - /// - void setVolume(float volume) override; - - /// - /// Set source loop. - /// - /// @param loop Looping or not. - /// - void setLoop(bool loop) override; - - /// - /// Set source rate. - /// - /// @param rate Rate of source. - /// - void setRate(float rate) override; - - /// - /// Handle a specific command. - /// - /// @param manager Audio manager. - /// @param cmd Source commad. - /// - inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd); - - /// - /// Process decoded source data. - /// - /// @param buffer Source data. - /// @param size Data size. - /// - inline void process(void* buffer, size_t size); - - protected: - /// - /// Decode wav file. - /// - /// @param mem Wav file data. - /// @param size Wav data size. - /// - void decode_wav(void* mem, int size); - - /// - /// Decode ogg file. - /// - /// @param mem ogg file data. - /// @param size ogg data size. - /// - void decode_ogg(void* mem, int size); - - /// - /// Check source state. - /// - /// @param state State to be checked. - /// @return True if state is given state, otherwise return false. - /// - inline bool is(int state) const - { - return (status.state & state) == state; - } - - // Source data. - struct { - const void* data; // Ƶ - int length; // dataֽڳ - const void* end; // dataβ = (unsigned char*)data + size - int samplerate; // Ƶ - unsigned char bitdepth; // ÿsampleıس - int samples; // sample = size / (bitdepth / 8) - unsigned char channels; // channel1(mono)2(stereo) - } raw; - // Procedure controller variable. - struct { - int pos; // ǰŵsample - int pitch; // pitch - int state; // ǰ״̬ - bool loop; // loop or not - float volume; // - } status; - - }; - - /// - /// Source manager. - /// - class SDLSourceManager : public Object - { - public: - /// - /// Get manager singleton. - /// - /// @return Singleton of SDL source manager. - /// - static SDLSourceManager* get(); - - /// - /// Process commands. - /// - void processCommands(); - - /// - /// Process sources. - /// - /// @param buffer Source data. - /// @param size Size of source data. - /// - void processSources(void* buffer, size_t size); - - /// - /// Clear source queue. - /// - /// This function will stop all sources. - /// - void removeAllSource(); - - /// - /// Remove specific source. - /// - /// @param source SDL audio source. - /// - void removeSource(SDLSource* source); - - /// - /// Push specific source into queue. - /// - /// @param source SDL audio source. - /// - void pushSource(SDLSource* source); - - /// - /// Get command from queue. - /// - /// @return Command at first place. - /// - SDLSourceCommand* getCommand(); - - /// - /// Push command. - /// - /// @param cmd Spcific command. - /// - void pushCommand(SDLSourceCommand* cmd); - - private: - std::queue<SDLSourceCommand*> commands; - std::stack<SDLSourceCommand*> commandsPool; - std::vector<SDLSource*> sources; // processing sources - static SDLSourceManager* manager; - - }; - - class SourceException : public Object, public std::exception - { - const char* what() const throw () - { - return "Load Source Exception"; - } - }; - - } // namespace SDL - } // namespace Audio + namespace Audio + { + namespace SDL + { + + typedef struct SDLSourceCommand; + + class SDLSourceManager; + + /// + /// Audio source SDL implementation. + /// + class SDLSource : public Source + { + public: + /// + /// Source constructor. + /// + SDLSource(); + + /// + /// + /// + SDLSource(const char* file); + + /// + /// + /// + SDLSource(void* mem, size_t size); + + /// + /// Source destructor. + /// + ~SDLSource(); + + /// + /// Play source. + /// + void play() override; + + /// + /// Stop source. + /// + void stop() override; + + /// + /// Pause source. + /// + void pause() override; + + /// + /// Resume source. + /// + void resume() override; + + /// + /// Rewind source. + /// + void rewind() override; + + /// + /// Return if the source is stopped. + /// + /// @return True if the source is stopped, otherwise return false. + /// + bool isStopped() const override; + + /// + /// Return if the source is paused. + /// + /// @return True if the source is paused(, otherwise return false. + /// + bool isPaused() const override; + + /// + /// Set pitch. + /// + /// @param pitch Pitch of source. + /// + void setPitch(float pitch) override; + + /// + /// Set volume. + /// + /// @param volume Volume of source. + /// + void setVolume(float volume) override; + + /// + /// Set source loop. + /// + /// @param loop Looping or not. + /// + void setLoop(bool loop) override; + + /// + /// Set source rate. + /// + /// @param rate Rate of source. + /// + void setRate(float rate) override; + + /// + /// Handle a specific command. + /// + /// @param manager Audio manager. + /// @param cmd Source commad. + /// + inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd); + + /// + /// Process decoded source data. + /// + /// @param buffer Source data. + /// @param size Data size. + /// + inline void process(void* buffer, size_t size); + + protected: + /// + /// Decode wav file. + /// + /// @param mem Wav file data. + /// @param size Wav data size. + /// + void decode_wav(void* mem, int size); + + /// + /// Decode ogg file. + /// + /// @param mem ogg file data. + /// @param size ogg data size. + /// + void decode_ogg(void* mem, int size); + + /// + /// Check source state. + /// + /// @param state State to be checked. + /// @return True if state is given state, otherwise return false. + /// + inline bool is(int state) const + { + return (status.state & state) == state; + } + + // Source data. + struct { + const void* data; // Ƶ + int length; // dataֽڳ + const void* end; // dataβ = (unsigned char*)data + size + int samplerate; // Ƶ + unsigned char bitdepth; // ÿsampleıس + int samples; // sample = size / (bitdepth / 8) + unsigned char channels; // channel1(mono)2(stereo) + } raw; + // Procedure controller variable. + struct { + int pos; // ǰŵsample + int pitch; // pitch + int state; // ǰ״̬ + bool loop; // loop or not + float volume; // + } status; + + }; + + /// + /// Source manager. + /// + class SDLSourceManager : public Object + { + public: + /// + /// Get manager singleton. + /// + /// @return Singleton of SDL source manager. + /// + static SDLSourceManager* get(); + + /// + /// Process commands. + /// + void processCommands(); + + /// + /// Process sources. + /// + /// @param buffer Source data. + /// @param size Size of source data. + /// + void processSources(void* buffer, size_t size); + + /// + /// Clear source queue. + /// + /// This function will stop all sources. + /// + void removeAllSource(); + + /// + /// Remove specific source. + /// + /// @param source SDL audio source. + /// + void removeSource(SDLSource* source); + + /// + /// Push specific source into queue. + /// + /// @param source SDL audio source. + /// + void pushSource(SDLSource* source); + + /// + /// Get command from queue. + /// + /// @return Command at first place. + /// + SDLSourceCommand* getCommand(); + + /// + /// Push command. + /// + /// @param cmd Spcific command. + /// + void pushCommand(SDLSourceCommand* cmd); + + private: + std::queue<SDLSourceCommand*> commands; + std::stack<SDLSourceCommand*> commandsPool; + std::vector<SDLSource*> sources; // processing sources + static SDLSourceManager* manager; + + }; + + class SourceException : public Object, public std::exception + { + const char* what() const throw () + { + return "Load Source Exception"; + } + }; + + } // namespace SDL + } // namespace Audio } // namespace JinEngine #endif // (jin_audio) && (jin_audio == jin_audio_sdl) diff --git a/src/libjin/audio/audio_manager.cpp b/src/libjin/audio/audio_manager.cpp index dc0e9e2..69fc4c4 100644 --- a/src/libjin/audio/audio_manager.cpp +++ b/src/libjin/audio/audio_manager.cpp @@ -6,10 +6,10 @@ namespace JinEngine { - namespace Audio - { + namespace Audio + { - } // namespace Audio + } // namespace Audio } // namespace JinEngine #endif // jin_audio diff --git a/src/libjin/audio/audio_manager.h b/src/libjin/audio/audio_manager.h index 52757ba..8e09a09 100644 --- a/src/libjin/audio/audio_manager.h +++ b/src/libjin/audio/audio_manager.h @@ -11,73 +11,73 @@ namespace JinEngine { - namespace Audio - { - - class Source; - - /// - /// Audio manager. - /// - template<class SubAudio> - class AudioManager : public Subsystem<SubAudio> - { - public: - /// - /// Audio state. - /// - enum State - { - PLAY , - STOP , - PAUSE, - }; - - /// - /// AudioManager constructor. - /// - AudioManager() - : volume(1) - , state(State::PLAY) - {}; - - /// - /// AudioManager destructor. - /// - virtual ~AudioManager() {}; - - /// - /// Play all sources whose state is playing. - /// - virtual void play() = 0; - - /// - /// Stop and remove all sources from the queue. - /// - virtual void stop() = 0; - - /// - /// Pause audio. - /// - virtual void pause() = 0; - - /// - /// Resume audio. - /// - virtual void resume() = 0; - - /// - /// Set global audio volume. - /// - virtual void setVolume(float volume) = 0; - - protected: - float volume; - State state; - - }; - - } // namespace Audio + namespace Audio + { + + class Source; + + /// + /// Audio manager. + /// + template<class SubAudio> + class AudioManager : public Subsystem<SubAudio> + { + public: + /// + /// Audio state. + /// + enum State + { + PLAY , + STOP , + PAUSE, + }; + + /// + /// AudioManager constructor. + /// + AudioManager() + : volume(1) + , state(State::PLAY) + {}; + + /// + /// AudioManager destructor. + /// + virtual ~AudioManager() {}; + + /// + /// Play all sources whose state is playing. + /// + virtual void play() = 0; + + /// + /// Stop and remove all sources from the queue. + /// + virtual void stop() = 0; + + /// + /// Pause audio. + /// + virtual void pause() = 0; + + /// + /// Resume audio. + /// + virtual void resume() = 0; + + /// + /// Set global audio volume. + /// + virtual void setVolume(float volume) = 0; + + protected: + float volume; + State state; + + }; + + } // namespace Audio } // namespace JinEngine #endif // jin_audio diff --git a/src/libjin/audio/source.cpp b/src/libjin/audio/source.cpp index 289072e..0869569 100644 --- a/src/libjin/audio/source.cpp +++ b/src/libjin/audio/source.cpp @@ -7,24 +7,24 @@ namespace JinEngine { - namespace Audio - { + namespace Audio + { - static int check_header(const void *data, int size, const char *str, int offset) { - int len = strlen(str); - return (size >= offset + len) && !memcmp((char*)data + offset, str, len); - } + static int check_header(const void *data, int size, const char *str, int offset) { + int len = strlen(str); + return (size >= offset + len) && !memcmp((char*)data + offset, str, len); + } - SourceType Source::getType(const void* mem, int size) - { - if(check_header(mem, size, "WAVE", 8)) - return SourceType::WAV; - if(check_header(mem, size, "OggS", 0)) - return SourceType::OGG; - return SourceType::INVALID; - } + SourceType Source::getType(const void* mem, int size) + { + if(check_header(mem, size, "WAVE", 8)) + return SourceType::WAV; + if(check_header(mem, size, "OggS", 0)) + return SourceType::OGG; + return SourceType::INVALID; + } - } // namespace Audio + } // namespace Audio } // namespace JinEngine #endif // jin_audio diff --git a/src/libjin/audio/source.h b/src/libjin/audio/source.h index f3b749d..34350b2 100644 --- a/src/libjin/audio/source.h +++ b/src/libjin/audio/source.h @@ -9,108 +9,108 @@ namespace JinEngine { - namespace Audio - { - - /// - /// Audio source encoding type. - /// - enum SourceType - { - INVALID = 0, - WAV, - OGG, - }; - - /// - /// Audio source. - /// - class Source : public Object - { - public: - /// - /// Source constructor. - /// - Source() {}; - - /// - /// Source destructor. - /// - virtual ~Source() {}; - - /// - /// Start playing source. - /// - virtual void play() = 0; - - /// - /// Stop playing source. - /// - virtual void stop() = 0; - - /// - /// Pause source. - /// - virtual void pause() = 0; - - /// - /// Resume source. - /// - virtual void resume() = 0; - - /// - /// Rewind source. - /// - virtual void rewind() = 0; - - /// - /// Whether the source is playing or not. - /// - virtual bool isStopped() const = 0; - - /// - /// Whether the source is paused or not. - /// - virtual bool isPaused() const = 0; - - /// - /// Set source pitch. - /// - /// @param pitch Pitch of source. - /// - virtual void setPitch(float pitch) = 0; - - /// - /// Set volume of source. - /// - /// @param volume Volume of source. - /// - virtual void setVolume(float volume) = 0; - - /// - /// Set source loop. - /// - /// @param loop Looping or not. - /// - virtual void setLoop(bool loop) = 0; - - /// - /// Set source rate. - /// - /// @param rate Rate of source. - /// - virtual void setRate(float rate) = 0; - - protected: - - /// - /// Get type of source data. - /// - static SourceType getType(const void* mem, int size); - - }; - - } // namespace Audio + namespace Audio + { + + /// + /// Audio source encoding type. + /// + enum SourceType + { + INVALID = 0, + WAV, + OGG, + }; + + /// + /// Audio source. + /// + class Source : public Object + { + public: + /// + /// Source constructor. + /// + Source() {}; + + /// + /// Source destructor. + /// + virtual ~Source() {}; + + /// + /// Start playing source. + /// + virtual void play() = 0; + + /// + /// Stop playing source. + /// + virtual void stop() = 0; + + /// + /// Pause source. + /// + virtual void pause() = 0; + + /// + /// Resume source. + /// + virtual void resume() = 0; + + /// + /// Rewind source. + /// + virtual void rewind() = 0; + + /// + /// Whether the source is playing or not. + /// + virtual bool isStopped() const = 0; + + /// + /// Whether the source is paused or not. + /// + virtual bool isPaused() const = 0; + + /// + /// Set source pitch. + /// + /// @param pitch Pitch of source. + /// + virtual void setPitch(float pitch) = 0; + + /// + /// Set volume of source. + /// + /// @param volume Volume of source. + /// + virtual void setVolume(float volume) = 0; + + /// + /// Set source loop. + /// + /// @param loop Looping or not. + /// + virtual void setLoop(bool loop) = 0; + + /// + /// Set source rate. + /// + /// @param rate Rate of source. + /// + virtual void setRate(float rate) = 0; + + protected: + + /// + /// Get type of source data. + /// + static SourceType getType(const void* mem, int size); + + }; + + } // namespace Audio } // namespace JinEngine #endif // jin_audio diff --git a/src/libjin/common/array.hpp b/src/libjin/common/array.hpp index 8a5cbf1..49ed8ac 100644 --- a/src/libjin/common/array.hpp +++ b/src/libjin/common/array.hpp @@ -4,119 +4,119 @@ namespace JinEngine { - /// - /// A array created on heap. - /// - template<typename T> - class Array - { - public: - /// - /// Array constructor. - /// - Array() - : length(0) - , data(nullptr) - { - } + /// + /// A array created on heap. + /// + template<typename T> + class Array + { + public: + /// + /// Array constructor. + /// + Array() + : length(0) + , data(nullptr) + { + } - /// - /// Array constructor. - /// - /// @param l Length of array. - /// - Array(int l) - { - length = l; - data = new T[l]; - } + /// + /// Array constructor. + /// + /// @param l Length of array. + /// + Array(int l) + { + length = l; + data = new T[l]; + } - /// - /// Array destructor. - /// - ~Array() - { - delete[] data; - length = 0; - } + /// + /// Array destructor. + /// + ~Array() + { + delete[] data; + length = 0; + } - /// - /// Get address of data. - /// - /// @return Address of data. - /// - T* operator &() - { - return data; - } + /// + /// Get address of data. + /// + /// @return Address of data. + /// + T* operator &() + { + return data; + } - /// - /// Get specific element of array. - /// - /// @return Element of array. - /// - T& operator[](int index) - { - return data[index]; - } + /// + /// Get specific element of array. + /// + /// @return Element of array. + /// + T& operator[](int index) + { + return data[index]; + } - /// - /// Bind data with given data. - /// - /// @param data Data pointer. - /// @param length Length of data. - /// - void bind(T* data, int length) - { - if (data != nullptr) - delete data; - this->data = data; - this->length = length; - } + /// + /// Bind data with given data. + /// + /// @param data Data pointer. + /// @param length Length of data. + /// + void bind(T* data, int length) + { + if (data != nullptr) + delete data; + this->data = data; + this->length = length; + } - /// - /// Add an element. - /// - /// @param v Value of element. - /// - void add(T value) - { - int len = length + 1; - T* d = new T[len]; - memcpy(d, data, size()); - d[length] = value; - bind(d, len); - } + /// + /// Add an element. + /// + /// @param v Value of element. + /// + void add(T value) + { + int len = length + 1; + T* d = new T[len]; + memcpy(d, data, size()); + d[length] = value; + bind(d, len); + } - /// - /// Get size of data in byte. - /// - /// @return Size of data in byte. - /// - int size() - { - return sizeof(T) * length; - } + /// + /// Get size of data in byte. + /// + /// @return Size of data in byte. + /// + int size() + { + return sizeof(T) * length; + } - /// - /// Get length of data. - /// - /// @return Count of data. - /// - int count() - { - return length; - } + /// + /// Get length of data. + /// + /// @return Count of data. + /// + int count() + { + return length; + } - private: - // Disable new and delete. - void* operator new(size_t t); - void operator delete(void* ptr); + private: + // Disable new and delete. + void* operator new(size_t t); + void operator delete(void* ptr); - T * data; - unsigned int length; + T * data; + unsigned int length; - }; + }; } // namespace JinEngine diff --git a/src/libjin/common/exception.cpp b/src/libjin/common/exception.cpp index dc4e6ac..3f53132 100644 --- a/src/libjin/common/exception.cpp +++ b/src/libjin/common/exception.cpp @@ -5,42 +5,42 @@ namespace JinEngine { - Exception::Exception(const char *fmt, ...) - { - va_list args; - int size_buffer = 256, size_out; - char *buffer; - while (true) - { - buffer = new char[size_buffer]; - memset(buffer, 0, size_buffer); - - va_start(args, fmt); - size_out = vsnprintf(buffer, size_buffer, fmt, args); - va_end(args); - - // see http://perfec.to/vsnprintf/pasprintf.c - // if size_out ... - // == -1 --> output was truncated - // == size_buffer --> output was truncated - // == size_buffer-1 --> ambiguous, /may/ have been truncated - // > size_buffer --> output was truncated, and size_out - // bytes would have been written - if (size_out == size_buffer || size_out == -1 || size_out == size_buffer - 1) - size_buffer *= 2; - else if (size_out > size_buffer) - size_buffer = size_out + 2; // to avoid the ambiguous case - else - break; - - delete[] buffer; - } - mMessage = std::string(buffer); - delete[] buffer; - } - - Exception::~Exception() throw() - { - } + Exception::Exception(const char *fmt, ...) + { + va_list args; + int size_buffer = 256, size_out; + char *buffer; + while (true) + { + buffer = new char[size_buffer]; + memset(buffer, 0, size_buffer); + + va_start(args, fmt); + size_out = vsnprintf(buffer, size_buffer, fmt, args); + va_end(args); + + // see http://perfec.to/vsnprintf/pasprintf.c + // if size_out ... + // == -1 --> output was truncated + // == size_buffer --> output was truncated + // == size_buffer-1 --> ambiguous, /may/ have been truncated + // > size_buffer --> output was truncated, and size_out + // bytes would have been written + if (size_out == size_buffer || size_out == -1 || size_out == size_buffer - 1) + size_buffer *= 2; + else if (size_out > size_buffer) + size_buffer = size_out + 2; // to avoid the ambiguous case + else + break; + + delete[] buffer; + } + mMessage = std::string(buffer); + delete[] buffer; + } + + Exception::~Exception() throw() + { + } } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/common/exception.h b/src/libjin/common/exception.h index 0dee14c..f46b607 100644 --- a/src/libjin/common/exception.h +++ b/src/libjin/common/exception.h @@ -9,37 +9,37 @@ namespace JinEngine { - /// - /// Jin Exception. - /// - class Exception : public Object, public std::exception - { - public: - /// - /// Creates a new Exception according to printf-rules. - /// - /// @param fmt The format string (see printf). - /// - Exception(const char *fmt, ...); - virtual ~Exception() throw(); - - /// - /// Returns a string containing reason for the exception. - /// - /// @return A description of the exception. - /// - inline virtual const char *what() const throw() - { - return mMessage.c_str(); - } - - private: - /// - /// Exception message. - /// - std::string mMessage; - - }; + /// + /// Jin Exception. + /// + class Exception : public Object, public std::exception + { + public: + /// + /// Creates a new Exception according to printf-rules. + /// + /// @param fmt The format string (see printf). + /// + Exception(const char *fmt, ...); + virtual ~Exception() throw(); + + /// + /// Returns a string containing reason for the exception. + /// + /// @return A description of the exception. + /// + inline virtual const char *what() const throw() + { + return mMessage.c_str(); + } + + private: + /// + /// Exception message. + /// + std::string mMessage; + + }; } // namespace JinEngine diff --git a/src/libjin/common/noncopyable.h b/src/libjin/common/noncopyable.h index ddde7a1..2a9a71e 100644 --- a/src/libjin/common/noncopyable.h +++ b/src/libjin/common/noncopyable.h @@ -6,20 +6,20 @@ namespace JinEngine { - /// - /// Class inherites this could not be copied. - /// - class Noncopyable : public Object - { - public: - Noncopyable(void) { } - virtual ~Noncopyable(void) { } + /// + /// Class inherites this could not be copied. + /// + class Noncopyable : public Object + { + public: + Noncopyable(void) { } + virtual ~Noncopyable(void) { } - private: - Noncopyable(const Noncopyable& other); - Noncopyable& operator=(const Noncopyable& other); + private: + Noncopyable(const Noncopyable& other); + Noncopyable& operator=(const Noncopyable& other); - }; + }; } // namespace JinEngine diff --git a/src/libjin/common/object.h b/src/libjin/common/object.h index 581500f..860a7ab 100644 --- a/src/libjin/common/object.h +++ b/src/libjin/common/object.h @@ -4,15 +4,15 @@ namespace JinEngine { - /// - /// Base class of all classes in libjin. - /// - class Object - { - public: - virtual ~Object() {}; + /// + /// Base class of all classes in libjin. + /// + class Object + { + public: + virtual ~Object() {}; - }; + }; } // namespace JinEngine diff --git a/src/libjin/common/pool.hpp b/src/libjin/common/pool.hpp index 356ff87..262bc07 100644 --- a/src/libjin/common/pool.hpp +++ b/src/libjin/common/pool.hpp @@ -12,165 +12,165 @@ namespace JinEngine { - class DefaultMemoryAllocator : public Object - { - public: - static inline void *Allocate(size_t size) - { - return ::operator new(size, ::std::nothrow); - } - static inline void Deallocate(void *pointer, size_t size) - { - ::operator delete(pointer); - } - }; - - template<typename T, class TMemoryAllocator = DefaultMemoryAllocator> - class Pool : public Object - { - private: - struct _Node - { - void *_memory; - size_t _capacity; - _Node *_nextNode; - - _Node(size_t capacity) - { - if (capacity < 1) - throw std::invalid_argument("capacity must be at least 1."); - - _memory = TMemoryAllocator::Allocate(_itemSize * capacity); - if (_memory == NULL) - throw std::bad_alloc(); - - _capacity = capacity; - _nextNode = NULL; - } - ~_Node() - { - TMemoryAllocator::Deallocate(_memory, _itemSize * _capacity); - } - }; - - void *_nodeMemory; - T *_firstDeleted; - size_t _countInNode; - size_t _nodeCapacity; - _Node _firstNode; - _Node *_lastNode; - size_t _maxBlockLength; - - static const size_t _itemSize; - - Pool(const Pool<T, TMemoryAllocator> &source); - void operator = (const Pool<T, TMemoryAllocator> &source); - - void _AllocateNewNode() - { - size_t size = _countInNode; - if (size >= _maxBlockLength) - size = _maxBlockLength; - else - { - size *= 2; - - if (size < _countInNode) - throw std::overflow_error("size became too big."); - - if (size >= _maxBlockLength) - size = _maxBlockLength; - } - - _Node *newNode = new _Node(size); - _lastNode->_nextNode = newNode; - _lastNode = newNode; - _nodeMemory = newNode->_memory; - _countInNode = 0; - _nodeCapacity = size; - } - - public: - explicit Pool(size_t initialCapacity = 32, size_t maxBlockLength = 1000000) - : _firstDeleted(NULL) - , _countInNode(0) - , _nodeCapacity(initialCapacity) - , _firstNode(initialCapacity) - , _maxBlockLength(maxBlockLength) - { - if (maxBlockLength < 1) - throw std::invalid_argument("maxBlockLength must be at least 1."); - - _nodeMemory = _firstNode._memory; - _lastNode = &_firstNode; - } - ~Pool() - { - _Node *node = _firstNode._nextNode; - while (node) - { - _Node *nextNode = node->_nextNode; - delete node; - node = nextNode; - } - } - - T *New() - { - if (_firstDeleted) - { - T *result = _firstDeleted; - _firstDeleted = *((T **)_firstDeleted); - new(result) T(); - return result; - } - - if (_countInNode >= _nodeCapacity) - _AllocateNewNode(); - - char *address = (char *)_nodeMemory; - address += _countInNode * _itemSize; - T *result = new(address) T(); - _countInNode++; - return result; - } - - // This method is useful if you want to call a non-default constructor. - // It should be used like this: - // new (pool.GetNextWithoutInitializing()) ObjectType(... parameters ...); - T *GetNextWithoutInitializing() - { - if (_firstDeleted) - { - T *result = (T *)_firstDeleted; - _firstDeleted = *((T **)_firstDeleted); - return result; - } - - if (_countInNode >= _nodeCapacity) - _AllocateNewNode(); - - char *address = (char *)_nodeMemory; - address += _countInNode * _itemSize; - _countInNode++; - return (T *)address; - } - void Delete(T *content) - { - content->~T(); - - *((T **)content) = _firstDeleted; - _firstDeleted = content; - } - void DeleteWithoutDestroying(T *content) - { - *((T **)content) = _firstDeleted; - _firstDeleted = content; - } - }; - - template<typename T, class TMemoryAllocator> - const size_t Pool<T, TMemoryAllocator>::_itemSize = ((sizeof(T) + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *); + class DefaultMemoryAllocator : public Object + { + public: + static inline void *Allocate(size_t size) + { + return ::operator new(size, ::std::nothrow); + } + static inline void Deallocate(void *pointer, size_t size) + { + ::operator delete(pointer); + } + }; + + template<typename T, class TMemoryAllocator = DefaultMemoryAllocator> + class Pool : public Object + { + private: + struct _Node + { + void *_memory; + size_t _capacity; + _Node *_nextNode; + + _Node(size_t capacity) + { + if (capacity < 1) + throw std::invalid_argument("capacity must be at least 1."); + + _memory = TMemoryAllocator::Allocate(_itemSize * capacity); + if (_memory == NULL) + throw std::bad_alloc(); + + _capacity = capacity; + _nextNode = NULL; + } + ~_Node() + { + TMemoryAllocator::Deallocate(_memory, _itemSize * _capacity); + } + }; + + void *_nodeMemory; + T *_firstDeleted; + size_t _countInNode; + size_t _nodeCapacity; + _Node _firstNode; + _Node *_lastNode; + size_t _maxBlockLength; + + static const size_t _itemSize; + + Pool(const Pool<T, TMemoryAllocator> &source); + void operator = (const Pool<T, TMemoryAllocator> &source); + + void _AllocateNewNode() + { + size_t size = _countInNode; + if (size >= _maxBlockLength) + size = _maxBlockLength; + else + { + size *= 2; + + if (size < _countInNode) + throw std::overflow_error("size became too big."); + + if (size >= _maxBlockLength) + size = _maxBlockLength; + } + + _Node *newNode = new _Node(size); + _lastNode->_nextNode = newNode; + _lastNode = newNode; + _nodeMemory = newNode->_memory; + _countInNode = 0; + _nodeCapacity = size; + } + + public: + explicit Pool(size_t initialCapacity = 32, size_t maxBlockLength = 1000000) + : _firstDeleted(NULL) + , _countInNode(0) + , _nodeCapacity(initialCapacity) + , _firstNode(initialCapacity) + , _maxBlockLength(maxBlockLength) + { + if (maxBlockLength < 1) + throw std::invalid_argument("maxBlockLength must be at least 1."); + + _nodeMemory = _firstNode._memory; + _lastNode = &_firstNode; + } + ~Pool() + { + _Node *node = _firstNode._nextNode; + while (node) + { + _Node *nextNode = node->_nextNode; + delete node; + node = nextNode; + } + } + + T *New() + { + if (_firstDeleted) + { + T *result = _firstDeleted; + _firstDeleted = *((T **)_firstDeleted); + new(result) T(); + return result; + } + + if (_countInNode >= _nodeCapacity) + _AllocateNewNode(); + + char *address = (char *)_nodeMemory; + address += _countInNode * _itemSize; + T *result = new(address) T(); + _countInNode++; + return result; + } + + // This method is useful if you want to call a non-default constructor. + // It should be used like this: + // new (pool.GetNextWithoutInitializing()) ObjectType(... parameters ...); + T *GetNextWithoutInitializing() + { + if (_firstDeleted) + { + T *result = (T *)_firstDeleted; + _firstDeleted = *((T **)_firstDeleted); + return result; + } + + if (_countInNode >= _nodeCapacity) + _AllocateNewNode(); + + char *address = (char *)_nodeMemory; + address += _countInNode * _itemSize; + _countInNode++; + return (T *)address; + } + void Delete(T *content) + { + content->~T(); + + *((T **)content) = _firstDeleted; + _firstDeleted = content; + } + void DeleteWithoutDestroying(T *content) + { + *((T **)content) = _firstDeleted; + _firstDeleted = content; + } + }; + + template<typename T, class TMemoryAllocator> + const size_t Pool<T, TMemoryAllocator>::_itemSize = ((sizeof(T) + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *); } // namespace JinEngine diff --git a/src/libjin/common/singleton.hpp b/src/libjin/common/singleton.hpp index 015c9b0..f66d6e6 100644 --- a/src/libjin/common/singleton.hpp +++ b/src/libjin/common/singleton.hpp @@ -7,77 +7,77 @@ namespace JinEngine { - /// - /// Singleton base class. - /// - template<class T> - class Singleton : public Object - { - public: - /// - /// Get singleton. - /// - /// @param Singleton instance of class. - /// - static T* get() - { - if (_instance == nullptr) - _instance = new T; - return _instance; - } + /// + /// Singleton base class. + /// + template<class T> + class Singleton : public Object + { + public: + /// + /// Get singleton. + /// + /// @param Singleton instance of class. + /// + static T* get() + { + if (_instance == nullptr) + _instance = new T; + return _instance; + } - /// - /// Destroy instance of singleton. - /// - static void destroy() - { - delete _instance; - _instance = nullptr; - } + /// + /// Destroy instance of singleton. + /// + static void destroy() + { + delete _instance; + _instance = nullptr; + } - protected: - /// - /// Singleton constructor. - /// - Singleton() - { - // Check singleton. - if (_instance) - throw Exception("This is a singleton."); - }; + protected: + /// + /// Singleton constructor. + /// + Singleton() + { + // Check singleton. + if (_instance) + throw Exception("This is a singleton."); + }; - /// - /// Singleton destructor. - /// - virtual ~Singleton() {}; + /// + /// Singleton destructor. + /// + virtual ~Singleton() {}; - /// - /// Singleton instance. - /// - static T* _instance; + /// + /// Singleton instance. + /// + static T* _instance; - private: - /// - /// Singleton copy constructor. - /// - /// @param singleton Singleton of class. - /// - Singleton(const Singleton& singleton); + private: + /// + /// Singleton copy constructor. + /// + /// @param singleton Singleton of class. + /// + Singleton(const Singleton& singleton); - /// - /// Singleton assignment. - /// - /// @param singleton Singleton of class. - /// - Singleton& operator = (const Singleton& singleton); + /// + /// Singleton assignment. + /// + /// @param singleton Singleton of class. + /// + Singleton& operator = (const Singleton& singleton); - }; + }; - /// - /// Singleton instance. - /// - template<class T> - T* Singleton<T>::_instance = nullptr; + /// + /// Singleton instance. + /// + template<class T> + T* Singleton<T>::_instance = nullptr; } // namespace JinEngine diff --git a/src/libjin/common/string.h b/src/libjin/common/string.h index 4e46f17..cecdbc2 100644 --- a/src/libjin/common/string.h +++ b/src/libjin/common/string.h @@ -6,66 +6,66 @@ namespace JinEngine { - class String : public std::string - { - public: - inline String() - : std::string() - { - } - - inline String(const std::string& str) - : std::string(str) - { - } - - inline String(const String& str) - : std::string(str) - { - } - - inline String(const char* str) - : std::string(str) - { - } - - inline String& operator = (const String& str) - { - std::string::operator=(str); - return *this; - } - - inline operator const char* () const - { - return this->c_str(); - } - - inline const char* str() const - { - return this->c_str(); - } - - inline String(const String& s2, size_type pos2, size_type len2) - : std::string(s2, pos2, len2) - { - } - - inline String(const char* buf, size_type bufsize) - : std::string(buf, bufsize) - { - } - - inline String(size_type repetitions, char c) - : std::string(repetitions, c) - { - } - - inline int length() const - { - return size(); - } - - }; + class String : public std::string + { + public: + inline String() + : std::string() + { + } + + inline String(const std::string& str) + : std::string(str) + { + } + + inline String(const String& str) + : std::string(str) + { + } + + inline String(const char* str) + : std::string(str) + { + } + + inline String& operator = (const String& str) + { + std::string::operator=(str); + return *this; + } + + inline operator const char* () const + { + return this->c_str(); + } + + inline const char* str() const + { + return this->c_str(); + } + + inline String(const String& s2, size_type pos2, size_type len2) + : std::string(s2, pos2, len2) + { + } + + inline String(const char* buf, size_type bufsize) + : std::string(buf, bufsize) + { + } + + inline String(size_type repetitions, char c) + : std::string(repetitions, c) + { + } + + inline int length() const + { + return size(); + } + + }; } diff --git a/src/libjin/common/stringmap.hpp b/src/libjin/common/stringmap.hpp index 1db798e..ecd6fdc 100644 --- a/src/libjin/common/stringmap.hpp +++ b/src/libjin/common/stringmap.hpp @@ -6,139 +6,139 @@ namespace JinEngine { - template<typename T, unsigned SIZE> - class StringMap : public Object - { - private: - - struct Record - { - const char * key; - T value; - bool set; - Record() : set(false) {} - }; - - const static unsigned MAX = SIZE * 2; - - Record records[MAX]; - const char * reverse[SIZE]; - - public: - - struct Entry - { - const char * key; - T value; - }; - - StringMap(Entry * entries, unsigned num) - { - - for (unsigned i = 0; i < SIZE; ++i) - reverse[i] = 0; - - unsigned n = num / sizeof(Entry); - - for (unsigned i = 0; i < n; ++i) - { - add(entries[i].key, entries[i].value); - } - } - - bool streq(const char * a, const char * b) - { - while (*a != 0 && *b != 0) - { - if (*a != *b) - return false; - ++a; - ++b; - } - - return (*a == 0 && *b == 0); - } - - bool find(const char * key, T & t) - { - //unsigned str_hash = djb2(key); - - for (unsigned i = 0; i < MAX; ++i) - { - //unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? - - if (records[i].set && streq(records[i].key, key)) - { - t = records[i].value; - return true; - } - } - - return false; - } - - bool find(T key, const char *& str) - { - unsigned index = (unsigned)key; - - if (index >= SIZE) - return false; - - if (reverse[index] != 0) - { - str = reverse[index]; - return true; - } - else - { - return false; - } - } - - bool add(const char * key, T value) - { - unsigned str_hash = djb2(key); - bool inserted = false; - - for (unsigned i = 0; i < MAX; ++i) - { - unsigned str_i = (str_hash + i) % MAX; - - if (!records[str_i].set) - { - inserted = true; - records[str_i].set = true; - records[str_i].key = key; - records[str_i].value = value; - break; - } - } - - unsigned index = (unsigned)value; - - if (index >= SIZE) - { - printf("\nConstant %s out of bounds with %i!\n", key, index); - return false; - } - - reverse[index] = key; - - return inserted; - } - - unsigned djb2(const char * key) - { - unsigned hash = 5381; - int c; - - while ((c = *key++)) - hash = ((hash << 5) + hash) + c; - - return hash; - } - - }; // StringMap + template<typename T, unsigned SIZE> + class StringMap : public Object + { + private: + + struct Record + { + const char * key; + T value; + bool set; + Record() : set(false) {} + }; + + const static unsigned MAX = SIZE * 2; + + Record records[MAX]; + const char * reverse[SIZE]; + + public: + + struct Entry + { + const char * key; + T value; + }; + + StringMap(Entry * entries, unsigned num) + { + + for (unsigned i = 0; i < SIZE; ++i) + reverse[i] = 0; + + unsigned n = num / sizeof(Entry); + + for (unsigned i = 0; i < n; ++i) + { + add(entries[i].key, entries[i].value); + } + } + + bool streq(const char * a, const char * b) + { + while (*a != 0 && *b != 0) + { + if (*a != *b) + return false; + ++a; + ++b; + } + + return (*a == 0 && *b == 0); + } + + bool find(const char * key, T & t) + { + //unsigned str_hash = djb2(key); + + for (unsigned i = 0; i < MAX; ++i) + { + //unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? + + if (records[i].set && streq(records[i].key, key)) + { + t = records[i].value; + return true; + } + } + + return false; + } + + bool find(T key, const char *& str) + { + unsigned index = (unsigned)key; + + if (index >= SIZE) + return false; + + if (reverse[index] != 0) + { + str = reverse[index]; + return true; + } + else + { + return false; + } + } + + bool add(const char * key, T value) + { + unsigned str_hash = djb2(key); + bool inserted = false; + + for (unsigned i = 0; i < MAX; ++i) + { + unsigned str_i = (str_hash + i) % MAX; + + if (!records[str_i].set) + { + inserted = true; + records[str_i].set = true; + records[str_i].key = key; + records[str_i].value = value; + break; + } + } + + unsigned index = (unsigned)value; + + if (index >= SIZE) + { + printf("\nConstant %s out of bounds with %i!\n", key, index); + return false; + } + + reverse[index] = key; + + return inserted; + } + + unsigned djb2(const char * key) + { + unsigned hash = 5381; + int c; + + while ((c = *key++)) + hash = ((hash << 5) + hash) + c; + + return hash; + } + + }; // StringMap } // namespace JinEngine diff --git a/src/libjin/common/subsystem.hpp b/src/libjin/common/subsystem.hpp index 9828c40..2f3a4a4 100644 --- a/src/libjin/common/subsystem.hpp +++ b/src/libjin/common/subsystem.hpp @@ -8,66 +8,66 @@ namespace JinEngine { - /// - /// Subsystem class. - /// - template<class System> - class Subsystem : public Singleton<System> - { - public: - /// - /// Subsystem setting. - /// - struct Setting - { - }; + /// + /// Subsystem class. + /// + template<class System> + class Subsystem : public Singleton<System> + { + public: + /// + /// Subsystem setting. + /// + struct Setting + { + }; - typedef Setting SettingBase; + typedef Setting SettingBase; - /// - /// Initialize subsystem. - /// - /// @param setting Subsystem setting. - /// @return True if initialize sucessful, otherwise return false. - /// - bool start(const SettingBase* setting = nullptr) - { - static bool success = startSystem(setting); - return success; - } + /// + /// Initialize subsystem. + /// + /// @param setting Subsystem setting. + /// @return True if initialize sucessful, otherwise return false. + /// + bool start(const SettingBase* setting = nullptr) + { + static bool success = startSystem(setting); + return success; + } - /// - /// Quit subsystem. - /// - void quit() - { - // Call only once. - static char __dummy__ = (quitSystem(), 1); - Singleton<System>::destroy(); - } + /// + /// Quit subsystem. + /// + void quit() + { + // Call only once. + static char __dummy__ = (quitSystem(), 1); + Singleton<System>::destroy(); + } - /// - /// Subsystem constructor. - /// - Subsystem() {}; + /// + /// Subsystem constructor. + /// + Subsystem() {}; - /// - /// Subsystem destructor. - /// - virtual ~Subsystem() {} + /// + /// Subsystem destructor. + /// + virtual ~Subsystem() {} - protected: - /// - /// Initializer callback. - /// - virtual bool startSystem(const Setting* setting) = 0; + protected: + /// + /// Initializer callback. + /// + virtual bool startSystem(const Setting* setting) = 0; - /// - /// Quit subsystem callback. - /// - virtual void quitSystem() = 0; + /// + /// Quit subsystem callback. + /// + virtual void quitSystem() = 0; - }; + }; } // namespace JinEngine diff --git a/src/libjin/common/temporary.h b/src/libjin/common/temporary.h index 3f02b2b..9152c33 100644 --- a/src/libjin/common/temporary.h +++ b/src/libjin/common/temporary.h @@ -5,28 +5,28 @@ namespace JinEngine { - - /// - /// Class inherites this clound only be created on stack or static zone. - /// - class Temporary : public Object - { - public: - Temporary() {}; - virtual ~Temporary() {}; + + /// + /// Class inherites this clound only be created on stack or static zone. + /// + class Temporary : public Object + { + public: + Temporary() {}; + virtual ~Temporary() {}; /* - protected: - void operator delete(void* t) - { - if(t != nullptr) - free(t); - } + protected: + void operator delete(void* t) + { + if(t != nullptr) + free(t); + } */ - private: - // Disable new operands. - void* operator new(size_t); + private: + // Disable new operands. + void* operator new(size_t); - }; + }; } // namespace JinEngine diff --git a/src/libjin/common/types.h b/src/libjin/common/types.h index e31ce5e..921a327 100644 --- a/src/libjin/common/types.h +++ b/src/libjin/common/types.h @@ -7,23 +7,23 @@ namespace JinEngine { - typedef int8_t int8; ///< Signed integer with a size of 8 bits. Supports values from -128 to 127 - typedef uint8_t uint8; ///< Unsigned integer with a size of 8 bits. Supports values from 0 to 255. - typedef uint8 byte; ///< Unsigned integer with 8 bits (1 byte). Supports 256 values from 0 to 255. - typedef int16_t int16; ///< Signed integer with a size of 16 bits. Supports values from -32768 to 32767 - typedef uint16_t uint16; ///< Unsigned integer with a size of 16 bits. Supports values from 0 to 65535. - typedef int32_t int32; ///< Signed integer with a size of 32 bits. Supports values from -2147483648 to 2147483647. - typedef uint32_t uint32; ///< Unsigned integer with a size of 32 bits. Supports values from 0 to 4294967295, (2^32 - 1). - typedef int64_t int64; ///< Signed integer with a size of 64 bits. Supports values from -(2^63) to (2^63 - 1). - typedef uint64_t uint64; ///< Unsigned integer with a size of 64 bits, Supports values from 0 to (2^64 - 1). + typedef int8_t int8; ///< Signed integer with a size of 8 bits. Supports values from -128 to 127 + typedef uint8_t uint8; ///< Unsigned integer with a size of 8 bits. Supports values from 0 to 255. + typedef uint8 byte; ///< Unsigned integer with 8 bits (1 byte). Supports 256 values from 0 to 255. + typedef int16_t int16; ///< Signed integer with a size of 16 bits. Supports values from -32768 to 32767 + typedef uint16_t uint16; ///< Unsigned integer with a size of 16 bits. Supports values from 0 to 65535. + typedef int32_t int32; ///< Signed integer with a size of 32 bits. Supports values from -2147483648 to 2147483647. + typedef uint32_t uint32; ///< Unsigned integer with a size of 32 bits. Supports values from 0 to 4294967295, (2^32 - 1). + typedef int64_t int64; ///< Signed integer with a size of 64 bits. Supports values from -(2^63) to (2^63 - 1). + typedef uint64_t uint64; ///< Unsigned integer with a size of 64 bits, Supports values from 0 to (2^64 - 1). - typedef uint32_t uint; - typedef int32_t sint; + typedef uint32_t uint; + typedef int32_t sint; #define Union(name, ...) \ -union _Ctor{ \ - _Ctor() { memset(this, 0, sizeof(*this)); } \ - __VA_ARGS__; \ +union _Ctor{ \ + _Ctor() { memset(this, 0, sizeof(*this)); } \ + __VA_ARGS__; \ } name; #define Struct(name, ...) \ diff --git a/src/libjin/core/configuration.h b/src/libjin/core/configuration.h index 40956b5..d6451cb 100644 --- a/src/libjin/core/configuration.h +++ b/src/libjin/core/configuration.h @@ -9,17 +9,17 @@ //#define jin_debug #define jin_os_windows 0x01 -#define jin_os_mac 0x02 +#define jin_os_mac 0x02 #define jin_os_linux 0x03 #define jin_os jin_os_windows -#define jin_graphics_font 0x02 -#define jin_graphics_shader 0x04 +#define jin_graphics_font 0x02 +#define jin_graphics_shader 0x04 #define jin_graphics_particle 0x08 #define jin_graphics_animation 0x10 #define jin_graphics (jin_graphics_font|jin_graphics_shader) -#define jin_audio_sdl 0x01 +#define jin_audio_sdl 0x01 #define jin_audio_openal 0x02 #define jin_audio jin_audio_sdl @@ -42,8 +42,8 @@ #define jin_physics_box2d 0x02 //#define jin_physics jin_physics_newton -#define jin_thread_sdl 0x01 -#define jin_thread_cpp 0x02 +#define jin_thread_sdl 0x01 +#define jin_thread_cpp 0x02 #define jin_thread_pthread 0x03 #define jin_thread jin_thread_sdl diff --git a/src/libjin/core/version.h b/src/libjin/core/version.h index b5fe379..9fc403b 100644 --- a/src/libjin/core/version.h +++ b/src/libjin/core/version.h @@ -3,50 +3,50 @@ namespace JinEngine { - namespace Core - { + namespace Core + { - /// - /// Get version of Jin. - /// - /// @return Version of Jin. - /// - const char* getVersion() - { - return "Jin 0.1"; - } + /// + /// Get version of Jin. + /// + /// @return Version of Jin. + /// + const char* getVersion() + { + return "Jin 0.1"; + } - /// - /// Get author of Jin. - /// - /// @return Author of Jin. - /// - const char* getAuthor() - { - return "Chai"; - } + /// + /// Get author of Jin. + /// + /// @return Author of Jin. + /// + const char* getAuthor() + { + return "Chai"; + } - /// - /// Get release of Jin. - /// - /// @return release string of Jin. - /// - const char* getRelease() - { - return "Jin 0.1.1"; - } + /// + /// Get release of Jin. + /// + /// @return release string of Jin. + /// + const char* getRelease() + { + return "Jin 0.1.1"; + } - /// - /// Get release of Jin. - /// - /// @return Revision of Jin. - /// - int getRevision() - { - return 101; - } + /// + /// Get release of Jin. + /// + /// @return Revision of Jin. + /// + int getRevision() + { + return 101; + } - } // namespace Core + } // namespace Core } // namespace JinEngine #endif // __JE_CORE_VERSION_H__ diff --git a/src/libjin/filesystem/asset_database.cpp b/src/libjin/filesystem/asset_database.cpp index e532f41..6214a4a 100644 --- a/src/libjin/filesystem/asset_database.cpp +++ b/src/libjin/filesystem/asset_database.cpp @@ -11,75 +11,75 @@ namespace JinEngine { - namespace Filesystem - { - - AssetDatabase* AssetDatabase::mAssetDatabase = 0; - - AssetDatabase::AssetDatabase() - { - mSmt = smtnewshared(); - } - - AssetDatabase* AssetDatabase::get() - { - return mAssetDatabase ? mAssetDatabase : (mAssetDatabase = new AssetDatabase()); - } - - void AssetDatabase::mount(const char * path) - { - int err = smtmount(mSmt, path); - if (err) - { - printf("%s mounted path %s", smterrstr(err), path); - exit(1); - } - } - - void AssetDatabase::read(const char* path, Buffer& buffer) - { - size_t size; - byte* data = (byte*)smtread(mSmt, path, &size); - if (data == nullptr) - throw Exception("Could not read file %s.", path); - buffer.bind(data, size); - } - - Buffer* read(const char* path) - { - return nullptr; - } - - void* AssetDatabase::read(const char* path, unsigned int* len) - { - return smtread(mSmt, path, len); - } - - const char* AssetDatabase::getFull(const char* path) - { - return smtfullpath(mSmt, path); - } - - bool AssetDatabase::isDir(const char* path) - { - return smtisdir(mSmt, path); - } - - bool AssetDatabase::isFile(const char* path) - { - return smtisreg(mSmt, path); - } - - bool AssetDatabase::exists(const char* path) - { - return smtexists(mSmt, path) == 0; - } + namespace Filesystem + { + + AssetDatabase* AssetDatabase::mAssetDatabase = 0; + + AssetDatabase::AssetDatabase() + { + mSmt = smtnewshared(); + } + + AssetDatabase* AssetDatabase::get() + { + return mAssetDatabase ? mAssetDatabase : (mAssetDatabase = new AssetDatabase()); + } + + void AssetDatabase::mount(const char * path) + { + int err = smtmount(mSmt, path); + if (err) + { + printf("%s mounted path %s", smterrstr(err), path); + exit(1); + } + } + + void AssetDatabase::read(const char* path, Buffer& buffer) + { + size_t size; + byte* data = (byte*)smtread(mSmt, path, &size); + if (data == nullptr) + throw Exception("Could not read file %s.", path); + buffer.bind(data, size); + } + + Buffer* read(const char* path) + { + return nullptr; + } + + void* AssetDatabase::read(const char* path, unsigned int* len) + { + return smtread(mSmt, path, len); + } + + const char* AssetDatabase::getFull(const char* path) + { + return smtfullpath(mSmt, path); + } + + bool AssetDatabase::isDir(const char* path) + { + return smtisdir(mSmt, path); + } + + bool AssetDatabase::isFile(const char* path) + { + return smtisreg(mSmt, path); + } + + bool AssetDatabase::exists(const char* path) + { + return smtexists(mSmt, path) == 0; + } /* - std::vector<std::string> AssetDatabase::getFiles(const char* path, bool recursive) - { - } + std::vector<std::string> AssetDatabase::getFiles(const char* path, bool recursive) + { + } */ - } // namespace Filesystem + } // namespace Filesystem } // namespace JinEngine #endif // jin_filesystem
\ No newline at end of file diff --git a/src/libjin/filesystem/asset_database.h b/src/libjin/filesystem/asset_database.h index 2d7d5a3..f7e6339 100644 --- a/src/libjin/filesystem/asset_database.h +++ b/src/libjin/filesystem/asset_database.h @@ -12,101 +12,101 @@ namespace JinEngine { - namespace Filesystem - { - - /// - /// Assets managment. - /// - class AssetDatabase : public Object - { - public: - /// - /// Get asset database singleton. - /// - /// @param Singleton of asset database. - /// - static AssetDatabase* get(); - - /// - /// Asset database constructor. - /// - AssetDatabase(); - - /// - /// Set asset root folder. - /// - /// @param root Root folder of assets. - /// - void mount(const char* root); - - /// - /// Check if the path is directory. - /// - /// @param path Path under asset folder. - /// @return True if the given path is directory, otherwise return false. - /// - bool isDir(const char* path); - - /// - /// Check if the path is file. - /// - /// @param path Path under asset folder. - /// @return True if the given path is file, otherwise return false. - /// - bool isFile(const char* path); - - /// - /// Check if the path exists. - /// @param path Given path. - /// @return True if path exists, otherwise return false. - /// - bool exists(const char* path); - - /// - /// Read file into a buffer. - /// - /// @param path Path of file. - /// @param buffer Buffer to fill. - /// @return True if read sucessful, otherwise return false. - /// - void read(const char* path, Buffer& buffer); - - /// - /// Read file and return data content. - /// - /// @param path Path of file. - /// @param length Length of data. - /// @return Data if read sucessful, otherwise return null. - /// - void* read(const char* path, unsigned int* length); - - /// - /// Get files under given directory. - /// - /// @param path Path of directory. - /// @param recursive Recursivily search folder. - /// @return File list under given directory. - /// - std::vector<std::string> getFiles(const char* directory, bool recursive = false); - - /// - /// Get full path of asset. - /// - /// @param path Path of asset. - /// @return Full path of asset. - /// - const char* getFull(const char* path); - - private: - static AssetDatabase* mAssetDatabase; + namespace Filesystem + { + + /// + /// Assets managment. + /// + class AssetDatabase : public Object + { + public: + /// + /// Get asset database singleton. + /// + /// @param Singleton of asset database. + /// + static AssetDatabase* get(); + + /// + /// Asset database constructor. + /// + AssetDatabase(); + + /// + /// Set asset root folder. + /// + /// @param root Root folder of assets. + /// + void mount(const char* root); + + /// + /// Check if the path is directory. + /// + /// @param path Path under asset folder. + /// @return True if the given path is directory, otherwise return false. + /// + bool isDir(const char* path); + + /// + /// Check if the path is file. + /// + /// @param path Path under asset folder. + /// @return True if the given path is file, otherwise return false. + /// + bool isFile(const char* path); + + /// + /// Check if the path exists. + /// @param path Given path. + /// @return True if path exists, otherwise return false. + /// + bool exists(const char* path); + + /// + /// Read file into a buffer. + /// + /// @param path Path of file. + /// @param buffer Buffer to fill. + /// @return True if read sucessful, otherwise return false. + /// + void read(const char* path, Buffer& buffer); + + /// + /// Read file and return data content. + /// + /// @param path Path of file. + /// @param length Length of data. + /// @return Data if read sucessful, otherwise return null. + /// + void* read(const char* path, unsigned int* length); + + /// + /// Get files under given directory. + /// + /// @param path Path of directory. + /// @param recursive Recursivily search folder. + /// @return File list under given directory. + /// + std::vector<std::string> getFiles(const char* directory, bool recursive = false); + + /// + /// Get full path of asset. + /// + /// @param path Path of asset. + /// @return Full path of asset. + /// + const char* getFull(const char* path); + + private: + static AssetDatabase* mAssetDatabase; #if jin_filesystem == jin_filesystem_smount - smtShared* mSmt; + smtShared* mSmt; #endif - }; + }; - } // namespace Filesystem + } // namespace Filesystem } // namespace JinEngine #endif // jin_filesystem diff --git a/src/libjin/filesystem/buffer.h b/src/libjin/filesystem/buffer.h index 2b5be6a..8056fd5 100644 --- a/src/libjin/filesystem/buffer.h +++ b/src/libjin/filesystem/buffer.h @@ -12,156 +12,156 @@ namespace JinEngine { - namespace Filesystem - { - - /// - /// Data buffer allocated on heap. - /// - class Buffer : public Temporary - { - public: - /// - /// Buffer constructor. - /// - Buffer() - : mData(0) - , mSize(0) - { - } - - /// - /// Copy constructor. - /// - /// @param src Buffer source. - /// - Buffer(const Buffer& src) - { - delete[] mData; - mSize = src.mSize; - mData = new byte[mSize]; - memcpy(mData, src.mData, mSize); - } - - /// - /// Buffer constructor. - /// - /// @param data Buffer data. - /// @param size Size of buffer. - /// - Buffer(void* data, int size) - { - mSize = size; - mData = new byte[mSize]; - memcpy(mData, data, mSize); - } - - /// - /// Buffer constructor. - /// - /// @param size Size of data. - /// - Buffer(size_t size) - { - mData = new byte[size]; - memset(mData, 0, size); - mSize = size; - } - - /// - /// Buffer destructor. - /// - ~Buffer() - { - delete[] mData; - mSize = 0; - } - - /// - /// Set buffer data. - /// - /// @param data Buffer data. - /// @param size Size of data. - /// - void set(byte* data, size_t size) - { - if (data == nullptr) - return; - if (mSize != size) - { - delete mData; - mData = new byte[size]; - } - mSize = size; - memcpy(mData, data, size); - } - - /// - /// Bind buffer data. - /// - /// @param data Buffer data. - /// @param size Size of buffer. - /// - void bind(byte* data, size_t size) - { - if (mData != nullptr) - delete mData; - mSize = size; - mData = data; - } - - /// - /// Buffer assignment. - /// - /// @param buffer Buffer to copy. - /// - void operator = (const Buffer& buffer) - { - delete[] mData; - mSize = buffer.mSize; - mData = new byte[mSize]; - memcpy(mData, buffer.mData, mSize); - } - - /// - /// Get data addresss. - /// - /// @return Data address. - /// - const byte* operator &() - { - return mData; - } - - /// - /// Get data size. - /// - /// @return Size of data. - /// - const inline size_t size() - { - return mSize; - } - - /// - /// Clear data. - /// - void clear() - { - if (mData == nullptr) - return; - delete mData; - mData = nullptr; - mSize = 0; - } - - private: - byte* mData; - size_t mSize; - - }; - - } // namespace Filesystem + namespace Filesystem + { + + /// + /// Data buffer allocated on heap. + /// + class Buffer : public Temporary + { + public: + /// + /// Buffer constructor. + /// + Buffer() + : mData(0) + , mSize(0) + { + } + + /// + /// Copy constructor. + /// + /// @param src Buffer source. + /// + Buffer(const Buffer& src) + { + delete[] mData; + mSize = src.mSize; + mData = new byte[mSize]; + memcpy(mData, src.mData, mSize); + } + + /// + /// Buffer constructor. + /// + /// @param data Buffer data. + /// @param size Size of buffer. + /// + Buffer(void* data, int size) + { + mSize = size; + mData = new byte[mSize]; + memcpy(mData, data, mSize); + } + + /// + /// Buffer constructor. + /// + /// @param size Size of data. + /// + Buffer(size_t size) + { + mData = new byte[size]; + memset(mData, 0, size); + mSize = size; + } + + /// + /// Buffer destructor. + /// + ~Buffer() + { + delete[] mData; + mSize = 0; + } + + /// + /// Set buffer data. + /// + /// @param data Buffer data. + /// @param size Size of data. + /// + void set(byte* data, size_t size) + { + if (data == nullptr) + return; + if (mSize != size) + { + delete mData; + mData = new byte[size]; + } + mSize = size; + memcpy(mData, data, size); + } + + /// + /// Bind buffer data. + /// + /// @param data Buffer data. + /// @param size Size of buffer. + /// + void bind(byte* data, size_t size) + { + if (mData != nullptr) + delete mData; + mSize = size; + mData = data; + } + + /// + /// Buffer assignment. + /// + /// @param buffer Buffer to copy. + /// + void operator = (const Buffer& buffer) + { + delete[] mData; + mSize = buffer.mSize; + mData = new byte[mSize]; + memcpy(mData, buffer.mData, mSize); + } + + /// + /// Get data addresss. + /// + /// @return Data address. + /// + const byte* operator &() + { + return mData; + } + + /// + /// Get data size. + /// + /// @return Size of data. + /// + const inline size_t size() + { + return mSize; + } + + /// + /// Clear data. + /// + void clear() + { + if (mData == nullptr) + return; + delete mData; + mData = nullptr; + mSize = 0; + } + + private: + byte* mData; + size_t mSize; + + }; + + } // namespace Filesystem } // namespace JinEngine #endif // jin_filesystem diff --git a/src/libjin/filesystem/je_compressor.h b/src/libjin/filesystem/je_compressor.h index efaf6c3..228d754 100644 --- a/src/libjin/filesystem/je_compressor.h +++ b/src/libjin/filesystem/je_compressor.h @@ -3,12 +3,12 @@ namespace JinEngine { - namespace Filesystem - { + namespace Filesystem + { - } + } } #endif
\ No newline at end of file diff --git a/src/libjin/game/application.cpp b/src/libjin/game/application.cpp index c198336..ee9d4c0 100644 --- a/src/libjin/game/application.cpp +++ b/src/libjin/game/application.cpp @@ -18,65 +18,65 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Game - { + namespace Game + { - Application::Application() :_running(true) {}; + Application::Application() :_running(true) {}; - /* default game loop */ - void Application::run() - { - if (_onLoad != nullptr) - _onLoad(); - Window* wnd = Window::get(); - const int FPS = wnd ? wnd->getFPS() : 60; - const int MS_PER_UPDATE = 1000.0f / FPS; - _running = true; - Event e; - int current = getMilliSecond(); - int previous = current; - int dt = 0; - while (_running) - { - while (JinEngine::Input::pollEvent(&e)) - { - if (_onEvent != nullptr) - _onEvent(&e); - if (!_running) - goto quitloop; - } - previous = current; - current = getMilliSecond(); - dt = current - previous; - if (_onUpdate != nullptr) - _onUpdate(dt); - glClear(GL_COLOR_BUFFER_BIT); - if (_onDraw != nullptr) - _onDraw(); - wnd->present(); - sleep(16); - } - quitloop:; - } + /* default game loop */ + void Application::run() + { + if (_onLoad != nullptr) + _onLoad(); + Window* wnd = Window::get(); + const int FPS = wnd ? wnd->getFPS() : 60; + const int MS_PER_UPDATE = 1000.0f / FPS; + _running = true; + Event e; + int current = getMilliSecond(); + int previous = current; + int dt = 0; + while (_running) + { + while (JinEngine::Input::pollEvent(&e)) + { + if (_onEvent != nullptr) + _onEvent(&e); + if (!_running) + goto quitloop; + } + previous = current; + current = getMilliSecond(); + dt = current - previous; + if (_onUpdate != nullptr) + _onUpdate(dt); + glClear(GL_COLOR_BUFFER_BIT); + if (_onDraw != nullptr) + _onDraw(); + wnd->present(); + sleep(16); + } + quitloop:; + } - bool Application::startSystem(const SettingBase* setting) - { - if (setting == nullptr) - return false; - Application::Setting* s = (Application::Setting*) setting; - _onEvent = s->eventHandler; - _onUpdate = s->updater; - _onDraw = s->drawer; - _onLoad = s->loader; - return true; - } + bool Application::startSystem(const SettingBase* setting) + { + if (setting == nullptr) + return false; + Application::Setting* s = (Application::Setting*) setting; + _onEvent = s->eventHandler; + _onUpdate = s->updater; + _onDraw = s->drawer; + _onLoad = s->loader; + return true; + } - void Application::quitSystem() - { - SDL_Quit(); - } + void Application::quitSystem() + { + SDL_Quit(); + } - } // namespace Core + } // namespace Core } // namespace JinEngine #endif // jin_game
\ No newline at end of file diff --git a/src/libjin/game/application.h b/src/libjin/game/application.h index 4c4f48b..7853e2b 100644 --- a/src/libjin/game/application.h +++ b/src/libjin/game/application.h @@ -12,71 +12,71 @@ namespace JinEngine { - namespace Game - { - - /// - /// Game class. - /// - class Application : public Subsystem<Application> - { - public: - typedef void(*onLoad)(); - typedef void(*onEvent)(JinEngine::Input::Event* e); - typedef void(*onUpdate)(int dt); - typedef void(*onDraw)(); - - Application(); - ~Application() {}; - - /// - /// Game setting. - /// - struct Setting : SettingBase - { - onEvent eventHandler; - onUpdate updater; - onDraw drawer; - onLoad loader; - }; - - /// - /// Main game loop. - /// - void run(); - - /// - /// Stop game. - /// - inline void stop() - { - _running = false; - }; - - /// - /// Return if game is running. - /// - /// @return True if game is running, otherwise return false. - /// - inline bool running() - { - return _running; - }; - - private: - onEvent _onEvent; - onUpdate _onUpdate; - onDraw _onDraw; - onLoad _onLoad; - - bool _running; - - bool startSystem(const SettingBase* setting); - void quitSystem(); - - }; - - } // namespace Core + namespace Game + { + + /// + /// Game class. + /// + class Application : public Subsystem<Application> + { + public: + typedef void(*onLoad)(); + typedef void(*onEvent)(JinEngine::Input::Event* e); + typedef void(*onUpdate)(int dt); + typedef void(*onDraw)(); + + Application(); + ~Application() {}; + + /// + /// Game setting. + /// + struct Setting : SettingBase + { + onEvent eventHandler; + onUpdate updater; + onDraw drawer; + onLoad loader; + }; + + /// + /// Main game loop. + /// + void run(); + + /// + /// Stop game. + /// + inline void stop() + { + _running = false; + }; + + /// + /// Return if game is running. + /// + /// @return True if game is running, otherwise return false. + /// + inline bool running() + { + return _running; + }; + + private: + onEvent _onEvent; + onUpdate _onUpdate; + onDraw _onDraw; + onLoad _onLoad; + + bool _running; + + bool startSystem(const SettingBase* setting); + void quitSystem(); + + }; + + } // namespace Core } // namespace JinEngine #endif // jin_game diff --git a/src/libjin/game/gameobject.cpp b/src/libjin/game/gameobject.cpp index b17c93c..9e09706 100644 --- a/src/libjin/game/gameobject.cpp +++ b/src/libjin/game/gameobject.cpp @@ -2,10 +2,10 @@ namespace JinEngine { - namespace Game - { + namespace Game + { - + - } // namespace Game + } // namespace Game } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/game/gameobject.h b/src/libjin/game/gameobject.h index 7cb0de2..f81ae75 100644 --- a/src/libjin/game/gameobject.h +++ b/src/libjin/game/gameobject.h @@ -13,27 +13,27 @@ namespace JinEngine { - namespace Game - { + namespace Game + { - /// - /// Game object base class. - /// - class GameObject : public Object - { - public: + /// + /// Game object base class. + /// + class GameObject : public Object + { + public: - /// - /// - /// - virtual ~GameObject() {}; + /// + /// + /// + virtual ~GameObject() {}; - protected: - Math::Transform mTransform; + protected: + Math::Transform mTransform; - }; + }; - } // namespace Game + } // namespace Game } // namespace JinEngine #endif // jin_game diff --git a/src/libjin/graphics/animations/animation.cpp b/src/libjin/graphics/animations/animation.cpp index 168c3e3..3eb67c0 100644 --- a/src/libjin/graphics/animations/animation.cpp +++ b/src/libjin/graphics/animations/animation.cpp @@ -5,61 +5,61 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Graphics - { - namespace Animations - { + namespace Graphics + { + namespace Animations + { - Animation::Animation() - : mLoop(true) - { - } + Animation::Animation() + : mLoop(true) + { + } - void Animation::addFrame(const Sprite* frame) - { - if(frame != nullptr) - mFrames.push_back(frame); - } + void Animation::addFrame(const Sprite* frame) + { + if(frame != nullptr) + mFrames.push_back(frame); + } - void Animation::addFrames(const std::vector<Sprite*>& frames) - { - mFrames.insert(mFrames.end(), frames.begin(), frames.end()); - } + void Animation::addFrames(const std::vector<Sprite*>& frames) + { + mFrames.insert(mFrames.end(), frames.begin(), frames.end()); + } - void Animation::setSpeed(float speed) - { - mSpeed = speed; - } + void Animation::setSpeed(float speed) + { + mSpeed = speed; + } - void Animation::setLoop(bool loop) - { - mLoop = loop; - } + void Animation::setLoop(bool loop) + { + mLoop = loop; + } - const Sprite* Animation::getFrame(uint index) const - { - if (mFrames.size() == 0) - return nullptr; - if (without<uint>(index, 0, mFrames.size() - 1)) - return nullptr; - return mFrames[index]; - } + const Sprite* Animation::getFrame(uint index) const + { + if (mFrames.size() == 0) + return nullptr; + if (without<uint>(index, 0, mFrames.size() - 1)) + return nullptr; + return mFrames[index]; + } - uint Animation::getFrameCount() const - { - return mFrames.size(); - } + uint Animation::getFrameCount() const + { + return mFrames.size(); + } - bool Animation::isLoop() const - { - return mLoop; - } + bool Animation::isLoop() const + { + return mLoop; + } - float Animation::getSpeed() const - { - return mSpeed; - } + float Animation::getSpeed() const + { + return mSpeed; + } - } - } + } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/animations/animation.h b/src/libjin/graphics/animations/animation.h index 72565fc..f48ff33 100644 --- a/src/libjin/graphics/animations/animation.h +++ b/src/libjin/graphics/animations/animation.h @@ -10,50 +10,50 @@ namespace JinEngine { - namespace Graphics - { - namespace Animations - { + namespace Graphics + { + namespace Animations + { - /// - /// Animation clip with key. - /// - class Animation : public Object - { - public: - Animation(); - - void addFrame(const Sprite* frame); + /// + /// Animation clip with key. + /// + class Animation : public Object + { + public: + Animation(); + + void addFrame(const Sprite* frame); - void addFrames(const std::vector<Sprite*>& frames); + void addFrames(const std::vector<Sprite*>& frames); - void setLoop(bool loop); + void setLoop(bool loop); - void setSpeed(float speed); + void setSpeed(float speed); - bool isLoop() const; + bool isLoop() const; - float getSpeed() const; + float getSpeed() const; - uint getFrameCount() const; + uint getFrameCount() const; - const Sprite* getFrame(uint index) const; + const Sprite* getFrame(uint index) const; - private: + private: - std::vector<const Sprite*> mFrames; + std::vector<const Sprite*> mFrames; - /// - /// Frame per second. - /// - float mSpeed; + /// + /// Frame per second. + /// + float mSpeed; - float mLoop; - - }; + float mLoop; + + }; - } // namespace Animations - } // namespace Graphics + } // namespace Animations + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/animations/animator.cpp b/src/libjin/graphics/animations/animator.cpp index 8db3bc2..d3fac8b 100644 --- a/src/libjin/graphics/animations/animator.cpp +++ b/src/libjin/graphics/animations/animator.cpp @@ -5,124 +5,124 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Graphics - { - namespace Animations - { - - Animator::Animator() - : mIndex(0) - , mTick(0) - , mIsActive(true) - { - } - - void Animator::setAnimation(const Animation* anim) - { - mAnimation = anim; - if (mAnimation) - { - mSpeed = mAnimation->getSpeed(); - mLoop = mAnimation->isLoop(); - } - } - - void Animator::play() - { - mIndex = 0; - mIsActive = true; - mTick = 0; - } - - void Animator::pause() - { - mIsActive = false; - } - - void Animator::resume() - { - mIsActive = true; - } - - void Animator::update(float dt) - { - if (!mIsActive || !mAnimation) - return; - float interval = 1 / mSpeed; - mTick += dt; - uint fc = mAnimation->getFrameCount(); - if (mTick >= interval) - { - mIndex += int(mTick / interval); - mTick = fmod(mTick, interval); - if (mLoop) - mIndex %= fc; - mIndex = clamp<uint>(mIndex, 0, fc - 1); - } - } - - void Animator::rewind() - { - mIndex = 0; - } - - void Animator::render(float x, float y, float sx, float sy, float r) const - { - if (!mAnimation) - return; - const Sprite* spr = mAnimation->getFrame(mIndex); - if (spr) - spr->render(x, y, sx, sy, r); - } - - void Animator::forceToFrame(uint index) - { - mIndex = index; - - } - - void Animator::setSpeed(float speed) - { - mSpeed = speed; - } - - void Animator::setDefaultSpeed() - { - if(mAnimation != nullptr) - mSpeed = mAnimation->getSpeed(); - else - { - jin_log_error("Animation is null."); - return; - } - } - - void Animator::setLoop(bool loop) - { - mLoop = loop; - } - - void Animator::setDefaultLoop() - { - if(mAnimation != nullptr) - mLoop = mAnimation->isLoop(); - else - { - jin_log_error("Animation is null."); - return; - } - } - - float Animator::getSpeed() - { - return mSpeed; - } - - uint Animator::getFrameCount() - { - return mAnimation->getFrameCount(); - } - - } - } + namespace Graphics + { + namespace Animations + { + + Animator::Animator() + : mIndex(0) + , mTick(0) + , mIsActive(true) + { + } + + void Animator::setAnimation(const Animation* anim) + { + mAnimation = anim; + if (mAnimation) + { + mSpeed = mAnimation->getSpeed(); + mLoop = mAnimation->isLoop(); + } + } + + void Animator::play() + { + mIndex = 0; + mIsActive = true; + mTick = 0; + } + + void Animator::pause() + { + mIsActive = false; + } + + void Animator::resume() + { + mIsActive = true; + } + + void Animator::update(float dt) + { + if (!mIsActive || !mAnimation) + return; + float interval = 1 / mSpeed; + mTick += dt; + uint fc = mAnimation->getFrameCount(); + if (mTick >= interval) + { + mIndex += int(mTick / interval); + mTick = fmod(mTick, interval); + if (mLoop) + mIndex %= fc; + mIndex = clamp<uint>(mIndex, 0, fc - 1); + } + } + + void Animator::rewind() + { + mIndex = 0; + } + + void Animator::render(float x, float y, float sx, float sy, float r) const + { + if (!mAnimation) + return; + const Sprite* spr = mAnimation->getFrame(mIndex); + if (spr) + spr->render(x, y, sx, sy, r); + } + + void Animator::forceToFrame(uint index) + { + mIndex = index; + + } + + void Animator::setSpeed(float speed) + { + mSpeed = speed; + } + + void Animator::setDefaultSpeed() + { + if(mAnimation != nullptr) + mSpeed = mAnimation->getSpeed(); + else + { + jin_log_error("Animation is null."); + return; + } + } + + void Animator::setLoop(bool loop) + { + mLoop = loop; + } + + void Animator::setDefaultLoop() + { + if(mAnimation != nullptr) + mLoop = mAnimation->isLoop(); + else + { + jin_log_error("Animation is null."); + return; + } + } + + float Animator::getSpeed() + { + return mSpeed; + } + + uint Animator::getFrameCount() + { + return mAnimation->getFrameCount(); + } + + } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/animations/animator.h b/src/libjin/graphics/animations/animator.h index 263c7cb..6a0cb28 100644 --- a/src/libjin/graphics/animations/animator.h +++ b/src/libjin/graphics/animations/animator.h @@ -10,61 +10,61 @@ namespace JinEngine { - namespace Graphics - { - namespace Animations - { + namespace Graphics + { + namespace Animations + { - class Animator : public Object, public Renderable - { - public: - Animator(); + class Animator : public Object, public Renderable + { + public: + Animator(); - void play(); + void play(); - void pause(); + void pause(); - void resume(); + void resume(); - void update(float dt); + void update(float dt); - void rewind(); + void rewind(); - void render(float x, float y, float sx, float sy, float r) const override; + void render(float x, float y, float sx, float sy, float r) const override; - void setAnimation(const Animation* anim); + void setAnimation(const Animation* anim); - void forceToFrame(uint index); + void forceToFrame(uint index); - void setSpeed(float speed); + void setSpeed(float speed); - void setDefaultSpeed(); + void setDefaultSpeed(); - void setLoop(bool loop); + void setLoop(bool loop); - void setDefaultLoop(); + void setDefaultLoop(); - float getSpeed(); + float getSpeed(); - uint getFrameCount(); + uint getFrameCount(); - private: - const Animation* mAnimation; + private: + const Animation* mAnimation; - uint mIndex; + uint mIndex; - float mTick; + float mTick; - bool mIsActive; + bool mIsActive; - float mSpeed; + float mSpeed; - bool mLoop; + bool mLoop; - }; + }; - } - } + } + } } #endif
\ No newline at end of file diff --git a/src/libjin/graphics/bitmap.cpp b/src/libjin/graphics/bitmap.cpp index cae6f0b..b038d6c 100644 --- a/src/libjin/graphics/bitmap.cpp +++ b/src/libjin/graphics/bitmap.cpp @@ -12,178 +12,178 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Graphics - { - - Bitmap* Bitmap::clone() - { - Bitmap* b = new Bitmap(this); - return b; - } - - Bitmap::Bitmap() - : width(0) - , height(0) - , pixels(nullptr) - { - } - - Bitmap::Bitmap(unsigned w, unsigned h) - { - width = w; - height = h; - pixels = new Color[w*h]; - if (pixels == nullptr) - throw Exception("No enough memory."); - } - - Bitmap::Bitmap(const char* path) - { - AssetDatabase* ad = AssetDatabase::get(); - Buffer buffer; - ad->read(path, buffer); - new (this) Bitmap(&buffer, buffer.size()); - } - - Bitmap::Bitmap(const void* pix, unsigned w, unsigned h) - { - new (this) Bitmap(w, h); - memcpy(pixels, pix, w * h * sizeof(Color)); - } - - Bitmap::Bitmap(const void* imgData, size_t size) - { - if (imgData == nullptr) - return; - int w, h; - void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha); - if (data == nullptr) - { - throw Exception("Could not create bitmap from image data."); - return; - } - new (this) Bitmap(); - pixels = (Color*)data; - width = w; - height = h; - } - - Bitmap::Bitmap(int w, int h, Color color) - { - new (this) Bitmap(w, h); - if (color != Color::BLACK) - setPixels(color); - } - - Bitmap::Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer) - { - new (this) Bitmap(w, h); - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { - Color c = drawer(width, height, x, y); - setPixel(c, x, y); - } - } - } - - Bitmap::Bitmap(const Bitmap* bitmap) - { - new (this) Bitmap(); - int w = bitmap->getWidth(); - int h = bitmap->getHeight(); - resetPixels(bitmap->getPixels(), w, h); - } - - Bitmap::~Bitmap() - { - stbi_image_free(pixels); - } - - void Bitmap::bind(Color* p, int w, int h) - { - if (pixels != nullptr) - delete[] pixels; - pixels = p; - width = w; - height = h; - } - - void Bitmap::resetPixels(const Color* p, int w, int h) - { - if (pixels != nullptr) - delete[] pixels; - pixels = new Color[w*h]; - if (pixels == nullptr) - throw Exception("Not enough memory."); - size_t s = w * h * sizeof(Color); - memcpy(pixels, p, s); - width = w; - height = h; - } - - void Bitmap::setPixel(const Color& c, int x, int y) - { - if (pixels == nullptr) - throw Exception("Bitmap don't have pixel space."); - if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) - return; - if (x + y * width >= width * height) - throw Exception("Pixel <%d, %d> of bitmap is out of range.", x, y); - pixels[x + y * width] = c; - } - - void Bitmap::resetPixels(const Color& c, int w, int h) - { - if (pixels != nullptr) - delete[] pixels; - pixels = new Color[w*h]; - if (pixels == nullptr) - throw Exception("Not enough memory."); - width = w; - height = h; - for (int x = 0; x < w; ++x) - { - for (int y = 0; y < h; ++y) - { - pixels[x + y * w] = c; - } - } - } - - void Bitmap::setPixels(Color* p, int count) - { - if (count > width * height) - throw Exception("Pixels are out of range."); - size_t s = width * height * sizeof(Color); - memcpy(pixels, p, s); - } - - void Bitmap::setPixels(Color c) - { - for (int x = 0; x < width; ++x) - { - for (int y = 0; y < height; ++y) - { - pixels[x + y * width] = c; - } - } - } - - Color Bitmap::getPixel(int x, int y) - { - if (pixels == nullptr) - return Color::BLACK; - if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) - return Color::BLACK; - return pixels[x + y * width]; - } - - const Color* Bitmap::getPixels() const - { - return pixels; - } - - } // namespace Graphics + namespace Graphics + { + + Bitmap* Bitmap::clone() + { + Bitmap* b = new Bitmap(this); + return b; + } + + Bitmap::Bitmap() + : width(0) + , height(0) + , pixels(nullptr) + { + } + + Bitmap::Bitmap(unsigned w, unsigned h) + { + width = w; + height = h; + pixels = new Color[w*h]; + if (pixels == nullptr) + throw Exception("No enough memory."); + } + + Bitmap::Bitmap(const char* path) + { + AssetDatabase* ad = AssetDatabase::get(); + Buffer buffer; + ad->read(path, buffer); + new (this) Bitmap(&buffer, buffer.size()); + } + + Bitmap::Bitmap(const void* pix, unsigned w, unsigned h) + { + new (this) Bitmap(w, h); + memcpy(pixels, pix, w * h * sizeof(Color)); + } + + Bitmap::Bitmap(const void* imgData, size_t size) + { + if (imgData == nullptr) + return; + int w, h; + void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha); + if (data == nullptr) + { + throw Exception("Could not create bitmap from image data."); + return; + } + new (this) Bitmap(); + pixels = (Color*)data; + width = w; + height = h; + } + + Bitmap::Bitmap(int w, int h, Color color) + { + new (this) Bitmap(w, h); + if (color != Color::BLACK) + setPixels(color); + } + + Bitmap::Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer) + { + new (this) Bitmap(w, h); + for (int y = 0; y < height; ++y) + { + for (int x = 0; x < width; ++x) + { + Color c = drawer(width, height, x, y); + setPixel(c, x, y); + } + } + } + + Bitmap::Bitmap(const Bitmap* bitmap) + { + new (this) Bitmap(); + int w = bitmap->getWidth(); + int h = bitmap->getHeight(); + resetPixels(bitmap->getPixels(), w, h); + } + + Bitmap::~Bitmap() + { + stbi_image_free(pixels); + } + + void Bitmap::bind(Color* p, int w, int h) + { + if (pixels != nullptr) + delete[] pixels; + pixels = p; + width = w; + height = h; + } + + void Bitmap::resetPixels(const Color* p, int w, int h) + { + if (pixels != nullptr) + delete[] pixels; + pixels = new Color[w*h]; + if (pixels == nullptr) + throw Exception("Not enough memory."); + size_t s = w * h * sizeof(Color); + memcpy(pixels, p, s); + width = w; + height = h; + } + + void Bitmap::setPixel(const Color& c, int x, int y) + { + if (pixels == nullptr) + throw Exception("Bitmap don't have pixel space."); + if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) + return; + if (x + y * width >= width * height) + throw Exception("Pixel <%d, %d> of bitmap is out of range.", x, y); + pixels[x + y * width] = c; + } + + void Bitmap::resetPixels(const Color& c, int w, int h) + { + if (pixels != nullptr) + delete[] pixels; + pixels = new Color[w*h]; + if (pixels == nullptr) + throw Exception("Not enough memory."); + width = w; + height = h; + for (int x = 0; x < w; ++x) + { + for (int y = 0; y < h; ++y) + { + pixels[x + y * w] = c; + } + } + } + + void Bitmap::setPixels(Color* p, int count) + { + if (count > width * height) + throw Exception("Pixels are out of range."); + size_t s = width * height * sizeof(Color); + memcpy(pixels, p, s); + } + + void Bitmap::setPixels(Color c) + { + for (int x = 0; x < width; ++x) + { + for (int y = 0; y < height; ++y) + { + pixels[x + y * width] = c; + } + } + } + + Color Bitmap::getPixel(int x, int y) + { + if (pixels == nullptr) + return Color::BLACK; + if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) + return Color::BLACK; + return pixels[x + y * width]; + } + + const Color* Bitmap::getPixels() const + { + return pixels; + } + + } // namespace Graphics } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/graphics/bitmap.h b/src/libjin/graphics/bitmap.h index 17dca40..c42fc23 100644 --- a/src/libjin/graphics/bitmap.h +++ b/src/libjin/graphics/bitmap.h @@ -12,150 +12,150 @@ namespace JinEngine { - namespace Graphics - { - - /// - /// A RGBA32 bitmap. - /// - /// A bitmap keeps pixels and can't draw directly onto screen. To render bitmap, a texture is required. A - /// texture is a renderable hard ware side structure which could be handled with GPU. For instance, opengl - /// create texture and store it in GPU memory for rendering them onto hdc. - /// - class Bitmap : public Object - { - public: - /// - /// Constructor of bitmap. - /// - Bitmap(); - - /// - /// Constructor of bitmap. - /// - /// @param width Width of bitmap. - /// @param height Height of bitmap. - /// - Bitmap(unsigned w, unsigned h); - - Bitmap(const char* path); - - Bitmap(const void* pixels, unsigned w, unsigned h); - - Bitmap(const void* imgData, size_t size); - - Bitmap(int w, int h, Color color); - - Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer); - - Bitmap(const Bitmap* bitmap); - - /// - /// Destructor of bitmap - /// - virtual ~Bitmap(); - - /// - /// Create bitmap with another one. - /// - /// @param bitmap Bitmap be cloned. - /// @return Return bitmap pointer if created, otherwise return null. - /// - Bitmap* clone(); - - /// - /// Directly bind pixels with given pixels data - /// - /// @param pixels Pixels to be binded. - /// @param width Width of bitmap - /// @param height Height of bitmap - /// - void bind(Color* pixels, int width, int height); - - /// - /// Reset pixel data with given pixels data. - /// - /// @param pixels Pixels to be set. - /// @param width Width of bitmap - /// @param height Height of bitmap - /// - void resetPixels(const Color* pixels, int width, int height); - - /// - /// Reset pixel data with given color. - /// - /// @param color Color to be set. - /// @param width Width of bitmap - /// @param height Height of bitmap - /// - void resetPixels(const Color& color, int width, int height); - - /// - /// Set pixel with given color. - /// - /// @param color Color to be set. - /// @param x X value of pixel. - /// @param y Y value of pixel. - /// - void setPixel(const Color& color, int x, int y); - - /// - /// Set pixels with given color. - /// - /// @param color Color to be set. - /// - void setPixels(Color color); - - /// - /// Set pixels with given color data. - /// - /// @param colors New pixels' colors. - /// @param count Number of pixels. - /// - void setPixels(Color* colors, int count); - - /// - /// Get pixel in given position. - /// - /// @param x X value of position. - /// @param y Y value of position. - /// - Color getPixel(int x, int y); - - /// - /// Get pixels. - /// @return Colors of the bitmap. - /// - const Color* getPixels() const; - - /// - /// Get bitmap width. - /// - /// @return Width of bitmap. - /// - inline int getWidth() const { return width; } - - /// - /// Get bitmap height. - /// - /// @return Height of bitmap. - /// - inline int getHeight() const { return height; } - - /// - /// Get bitmap size. - /// - /// @return Size of bitmap. - /// - inline Math::Vector2<int> getSize() const { return Math::Vector2<int>(width, height); } - - protected: - Color * pixels; - unsigned width, height; - - }; - - } // namespace Graphics + namespace Graphics + { + + /// + /// A RGBA32 bitmap. + /// + /// A bitmap keeps pixels and can't draw directly onto screen. To render bitmap, a texture is required. A + /// texture is a renderable hard ware side structure which could be handled with GPU. For instance, opengl + /// create texture and store it in GPU memory for rendering them onto hdc. + /// + class Bitmap : public Object + { + public: + /// + /// Constructor of bitmap. + /// + Bitmap(); + + /// + /// Constructor of bitmap. + /// + /// @param width Width of bitmap. + /// @param height Height of bitmap. + /// + Bitmap(unsigned w, unsigned h); + + Bitmap(const char* path); + + Bitmap(const void* pixels, unsigned w, unsigned h); + + Bitmap(const void* imgData, size_t size); + + Bitmap(int w, int h, Color color); + + Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer); + + Bitmap(const Bitmap* bitmap); + + /// + /// Destructor of bitmap + /// + virtual ~Bitmap(); + + /// + /// Create bitmap with another one. + /// + /// @param bitmap Bitmap be cloned. + /// @return Return bitmap pointer if created, otherwise return null. + /// + Bitmap* clone(); + + /// + /// Directly bind pixels with given pixels data + /// + /// @param pixels Pixels to be binded. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void bind(Color* pixels, int width, int height); + + /// + /// Reset pixel data with given pixels data. + /// + /// @param pixels Pixels to be set. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void resetPixels(const Color* pixels, int width, int height); + + /// + /// Reset pixel data with given color. + /// + /// @param color Color to be set. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void resetPixels(const Color& color, int width, int height); + + /// + /// Set pixel with given color. + /// + /// @param color Color to be set. + /// @param x X value of pixel. + /// @param y Y value of pixel. + /// + void setPixel(const Color& color, int x, int y); + + /// + /// Set pixels with given color. + /// + /// @param color Color to be set. + /// + void setPixels(Color color); + + /// + /// Set pixels with given color data. + /// + /// @param colors New pixels' colors. + /// @param count Number of pixels. + /// + void setPixels(Color* colors, int count); + + /// + /// Get pixel in given position. + /// + /// @param x X value of position. + /// @param y Y value of position. + /// + Color getPixel(int x, int y); + + /// + /// Get pixels. + /// @return Colors of the bitmap. + /// + const Color* getPixels() const; + + /// + /// Get bitmap width. + /// + /// @return Width of bitmap. + /// + inline int getWidth() const { return width; } + + /// + /// Get bitmap height. + /// + /// @return Height of bitmap. + /// + inline int getHeight() const { return height; } + + /// + /// Get bitmap size. + /// + /// @return Size of bitmap. + /// + inline Math::Vector2<int> getSize() const { return Math::Vector2<int>(width, height); } + + protected: + Color * pixels; + unsigned width, height; + + }; + + } // namespace Graphics } // namespace JinEngine #endif diff --git a/src/libjin/graphics/canvas.cpp b/src/libjin/graphics/canvas.cpp index db02110..a5c757b 100644 --- a/src/libjin/graphics/canvas.cpp +++ b/src/libjin/graphics/canvas.cpp @@ -7,52 +7,52 @@ namespace JinEngine { - namespace Graphics - { - - Canvas::Canvas(GLuint n) - : fbo(n) - { - ++gl.getStats().canvases; - } - - Canvas::Canvas(int w, int h) - : Graphic(w, h) - { - GLint current_fbo; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - - // Generate a new render buffer object. - fbo = gl.genFrameBuffer(); - gl.bindFrameBuffer(fbo); - - // Render texture. - GLuint texture = getGLTexture(); - gl.bindTexture2D(texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - // Unbind framebuffer - gl.bindFrameBuffer(current_fbo); - - ++gl.getStats().canvases; - } - - Canvas::~Canvas() - { - --gl.getStats().canvases; - } - - bool Canvas::isBinded(const Canvas* cvs) - { - return gl.getCanvas() == cvs; - } - - } // namespace Graphics + namespace Graphics + { + + Canvas::Canvas(GLuint n) + : fbo(n) + { + ++gl.getStats().canvases; + } + + Canvas::Canvas(int w, int h) + : Graphic(w, h) + { + GLint current_fbo; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + + // Generate a new render buffer object. + fbo = gl.genFrameBuffer(); + gl.bindFrameBuffer(fbo); + + // Render texture. + GLuint texture = getGLTexture(); + gl.bindTexture2D(texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + // Unbind framebuffer + gl.bindFrameBuffer(current_fbo); + + ++gl.getStats().canvases; + } + + Canvas::~Canvas() + { + --gl.getStats().canvases; + } + + bool Canvas::isBinded(const Canvas* cvs) + { + return gl.getCanvas() == cvs; + } + + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/graphics/canvas.h b/src/libjin/graphics/canvas.h index 302764a..4ccf96c 100644 --- a/src/libjin/graphics/canvas.h +++ b/src/libjin/graphics/canvas.h @@ -7,45 +7,45 @@ namespace JinEngine { - namespace Graphics - { - /// - /// Renderable canvas. - /// - /// A canvas is a rendering target. - /// - class Canvas : public Graphic - { - public: - /// - /// - /// - static bool isBinded(const Canvas*); - - /// - /// Default canvas, aka screen. - /// - Canvas(GLuint n); - - /// - /// - /// - Canvas(int w, int h); - - /// - /// - /// - ~Canvas(); - - inline GLuint getGLFrameBuffer() const { return fbo; }; - - protected: - - GLuint fbo; - - }; - - } // namespace Graphics + namespace Graphics + { + /// + /// Renderable canvas. + /// + /// A canvas is a rendering target. + /// + class Canvas : public Graphic + { + public: + /// + /// + /// + static bool isBinded(const Canvas*); + + /// + /// Default canvas, aka screen. + /// + Canvas(GLuint n); + + /// + /// + /// + Canvas(int w, int h); + + /// + /// + /// + ~Canvas(); + + inline GLuint getGLFrameBuffer() const { return fbo; }; + + protected: + + GLuint fbo; + + }; + + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics) diff --git a/src/libjin/graphics/color.cpp b/src/libjin/graphics/color.cpp index 92f61c6..5b3492e 100644 --- a/src/libjin/graphics/color.cpp +++ b/src/libjin/graphics/color.cpp @@ -2,21 +2,21 @@ namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - const Color Color::WHITE = Color(255, 255, 255); - const Color Color::BLACK = Color(0, 0, 0); - const Color Color::RED = Color(255, 0, 0); - const Color Color::GREEN = Color(0, 255, 0); - const Color Color::BLUE = Color(0, 0, 255); - const Color Color::MAGENTA = Color(255, 0, 255); - const Color Color::YELLOW = Color(255, 255, 0); + const Color Color::WHITE = Color(255, 255, 255); + const Color Color::BLACK = Color(0, 0, 0); + const Color Color::RED = Color(255, 0, 0); + const Color Color::GREEN = Color(0, 255, 0); + const Color Color::BLUE = Color(0, 0, 255); + const Color Color::MAGENTA = Color(255, 0, 255); + const Color Color::YELLOW = Color(255, 255, 0); - const uint32 Color::RMASK = 0x000000ff; - const uint32 Color::GMASK = 0x0000ff00; - const uint32 Color::BMASK = 0x00ff0000; - const uint32 Color::AMASK = 0xff000000; + const uint32 Color::RMASK = 0x000000ff; + const uint32 Color::GMASK = 0x0000ff00; + const uint32 Color::BMASK = 0x00ff0000; + const uint32 Color::AMASK = 0xff000000; - } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/color.h b/src/libjin/graphics/color.h index 0f7d6dd..f10d918 100644 --- a/src/libjin/graphics/color.h +++ b/src/libjin/graphics/color.h @@ -13,105 +13,105 @@ namespace JinEngine { - namespace Graphics - { - - typedef uint8 Channel; - - class Color - { - public: - // Built-in colors - static const Color WHITE; - static const Color BLACK; - static const Color RED; - static const Color GREEN; - static const Color BLUE; - static const Color MAGENTA; - static const Color YELLOW; - - static const uint32 RMASK; - static const uint32 GMASK; - static const uint32 BMASK; - static const uint32 AMASK; - - /// - /// Get lerp color with given factor. - /// - /// @param start Start color. - /// @param end End color. - /// @param t Factor of interplation. - /// @return Color after interplation. - /// - static Color lerp(Color start, Color end, float t) - { - t = Math::clamp<float>(t, 0, 1); - Color c; - c.r = Math::lerp(start.r, end.r, t); - c.g = Math::lerp(start.g, end.g, t); - c.b = Math::lerp(start.b, end.b, t); - c.a = Math::lerp(start.a, end.a, t); - return c; - } - - /// - /// - /// - Color() { r = g = b = a = 0; }; - - /// - /// - /// - Color(unsigned char _r - , unsigned char _g - , unsigned char _b - , unsigned char _a = 255) - { - r = _r; - g = _g; - b = _b; - a = _a; - } - - Color(const Color& c) - { - r = c.r; - g = c.g; - b = c.b; - a = c.a; - } - - void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) - { - r = _r; - g = _g; - b = _b; - a = _a; - } - - void operator = (const Color& c) - { - r = c.r; - g = c.g; - b = c.b; - a = c.a; - } - - bool operator == (const Color& c) - { - return r == c.r && g == c.g && b == c.b && a == c.a; - } - - bool operator != (const Color& c) - { - return !(r == c.r && g == c.g && b == c.b && a == c.a); - } - - Channel r, g, b, a; - - }; - - } // namespace Graphics + namespace Graphics + { + + typedef uint8 Channel; + + class Color + { + public: + // Built-in colors + static const Color WHITE; + static const Color BLACK; + static const Color RED; + static const Color GREEN; + static const Color BLUE; + static const Color MAGENTA; + static const Color YELLOW; + + static const uint32 RMASK; + static const uint32 GMASK; + static const uint32 BMASK; + static const uint32 AMASK; + + /// + /// Get lerp color with given factor. + /// + /// @param start Start color. + /// @param end End color. + /// @param t Factor of interplation. + /// @return Color after interplation. + /// + static Color lerp(Color start, Color end, float t) + { + t = Math::clamp<float>(t, 0, 1); + Color c; + c.r = Math::lerp(start.r, end.r, t); + c.g = Math::lerp(start.g, end.g, t); + c.b = Math::lerp(start.b, end.b, t); + c.a = Math::lerp(start.a, end.a, t); + return c; + } + + /// + /// + /// + Color() { r = g = b = a = 0; }; + + /// + /// + /// + Color(unsigned char _r + , unsigned char _g + , unsigned char _b + , unsigned char _a = 255) + { + r = _r; + g = _g; + b = _b; + a = _a; + } + + Color(const Color& c) + { + r = c.r; + g = c.g; + b = c.b; + a = c.a; + } + + void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) + { + r = _r; + g = _g; + b = _b; + a = _a; + } + + void operator = (const Color& c) + { + r = c.r; + g = c.g; + b = c.b; + a = c.a; + } + + bool operator == (const Color& c) + { + return r == c.r && g == c.g && b == c.b && a == c.a; + } + + bool operator != (const Color& c) + { + return !(r == c.r && g == c.g && b == c.b && a == c.a); + } + + Channel r, g, b, a; + + }; + + } // namespace Graphics } // namespace JinEngine #endif // jin_graphics diff --git a/src/libjin/graphics/fonts/decoder.cpp b/src/libjin/graphics/fonts/decoder.cpp index 5c74258..2b6fb66 100644 --- a/src/libjin/graphics/fonts/decoder.cpp +++ b/src/libjin/graphics/fonts/decoder.cpp @@ -4,93 +4,93 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { + namespace Graphics + { + namespace Fonts + { - /* utf8 byte string to unicode codepoint */ - static const char *utf8toCodepoint(const char *p, unsigned *res) { - return nullptr; + /* utf8 byte string to unicode codepoint */ + static const char *utf8toCodepoint(const char *p, unsigned *res) { + return nullptr; - } + } - ///////////////////////////////////////////////////////////////////////////// - // decoders - ///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// + // decoders + ///////////////////////////////////////////////////////////////////////////// - const void* Utf8::decode(const void* data, Codepoint* res) const - { - const char* p = (char*)data; - unsigned x, mask, shift; - switch (*p & 0xf0) { - case 0xf0: mask = 0x07; shift = 18; break; - case 0xe0: mask = 0x0f; shift = 12; break; - case 0xc0: - case 0xd0: mask = 0x1f; shift = 6; break; - default: - *res = *p; - return p + 1; - } - x = (*p & mask) << shift; - do { - if (*(++p) == '\0') { - *res = x; - return p; - } - shift -= 6; - x |= (*p & 0x3f) << shift; - } while (shift); - *res = x; - return p + 1; - } + const void* Utf8::decode(const void* data, Codepoint* res) const + { + const char* p = (char*)data; + unsigned x, mask, shift; + switch (*p & 0xf0) { + case 0xf0: mask = 0x07; shift = 18; break; + case 0xe0: mask = 0x0f; shift = 12; break; + case 0xc0: + case 0xd0: mask = 0x1f; shift = 6; break; + default: + *res = *p; + return p + 1; + } + x = (*p & mask) << shift; + do { + if (*(++p) == '\0') { + *res = x; + return p; + } + shift -= 6; + x |= (*p & 0x3f) << shift; + } while (shift); + *res = x; + return p + 1; + } - const void* Utf8::next(const void* data) const - { - const char* p = (char*)data; - unsigned x, mask, shift; - switch (*p & 0xf0) { - case 0xf0: mask = 0x07; shift = 18; break; - case 0xe0: mask = 0x0f; shift = 12; break; - case 0xc0: - case 0xd0: mask = 0x1f; shift = 6; break; - default: - return p + 1; - } - x = (*p & mask) << shift; - do { - if (*(++p) == '\0') { - return p; - } - shift -= 6; - x |= (*p & 0x3f) << shift; - } while (shift); - return p + 1; - } - /* - const void* Utf16::decode(const void* data, Codepoint* res) const - { - return nullptr; - } + const void* Utf8::next(const void* data) const + { + const char* p = (char*)data; + unsigned x, mask, shift; + switch (*p & 0xf0) { + case 0xf0: mask = 0x07; shift = 18; break; + case 0xe0: mask = 0x0f; shift = 12; break; + case 0xc0: + case 0xd0: mask = 0x1f; shift = 6; break; + default: + return p + 1; + } + x = (*p & mask) << shift; + do { + if (*(++p) == '\0') { + return p; + } + shift -= 6; + x |= (*p & 0x3f) << shift; + } while (shift); + return p + 1; + } + /* + const void* Utf16::decode(const void* data, Codepoint* res) const + { + return nullptr; + } - const void* Utf16::next(const void* data) const - { - return nullptr; - } - */ - const void* Ascii::decode(const void* data, Codepoint* res) const - { - const char* p = (char*)data; - *res = *p; - return p + 1; - } + const void* Utf16::next(const void* data) const + { + return nullptr; + } + */ + const void* Ascii::decode(const void* data, Codepoint* res) const + { + const char* p = (char*)data; + *res = *p; + return p + 1; + } - const void* Ascii::next(const void* data) const - { - const char* p = (char*)data; - return p + 1; - } + const void* Ascii::next(const void* data) const + { + const char* p = (char*)data; + return p + 1; + } - } // namespace Fonts - } // namespace Graphics + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/graphics/fonts/decoder.h b/src/libjin/graphics/fonts/decoder.h index 8ff7bd7..e5e7bda 100644 --- a/src/libjin/graphics/fonts/decoder.h +++ b/src/libjin/graphics/fonts/decoder.h @@ -9,91 +9,91 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - /// - /// Text decoder. - /// - class Decoder : public Object - { - public: - - /// - /// Decode a code unit. - /// - /// @param data Code units. - /// @param codepoint Value of code point. - /// @return Next code unit location. - /// - virtual const void* decode(const void* data, Codepoint* codepoint) const = 0; - - /// - /// Get next code unit location. - /// - /// @param data Code units. - /// @return Next code unit location. - /// - virtual const void* next(const void* data) const = 0; - - }; - - /// - /// Utf-8 decoder. - /// - class Utf8 : public Decoder - { - public: - - /// - /// Decode a code unit. - /// - /// @param data Code units. - /// @param codepoint Value of code point. - /// @return Next code unit location. - /// - const void* decode(const void* data, Codepoint* codepoint) const override; - - /// - /// Get next code unit location. - /// - /// @param data Code units. - /// @return Next code unit location. - /// - const void* next(const void* data) const override; - - }; - - /// - /// Ascii decoder. - /// - class Ascii : public Decoder - { - public: - - /// - /// Decode a code unit. - /// - /// @param data Code units. - /// @param codepoint Value of code point. - /// @return Next code unit location. - /// - const void* decode(const void* data, Codepoint* codepoint) const override; - - /// - /// Get next code unit location. - /// - /// @param data Code units. - /// @return Next code unit location. - /// - const void* next(const void* data) const override; - - }; - - } // namespace Fonts - } // namespace Graphics + namespace Graphics + { + namespace Fonts + { + + /// + /// Text decoder. + /// + class Decoder : public Object + { + public: + + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + virtual const void* decode(const void* data, Codepoint* codepoint) const = 0; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + virtual const void* next(const void* data) const = 0; + + }; + + /// + /// Utf-8 decoder. + /// + class Utf8 : public Decoder + { + public: + + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + const void* decode(const void* data, Codepoint* codepoint) const override; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + const void* next(const void* data) const override; + + }; + + /// + /// Ascii decoder. + /// + class Ascii : public Decoder + { + public: + + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + const void* decode(const void* data, Codepoint* codepoint) const override; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + const void* next(const void* data) const override; + + }; + + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/fonts/font.h b/src/libjin/graphics/fonts/font.h index 166cd6b..b206a2d 100644 --- a/src/libjin/graphics/fonts/font.h +++ b/src/libjin/graphics/fonts/font.h @@ -9,108 +9,108 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - struct Page; - - // - // Font - // |- TTF - // |- TextureFont - // - - /// - /// Base Font class. - /// - class Font : public Object, public Renderable - { - public: - /// - /// Font constructor. - /// - Font(unsigned fontsize) - : mFontSize(fontsize) - { - ++gl.getStats().fonts; - } - - /// - /// Font destructor. - /// - virtual ~Font() - { - --gl.getStats().fonts; - }; - - /// - /// Create page with given text. - /// - /// @param text Text to be typesetted. - /// @param lineheight Line height of text. - /// @param spacing Spacing between characters. 0 by default. - /// @return Page if created successfully, otherwise return null. - /// - virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0; - - /// - /// Create page with given unicode codepoints. - /// - /// @param content Unicode codepoints to be typesetted. - /// @param lineheight Line height of text. - /// @param spacing Spacing between characters. 0 by default. - /// @return Page if created successfully, otherwise return null. - /// - virtual Page* typeset(const Content& content, int lineheight, int spacing = 0) = 0; - - /// - /// Render page to given position. - /// - /// @param page Page to be rendered. - /// @param x X value of the position. - /// @param y Y value of the position. - /// - virtual void render(const Page* page, int x, int y) = 0; - - /// - /// Render unicode codepoints to given position. - /// - /// @param content Unicode codepoints to be typesetted. - /// @param x X value of the position. - /// @param y Y value of the position. - /// @param lineheight Line height of the content. - /// @param spacing Spacing between characters. - /// - virtual void render(const Content& content, int x, int y, int lineheight, int spacing = 0) = 0; - - /// - /// Render text to given position. - /// - /// @param text Text to be rendered. - /// @param x X value of the position. - /// @param y Y value of the position. - /// @param lineheight Line height of the text. - /// @param spacing Spacing between characters. - /// - virtual void render(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0; - - /// - /// Get font size. - /// - /// @return Font size. - /// - inline unsigned getFontSize() { return mFontSize; }; - - protected: - - unsigned mFontSize; - - }; - - } // namespace Fonts - } // namespace Graphics + namespace Graphics + { + namespace Fonts + { + + struct Page; + + // + // Font + // |- TTF + // |- TextureFont + // + + /// + /// Base Font class. + /// + class Font : public Object, public Renderable + { + public: + /// + /// Font constructor. + /// + Font(unsigned fontsize) + : mFontSize(fontsize) + { + ++gl.getStats().fonts; + } + + /// + /// Font destructor. + /// + virtual ~Font() + { + --gl.getStats().fonts; + }; + + /// + /// Create page with given text. + /// + /// @param text Text to be typesetted. + /// @param lineheight Line height of text. + /// @param spacing Spacing between characters. 0 by default. + /// @return Page if created successfully, otherwise return null. + /// + virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0; + + /// + /// Create page with given unicode codepoints. + /// + /// @param content Unicode codepoints to be typesetted. + /// @param lineheight Line height of text. + /// @param spacing Spacing between characters. 0 by default. + /// @return Page if created successfully, otherwise return null. + /// + virtual Page* typeset(const Content& content, int lineheight, int spacing = 0) = 0; + + /// + /// Render page to given position. + /// + /// @param page Page to be rendered. + /// @param x X value of the position. + /// @param y Y value of the position. + /// + virtual void render(const Page* page, int x, int y) = 0; + + /// + /// Render unicode codepoints to given position. + /// + /// @param content Unicode codepoints to be typesetted. + /// @param x X value of the position. + /// @param y Y value of the position. + /// @param lineheight Line height of the content. + /// @param spacing Spacing between characters. + /// + virtual void render(const Content& content, int x, int y, int lineheight, int spacing = 0) = 0; + + /// + /// Render text to given position. + /// + /// @param text Text to be rendered. + /// @param x X value of the position. + /// @param y Y value of the position. + /// @param lineheight Line height of the text. + /// @param spacing Spacing between characters. + /// + virtual void render(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0; + + /// + /// Get font size. + /// + /// @return Font size. + /// + inline unsigned getFontSize() { return mFontSize; }; + + protected: + + unsigned mFontSize; + + }; + + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine #endif // __JE_FONT_H__ diff --git a/src/libjin/graphics/fonts/page.h b/src/libjin/graphics/fonts/page.h index 75f1840..0a9b5e2 100644 --- a/src/libjin/graphics/fonts/page.h +++ b/src/libjin/graphics/fonts/page.h @@ -7,48 +7,48 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - class Font; - - /// - /// Glyphs data to be rendered. - /// - struct GlyphVertex - { - int x, y; ///< screen coordinates - float u, v; ///< normalized texture uv - }; - - /// - /// Glyphs info for reducing draw call. - /// - struct GlyphArrayDrawInfo - { - GLuint texture; ///< atlas - unsigned int start; ///< glyph vertex indecies - unsigned int count; ///< glyph vertex count - }; - - /// - /// Page to be rendered. - /// - /// A page is a pre-rendered text struct for reducing draw call. Each page - /// keeps a font pointer which should not be changed. - /// - struct Page : public Object - { - Font* font; - std::vector<GlyphArrayDrawInfo> glyphinfolist; - std::vector<GlyphVertex> glyphvertices; - Math::Vector2<int> size; - }; - - } // namespace Fonts - } // namespace Graphics + namespace Graphics + { + namespace Fonts + { + + class Font; + + /// + /// Glyphs data to be rendered. + /// + struct GlyphVertex + { + int x, y; ///< screen coordinates + float u, v; ///< normalized texture uv + }; + + /// + /// Glyphs info for reducing draw call. + /// + struct GlyphArrayDrawInfo + { + GLuint texture; ///< atlas + unsigned int start; ///< glyph vertex indecies + unsigned int count; ///< glyph vertex count + }; + + /// + /// Page to be rendered. + /// + /// A page is a pre-rendered text struct for reducing draw call. Each page + /// keeps a font pointer which should not be changed. + /// + struct Page : public Object + { + Font* font; + std::vector<GlyphArrayDrawInfo> glyphinfolist; + std::vector<GlyphVertex> glyphvertices; + Math::Vector2<int> size; + }; + + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine #endif // __JE_PAGE_H__ diff --git a/src/libjin/graphics/fonts/text.cpp b/src/libjin/graphics/fonts/text.cpp index 9684b81..311c8c8 100644 --- a/src/libjin/graphics/fonts/text.cpp +++ b/src/libjin/graphics/fonts/text.cpp @@ -5,153 +5,153 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - ///////////////////////////////////////////////////////////////////////////// - // iterator - ///////////////////////////////////////////////////////////////////////////// - - Text::Iterator::Iterator(const Iterator& itor) - : data(itor.data) - , p(itor.p) - , encode(itor.encode) - , length(itor.length) - { - switch (encode) - { - case Encode::UTF8: decoder = new Utf8(); break; - case Encode::ASCII: decoder = new Ascii(); break; - } - } - - Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length) - : data(_data) - , p(_data) - , encode(_encode) - , length(_length) - { - switch (encode) - { - case Encode::UTF8: decoder = new Utf8(); break; - case Encode::ASCII: decoder = new Ascii(); break; - } - } - - Text::Iterator::~Iterator() - { - delete decoder; - } - - Codepoint Text::Iterator::get() - { - Codepoint codepoint; - decoder->decode(p, &codepoint); - return codepoint; - } - - Codepoint Text::Iterator::operator*() - { - return get(); - } - /* - Text::Iterator Text::Iterator::begin() - { - Iterator itor(encode, data, length); - itor.toBegin(); - return itor; - } - - Text::Iterator Text::Iterator::end() - { - Iterator itor(encode, data, length); - itor.toEnd(); - return itor; - } - */ - void Text::Iterator::toBegin() - { - p = (const unsigned char*)data; - } - - void Text::Iterator::toEnd() - { - p = (const unsigned char*)data + length; - } - - Text::Iterator& Text::Iterator::operator ++() - { - p = decoder->next(p); - return *this; - } - - Text::Iterator Text::Iterator::operator ++(int) - { - p = decoder->next(p); - Iterator itor(encode, data, length); - itor.p = p; - return itor; - } - - bool Text::Iterator::operator !=(const Iterator& itor) - { - return !(data == itor.data - && p == itor.p - && length == itor.length - && encode == itor.encode); - } - - bool Text::Iterator::operator ==(const Iterator& itor) - { - return data == itor.data - && p == itor.p - && length == itor.length - && encode == itor.encode; - } - - ///////////////////////////////////////////////////////////////////////////// - // text - ///////////////////////////////////////////////////////////////////////////// - - Text::Text(Encode encode, const void* data) - { - unsigned length = strlen((const char*)data); - Iterator end = Iterator(encode, data, length); - end.toEnd(); - Iterator it = Iterator(encode, data, length); - for (; it != end; ++it) - { - content.push_back(*it); - } - } - - Text::Text(Encode encode, const void* data, unsigned length) - { - Iterator end = Iterator(encode, data, length); - end.toEnd(); - Iterator it = Iterator(encode, data, length); - for (; it != end; ++it) - { - content.push_back(*it); - } - } - - Text::~Text() - { - } - - const Content& Text::getContent() const - { - return content; - } - - const Content& Text::operator*() const - { - return content; - } - - } // namespace Fonts - } // namespace Graphics + namespace Graphics + { + namespace Fonts + { + + ///////////////////////////////////////////////////////////////////////////// + // iterator + ///////////////////////////////////////////////////////////////////////////// + + Text::Iterator::Iterator(const Iterator& itor) + : data(itor.data) + , p(itor.p) + , encode(itor.encode) + , length(itor.length) + { + switch (encode) + { + case Encode::UTF8: decoder = new Utf8(); break; + case Encode::ASCII: decoder = new Ascii(); break; + } + } + + Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length) + : data(_data) + , p(_data) + , encode(_encode) + , length(_length) + { + switch (encode) + { + case Encode::UTF8: decoder = new Utf8(); break; + case Encode::ASCII: decoder = new Ascii(); break; + } + } + + Text::Iterator::~Iterator() + { + delete decoder; + } + + Codepoint Text::Iterator::get() + { + Codepoint codepoint; + decoder->decode(p, &codepoint); + return codepoint; + } + + Codepoint Text::Iterator::operator*() + { + return get(); + } + /* + Text::Iterator Text::Iterator::begin() + { + Iterator itor(encode, data, length); + itor.toBegin(); + return itor; + } + + Text::Iterator Text::Iterator::end() + { + Iterator itor(encode, data, length); + itor.toEnd(); + return itor; + } + */ + void Text::Iterator::toBegin() + { + p = (const unsigned char*)data; + } + + void Text::Iterator::toEnd() + { + p = (const unsigned char*)data + length; + } + + Text::Iterator& Text::Iterator::operator ++() + { + p = decoder->next(p); + return *this; + } + + Text::Iterator Text::Iterator::operator ++(int) + { + p = decoder->next(p); + Iterator itor(encode, data, length); + itor.p = p; + return itor; + } + + bool Text::Iterator::operator !=(const Iterator& itor) + { + return !(data == itor.data + && p == itor.p + && length == itor.length + && encode == itor.encode); + } + + bool Text::Iterator::operator ==(const Iterator& itor) + { + return data == itor.data + && p == itor.p + && length == itor.length + && encode == itor.encode; + } + + ///////////////////////////////////////////////////////////////////////////// + // text + ///////////////////////////////////////////////////////////////////////////// + + Text::Text(Encode encode, const void* data) + { + unsigned length = strlen((const char*)data); + Iterator end = Iterator(encode, data, length); + end.toEnd(); + Iterator it = Iterator(encode, data, length); + for (; it != end; ++it) + { + content.push_back(*it); + } + } + + Text::Text(Encode encode, const void* data, unsigned length) + { + Iterator end = Iterator(encode, data, length); + end.toEnd(); + Iterator it = Iterator(encode, data, length); + for (; it != end; ++it) + { + content.push_back(*it); + } + } + + Text::~Text() + { + } + + const Content& Text::getContent() const + { + return content; + } + + const Content& Text::operator*() const + { + return content; + } + + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/graphics/fonts/text.h b/src/libjin/graphics/fonts/text.h index c3bb8db..fe02d36 100644 --- a/src/libjin/graphics/fonts/text.h +++ b/src/libjin/graphics/fonts/text.h @@ -7,168 +7,168 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - typedef unsigned int Codepoint; - - typedef std::vector<Codepoint> Content; - - class Text; - - class Decoder; - - /// - /// Supported text encoding. - /// - enum Encode - { - UTF8, ///< utf-8 - ASCII, ///< ASCII - }; - - /// - /// Decoded text. Saved as unicode codepoints. - /// - class Text : public Object - { - public: - /// - /// - /// - Text(Encode encode, const void* data); - - /// - /// - /// - Text(Encode encode, const void* data, unsigned int length); - - /// - /// - /// - ~Text(); - - /// - /// - /// - const Content& getContent() const; - - /// - /// - /// - const Content& operator*() const; - - private: - /// - /// - /// - class Iterator - { - public: - - /// - /// - /// - Iterator(const Iterator& itor); - - /// - /// - /// - Iterator(const Encode& encode, const void* data, unsigned int length); - - /// - /// - /// - ~Iterator(); - - /// - /// - /// - Codepoint get(); - - //Iterator begin(); - //Iterator end(); - - /// - /// - /// - void toBegin(); - - /// - /// - /// - void toEnd(); - - /// - /// - /// - Codepoint operator *(); - - /// - /// - /// - Iterator& operator ++(); - - /// - /// - /// - Iterator operator ++(int); - - /// - /// - /// - bool operator !=(const Iterator& itor); - - /// - /// - /// - bool operator ==(const Iterator& itor); - - private: - - /// - /// - /// - void operator = (const Iterator&); - - /// - /// - /// - const Encode encode; - - /// - /// - /// - const Decoder* decoder; - - /// - /// - /// - const void* p; - - /// - /// - /// - const void* const data; - - /// - /// - /// - unsigned int length; - - }; - - /// - /// - /// - Content content; - - }; - - } - } // namespace Graphics + namespace Graphics + { + namespace Fonts + { + + typedef unsigned int Codepoint; + + typedef std::vector<Codepoint> Content; + + class Text; + + class Decoder; + + /// + /// Supported text encoding. + /// + enum Encode + { + UTF8, ///< utf-8 + ASCII, ///< ASCII + }; + + /// + /// Decoded text. Saved as unicode codepoints. + /// + class Text : public Object + { + public: + /// + /// + /// + Text(Encode encode, const void* data); + + /// + /// + /// + Text(Encode encode, const void* data, unsigned int length); + + /// + /// + /// + ~Text(); + + /// + /// + /// + const Content& getContent() const; + + /// + /// + /// + const Content& operator*() const; + + private: + /// + /// + /// + class Iterator + { + public: + + /// + /// + /// + Iterator(const Iterator& itor); + + /// + /// + /// + Iterator(const Encode& encode, const void* data, unsigned int length); + + /// + /// + /// + ~Iterator(); + + /// + /// + /// + Codepoint get(); + + //Iterator begin(); + //Iterator end(); + + /// + /// + /// + void toBegin(); + + /// + /// + /// + void toEnd(); + + /// + /// + /// + Codepoint operator *(); + + /// + /// + /// + Iterator& operator ++(); + + /// + /// + /// + Iterator operator ++(int); + + /// + /// + /// + bool operator !=(const Iterator& itor); + + /// + /// + /// + bool operator ==(const Iterator& itor); + + private: + + /// + /// + /// + void operator = (const Iterator&); + + /// + /// + /// + const Encode encode; + + /// + /// + /// + const Decoder* decoder; + + /// + /// + /// + const void* p; + + /// + /// + /// + const void* const data; + + /// + /// + /// + unsigned int length; + + }; + + /// + /// + /// + Content content; + + }; + + } + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/fonts/texture_font.cpp b/src/libjin/graphics/fonts/texture_font.cpp index 31e5293..33e3bf1 100644 --- a/src/libjin/graphics/fonts/texture_font.cpp +++ b/src/libjin/graphics/fonts/texture_font.cpp @@ -12,298 +12,298 @@ using namespace JinEngine::Graphics::Shaders; namespace JinEngine { - namespace Graphics - { - namespace Fonts - { + namespace Graphics + { + namespace Fonts + { - TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) - : Graphic(bitmap) - , Font(cellh) - { - TextureGlyph glyph; - Vector2<int> count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh); - glyph.w = cellw; - glyph.h = cellh; - for (int y = 0; y < count.row(); ++y) - { - glyph.y = y * cellh; - for (int x = 0; x < count.colum(); ++x) - { - glyph.x = x * cellw; - if (x + y * count.colum() >= codepoints.size()) - return; - glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum()], glyph)); - } - } - } + TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) + : Graphic(bitmap) + , Font(cellh) + { + TextureGlyph glyph; + Vector2<int> count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh); + glyph.w = cellw; + glyph.h = cellh; + for (int y = 0; y < count.row(); ++y) + { + glyph.y = y * cellh; + for (int x = 0; x < count.colum(); ++x) + { + glyph.x = x * cellw; + if (x + y * count.colum() >= codepoints.size()) + return; + glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum()], glyph)); + } + } + } - TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) - : Graphic(bitmap) - , Font(cellh) - { - TextureGlyph glyph; - glyph.h = cellh; - int w = bitmap->getWidth(); - int h = bitmap->getHeight(); - int i = 0; - for (int y = 0; y < h; y += cellh) - { - glyph.y = y; - bool newc = false; - for (int x = 0; x <= w; ++x) - { - if (x == w && newc) - { - glyph.w = x - glyph.x; - if (i >= codepoints.size()) - return; - glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph)); - ++i; - newc = false; - break; - } - Color c = bitmap->getPixels()[x + y * w]; - if (!newc && c != mask) - { - glyph.x = x; - newc = true; - } - else if (newc && c == mask) - { - glyph.w = x - glyph.x; - if (i >= codepoints.size()) - return; - glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph)); - if (codepoints[i] == 't') - { - int a = 10; - } - ++i; - newc = false; - } - } - } - } + TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) + : Graphic(bitmap) + , Font(cellh) + { + TextureGlyph glyph; + glyph.h = cellh; + int w = bitmap->getWidth(); + int h = bitmap->getHeight(); + int i = 0; + for (int y = 0; y < h; y += cellh) + { + glyph.y = y; + bool newc = false; + for (int x = 0; x <= w; ++x) + { + if (x == w && newc) + { + glyph.w = x - glyph.x; + if (i >= codepoints.size()) + return; + glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph)); + ++i; + newc = false; + break; + } + Color c = bitmap->getPixels()[x + y * w]; + if (!newc && c != mask) + { + glyph.x = x; + newc = true; + } + else if (newc && c == mask) + { + glyph.w = x - glyph.x; + if (i >= codepoints.size()) + return; + glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph)); + if (codepoints[i] == 't') + { + int a = 10; + } + ++i; + newc = false; + } + } + } + } - TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh) - : TextureFont(bitmap, *text, mask, cellh) - { - } + TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh) + : TextureFont(bitmap, *text, mask, cellh) + { + } - TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh) - : TextureFont(bitmap, *text, cellw, cellh) - { - } + TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh) + : TextureFont(bitmap, *text, cellw, cellh) + { + } - TextureFont::~TextureFont() - { - } + TextureFont::~TextureFont() + { + } - const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const - { - auto it = glyphs.find(codepoint); - if (it != glyphs.end()) - { - return &it->second; - } - else - return nullptr; - } + const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const + { + auto it = glyphs.find(codepoint); + if (it != glyphs.end()) + { + return &it->second; + } + else + return nullptr; + } - Page* TextureFont::typeset(const Content& text, int lineheight, int spacing) - { - Page* page = new Page(); - page->font = this; - vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - vector<GlyphVertex>& glyphvertices = page->glyphvertices; - int texture = -1; - const TextureGlyph* glyph = nullptr; - GlyphVertex vertex; - Vector2<int> p(0, 0); - int i = 0; + Page* TextureFont::typeset(const Content& text, int lineheight, int spacing) + { + Page* page = new Page(); + page->font = this; + vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + vector<GlyphVertex>& glyphvertices = page->glyphvertices; + int texture = -1; + const TextureGlyph* glyph = nullptr; + GlyphVertex vertex; + Vector2<int> p(0, 0); + int i = 0; #define glyphvertices_push(_x, _y, _u, _v) \ - vertex.x = _x; vertex.y = _y;\ - vertex.u = _u; vertex.v = _v;\ - glyphvertices.push_back(vertex);\ + vertex.x = _x; vertex.y = _y;\ + vertex.u = _u; vertex.v = _v;\ + glyphvertices.push_back(vertex);\ - for (Codepoint c : text) - { - // return - if (c == 0x0D) continue; - // newline - if (c == 0x0A) - { - p.y() += lineheight; - p.x() = 0; - continue; - } - if (c == 0x09) - { - // tab = 4*space - unsigned cw = getCharWidth(0x20); - p.x() += cw * 4; - continue; - } - glyph = findGlyph(c); - if (glyph == nullptr) continue; - if (texture != getGLTexture()) - { - texture = getGLTexture(); - GlyphArrayDrawInfo info; - info.start = i; - info.count = 0; - info.texture = texture; - glyphinfolist.push_back(info); - } - glyphinfolist[glyphinfolist.size() - 1].count += 4; - // normalized - float w = getWidth(), h = getHeight(); - float nx = glyph->x / w, ny = glyph->y / h; - float nw = glyph->w / w, nh = glyph->h / h; - glyphvertices_push(p.x(), p.y(), nx, ny); - glyphvertices_push(p.x(), p.y() + glyph->h, nx, ny + nh); - glyphvertices_push(p.x() + glyph->w, p.y() + glyph->h, nx + nw, ny + nh); - glyphvertices_push(p.x() + glyph->w, p.y(), nx + nw, ny); - p.x() += glyph->w + spacing; - i += 4; - } - getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing); - return page; - } + for (Codepoint c : text) + { + // return + if (c == 0x0D) continue; + // newline + if (c == 0x0A) + { + p.y() += lineheight; + p.x() = 0; + continue; + } + if (c == 0x09) + { + // tab = 4*space + unsigned cw = getCharWidth(0x20); + p.x() += cw * 4; + continue; + } + glyph = findGlyph(c); + if (glyph == nullptr) continue; + if (texture != getGLTexture()) + { + texture = getGLTexture(); + GlyphArrayDrawInfo info; + info.start = i; + info.count = 0; + info.texture = texture; + glyphinfolist.push_back(info); + } + glyphinfolist[glyphinfolist.size() - 1].count += 4; + // normalized + float w = getWidth(), h = getHeight(); + float nx = glyph->x / w, ny = glyph->y / h; + float nw = glyph->w / w, nh = glyph->h / h; + glyphvertices_push(p.x(), p.y(), nx, ny); + glyphvertices_push(p.x(), p.y() + glyph->h, nx, ny + nh); + glyphvertices_push(p.x() + glyph->w, p.y() + glyph->h, nx + nw, ny + nh); + glyphvertices_push(p.x() + glyph->w, p.y(), nx + nw, ny); + p.x() += glyph->w + spacing; + i += 4; + } + getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing); + return page; + } - int TextureFont::getCharWidth(int c) - { - auto it = glyphs.find(c); - if (it != glyphs.end()) - { - return it->second.w; - } - return 0; - } + int TextureFont::getCharWidth(int c) + { + auto it = glyphs.find(c); + if (it != glyphs.end()) + { + return it->second.w; + } + return 0; + } - int TextureFont::getCharHeight(int c) - { - auto it = glyphs.find(c); - if (it != glyphs.end()) - { - return it->second.h; - } - return 0; - } + int TextureFont::getCharHeight(int c) + { + auto it = glyphs.find(c); + if (it != glyphs.end()) + { + return it->second.h; + } + return 0; + } - int TextureFont::getTextWidth(const Content& t, int spacing) - { - int res = 0; - int tmp = 0; - for (Codepoint c : t) - { - if (c == 0x0D) - continue; - if (c == 0x0A) - { - tmp = 0; - continue; - } - if (c == 0x09) - { - // tab = 4*space - unsigned cw = getCharWidth(0x20); - tmp += cw * 4; - if (tmp > res) res = tmp; - continue; - } - tmp += getCharWidth(c) + spacing; - if (tmp > res) res = tmp; - } - return res; - } + int TextureFont::getTextWidth(const Content& t, int spacing) + { + int res = 0; + int tmp = 0; + for (Codepoint c : t) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + continue; + } + if (c == 0x09) + { + // tab = 4*space + unsigned cw = getCharWidth(0x20); + tmp += cw * 4; + if (tmp > res) res = tmp; + continue; + } + tmp += getCharWidth(c) + spacing; + if (tmp > res) res = tmp; + } + return res; + } - int TextureFont::getTextHeight(const Content& t, int lineheight) - { - int res = 0; - bool newline = true; - for (Codepoint c : t) - { - if (c == 0x0A) - newline = true; - else if (c == 0x0D); - else if (newline) - { - newline = false; - res += lineheight; - } - } - return res; - } + int TextureFont::getTextHeight(const Content& t, int lineheight) + { + int res = 0; + bool newline = true; + for (Codepoint c : t) + { + if (c == 0x0A) + newline = true; + else if (c == 0x0D); + else if (newline) + { + newline = false; + res += lineheight; + } + } + return res; + } - void TextureFont::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing) - { - *w = 0; - *h = 0; - int tmp = 0; - bool newline = true; - for (Codepoint c : text) - { - if (c == 0x0D) - continue; - if (c == 0x0A) - { - tmp = 0; - newline = true; - continue; - } - else if (newline) - { - newline = false; - *h += lineheight; - } - tmp += getCharWidth(c) + spacing; - if (tmp > *w) - *w = tmp; - } - } + void TextureFont::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing) + { + *w = 0; + *h = 0; + int tmp = 0; + bool newline = true; + for (Codepoint c : text) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + newline = true; + continue; + } + else if (newline) + { + newline = false; + *h += lineheight; + } + tmp += getCharWidth(c) + spacing; + if (tmp > *w) + *w = tmp; + } + } - Page* TextureFont::typeset(const Text& text, int lineheight, int spacing) - { - return typeset(*text, lineheight, spacing); - } + Page* TextureFont::typeset(const Text& text, int lineheight, int spacing) + { + return typeset(*text, lineheight, spacing); + } - void TextureFont::render(const Page* page, int x, int y) - { - Shader* shader = gl.getShader(); - const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - const vector<GlyphVertex>& glyphvertices = page->glyphvertices; - Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0); - shader->begin() - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); - for (int i = 0; i < glyphinfolist.size(); ++i) - { - const GlyphArrayDrawInfo& info = glyphinfolist[i]; - shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x) - .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); - gl.bindTexture2D(info.texture); - gl.drawArrays(GL_QUADS, 0, info.count); - } - shader->end(); - } + void TextureFont::render(const Page* page, int x, int y) + { + Shader* shader = gl.getShader(); + const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + const vector<GlyphVertex>& glyphvertices = page->glyphvertices; + Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0); + shader->begin() + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); + for (int i = 0; i < glyphinfolist.size(); ++i) + { + const GlyphArrayDrawInfo& info = glyphinfolist[i]; + shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x) + .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); + gl.bindTexture2D(info.texture); + gl.drawArrays(GL_QUADS, 0, info.count); + } + shader->end(); + } - void TextureFont::render(const Content& text, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(text, lineheight, spacing); - render(page, x, y); - delete page; - } + void TextureFont::render(const Content& text, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(text, lineheight, spacing); + render(page, x, y); + delete page; + } - void TextureFont::render(const Text& text, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(text, lineheight, spacing); - render(page, x, y); - delete page; - } + void TextureFont::render(const Text& text, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(text, lineheight, spacing); + render(page, x, y); + delete page; + } - } - } + } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/fonts/texture_font.h b/src/libjin/graphics/fonts/texture_font.h index 1d7f0d2..510badb 100644 --- a/src/libjin/graphics/fonts/texture_font.h +++ b/src/libjin/graphics/fonts/texture_font.h @@ -15,117 +15,117 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - /// - /// - /// - class TextureFont : public Font, public Graphic, public Object - { - public: - /// - /// - /// - TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh); - - /// - /// - /// - TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh); - - /// - /// - /// - TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh); - - /// - /// - /// - TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh); - - /// - /// - /// - ~TextureFont(); - - /// - /// - /// - Page* typeset(const Text& text, int lineheight, int spacing = 0) override; - - /// - /// - /// - Page* typeset(const Content& text, int lineheight, int spacing = 0) override; - - /// - /// - /// - void render(const Page* page, int x, int y) override; - - /// - /// - /// - void render(const Content& text, int x, int y, int linehgiht, int spacing = 0) override; - - /// - /// - /// - void render(const Text& text, int x, int y, int lineheight, int spacing = 0)override; - - private: - - /// - /// - /// - struct TextureGlyph - { - float x, y, w, h; - }; - - /// - /// - /// - int getCharWidth(int c); - - /// - /// - /// - int getCharHeight(int c); - - /// - /// - /// - int getTextWidth(const Content& text, int spacing = 0); - - /// - /// - /// - int getTextHeight(const Content& text, int lineheight); - - /// - /// - /// - void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0); - - /// - /// - /// - const TextureGlyph* findGlyph(Codepoint codepoint) const; - - - /// - /// - /// - std::map<Codepoint, TextureGlyph> glyphs; - - }; - - } // namespace Fonts - } // namespace Graphics + namespace Graphics + { + namespace Fonts + { + + /// + /// + /// + class TextureFont : public Font, public Graphic, public Object + { + public: + /// + /// + /// + TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh); + + /// + /// + /// + TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh); + + /// + /// + /// + TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh); + + /// + /// + /// + TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh); + + /// + /// + /// + ~TextureFont(); + + /// + /// + /// + Page* typeset(const Text& text, int lineheight, int spacing = 0) override; + + /// + /// + /// + Page* typeset(const Content& text, int lineheight, int spacing = 0) override; + + /// + /// + /// + void render(const Page* page, int x, int y) override; + + /// + /// + /// + void render(const Content& text, int x, int y, int linehgiht, int spacing = 0) override; + + /// + /// + /// + void render(const Text& text, int x, int y, int lineheight, int spacing = 0)override; + + private: + + /// + /// + /// + struct TextureGlyph + { + float x, y, w, h; + }; + + /// + /// + /// + int getCharWidth(int c); + + /// + /// + /// + int getCharHeight(int c); + + /// + /// + /// + int getTextWidth(const Content& text, int spacing = 0); + + /// + /// + /// + int getTextHeight(const Content& text, int lineheight); + + /// + /// + /// + void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0); + + /// + /// + /// + const TextureGlyph* findGlyph(Codepoint codepoint) const; + + + /// + /// + /// + std::map<Codepoint, TextureGlyph> glyphs; + + }; + + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/fonts/ttf.cpp b/src/libjin/graphics/fonts/ttf.cpp index 1357810..b540fda 100644 --- a/src/libjin/graphics/fonts/ttf.cpp +++ b/src/libjin/graphics/fonts/ttf.cpp @@ -19,438 +19,438 @@ using namespace JinEngine::Graphics::Shaders; namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // TTFData - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - TTFData::TTFData(const unsigned char* d, unsigned int s) - { - raw.size = s; - raw.data = (unsigned char*)malloc(s); - memcpy(raw.data, d, s); - if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0)) - { - delete raw.data; - throw 0; - } - /* push default fontsize */ - pushTTFsize(FONT_SIZE); - } - - TTFData::~TTFData() - { - free(raw.data); - } - - TTF* TTFData::createTTF(unsigned fontSize) - { - TTF* ttf; - try - { - ttf = new TTF(this, fontSize); - } - catch (...) - { - return nullptr; - } - return ttf; - } - - /* - * (0, 0) - * +--------------+ ascent - * | +--------+ | - * | | | | - * | | bitmap | | - * +--|--------|--+ baseline - * | +--------+ | - * +--|-----------+ decent - * | | - * leftSideBearing | - * advanceWidth - */ - void TTFData::getVMetrics(int* baseline, int* descent) - { - float scale = scales.back(); - int ascent; - stbtt_GetFontVMetrics(&info, &ascent, descent, 0); - *baseline = (int)(ascent*scale) + 1; // slight adjustment - *descent = *baseline - (int)(*descent*scale) + 1; - } - - void TTFData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing) - { - float scale = scales.back(); - int adw, lsb; - stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb); - *advanceWidth = (int)(adw*scale); - *leftSideBearing = (int)(lsb*scale); - } - - void TTFData::pushTTFsize(unsigned int fs) - { - float sc = stbtt_ScaleForPixelHeight(&info, fs); - scales.push_back(sc); - } - - void TTFData::popTTFsize() - { - /* always keep default ttf size on the bottom of stack */ - if (scales.size() > 1) - scales.pop_back(); - } - - Channel* TTFData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const - { - float scale = scales.back(); - Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff); - return bitmap; - } - - Color* TTFData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const - { - float scale = scales.back(); - Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff); - int w = *width, h = *height; - //int xo = *xoff, yo = *yoff; - Color* bitmap32 = new Color[w*h]; - for (int y = 0; y < h; ++y) - { - for (int x = 0; x < w; ++x) - { - bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]); - } - } - free(bitmap); - return bitmap32; - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // TTF - ////////////////////////////////////////////////////////////////////////////////////////////////////// + namespace Graphics + { + namespace Fonts + { + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // TTFData + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + TTFData::TTFData(const unsigned char* d, unsigned int s) + { + raw.size = s; + raw.data = (unsigned char*)malloc(s); + memcpy(raw.data, d, s); + if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0)) + { + delete raw.data; + throw 0; + } + /* push default fontsize */ + pushTTFsize(FONT_SIZE); + } + + TTFData::~TTFData() + { + free(raw.data); + } + + TTF* TTFData::createTTF(unsigned fontSize) + { + TTF* ttf; + try + { + ttf = new TTF(this, fontSize); + } + catch (...) + { + return nullptr; + } + return ttf; + } + + /* + * (0, 0) + * +--------------+ ascent + * | +--------+ | + * | | | | + * | | bitmap | | + * +--|--------|--+ baseline + * | +--------+ | + * +--|-----------+ decent + * | | + * leftSideBearing | + * advanceWidth + */ + void TTFData::getVMetrics(int* baseline, int* descent) + { + float scale = scales.back(); + int ascent; + stbtt_GetFontVMetrics(&info, &ascent, descent, 0); + *baseline = (int)(ascent*scale) + 1; // slight adjustment + *descent = *baseline - (int)(*descent*scale) + 1; + } + + void TTFData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing) + { + float scale = scales.back(); + int adw, lsb; + stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb); + *advanceWidth = (int)(adw*scale); + *leftSideBearing = (int)(lsb*scale); + } + + void TTFData::pushTTFsize(unsigned int fs) + { + float sc = stbtt_ScaleForPixelHeight(&info, fs); + scales.push_back(sc); + } + + void TTFData::popTTFsize() + { + /* always keep default ttf size on the bottom of stack */ + if (scales.size() > 1) + scales.pop_back(); + } + + Channel* TTFData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const + { + float scale = scales.back(); + Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff); + return bitmap; + } + + Color* TTFData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const + { + float scale = scales.back(); + Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff); + int w = *width, h = *height; + //int xo = *xoff, yo = *yoff; + Color* bitmap32 = new Color[w*h]; + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]); + } + } + free(bitmap); + return bitmap32; + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // TTF + ////////////////////////////////////////////////////////////////////////////////////////////////////// #include "../shaders/built-in/font.shader.h" - using namespace std; - using namespace JinEngine::Math; - - const int TTF::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 }; - const int TTF::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 }; - - /* little endian unicode */ - static const char* unicodeLittleEndian(const char* p, unsigned* res) - { - } - - //TTF* TTF::createTTF(TTFData* fontData, unsigned int fontSzie) - //{ - // TTF* ttf; - // try - // { - // ttf = new TTF(fontData, fontSzie); - // } - // catch (...) - // { - // return nullptr; - // } - // return ttf; - //} - - TTF::TTF(TTFData* f, unsigned int fontSize) - : Font(fontSize) - , cursor(0, 0) - , ttf(f) - { - ttf->pushTTFsize(fontSize); - ttf->getVMetrics(&baseline, &descent); - estimateSize(); - ttf->popTTFsize(); - /* create a default texture */ - createAtlas(); - } - - /* estimate the size of atlas texture */ - void TTF::estimateSize() - { - for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level) - { - if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level]) - { - textureWidth = TEXTURE_WIDTHS[level]; - textureHeight = TEXTURE_HEIGHTS[level]; - break; - } - } - } - - TTF::~TTF() - { - } - - GLuint TTF::createAtlas() - { - GLuint t; - gl.flushError(); - t = gl.genTexture(); - gl.bindTexture2D(t); - gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE); - if (glGetError() != GL_NO_ERROR) - { - glDeleteTextures(1, &t); - - return 0; - } - atlases.push_back(t); - - return t; - } - - void TTF::render(const Content& t, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(t, lineheight, spacing); - render(page, x, y); - delete page; - } - - Page* TTF::typeset(const Content& text, int lineheight, int spacing) - { - Page* page = new Page(); - page->font = this; - vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - vector<GlyphVertex>& glyphvertices = page->glyphvertices; - int texture = -1; - TTFGlyph* glyph = nullptr; - GlyphVertex vertex; - Vector2<int> p(0, 0); - int i = 0; - - #define glyphvertices_push(_x, _y, _u, _v) \ - vertex.x = _x; vertex.y = _y;\ - vertex.u = _u; vertex.v = _v;\ - glyphvertices.push_back(vertex); - - #define glyphlize(c)\ - do{\ - glyph = &findGlyph(c); \ - if (texture != glyph->atlas) \ - { \ - GlyphArrayDrawInfo info; \ - info.start = i; \ - info.count = 0; \ - info.texture = glyph->atlas; \ - texture = glyph->atlas; \ - glyphinfolist.push_back(info); \ - } \ - glyphinfolist[glyphinfolist.size() - 1].count += 4; \ - TTFGlyph::Bbox& bbox = glyph->bbox; \ - glyphvertices_push(p.x(), p.y(), bbox.x, bbox.y); \ - glyphvertices_push(p.x(), p.y() + glyph->height, bbox.x, bbox.y + bbox.h); \ - glyphvertices_push(p.x() + glyph->width, p.y() + glyph->height, bbox.x + bbox.w, bbox.y + bbox.h); \ - glyphvertices_push(p.x() + glyph->width, p.y(), bbox.x + bbox.w, bbox.y); \ - }while(0) - - for (Codepoint c : text) - { - if (c == 0x0D) - continue; - if (c == 0x0A) - { - /* new line */ - p.y() += lineheight; - p.x() = 0; - continue; - } - if (c == 0x09) - { - // tab = 4*space - unsigned cw = getCharWidth(0x20); - p.x() += cw * 4; - continue; - } - glyphlize(c); - p.x() += glyph->width + spacing; - i += 4; - } - getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing); - return page; - } - - Page* TTF::typeset(const Text& text, int lineheight, int spacing) - { - return typeset(*text, lineheight, spacing); - } - - void TTF::render(const Page* page, int x, int y) - { - Shader* shader = gl.getShader(); - const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - const vector<GlyphVertex>& glyphvertices = page->glyphvertices; - Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0); - shader->begin() - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); - for (int i = 0; i < glyphinfolist.size(); ++i) - { - const GlyphArrayDrawInfo& info = glyphinfolist[i]; - shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x) - .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); - gl.bindTexture2D(info.texture); - gl.drawArrays(GL_QUADS, 0, info.count); - - } - shader->end(); - } - - void TTF::render(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */) - { - render(*text, x, y, lineheight, spacing); - } - - int TTF::getCharWidth(int c) - { - int adw, lsb; - ttf->pushTTFsize(mFontSize); - ttf->getHMetrics(c, &adw, &lsb); - ttf->popTTFsize(); - return adw; - } - - int TTF::getCharHeight(int c) - { - return descent; - } - - int TTF::getTextWidth(const Content& t, int spacing) - { - ttf->pushTTFsize(mFontSize); - int res = 0; - int tmp = 0; - for (Codepoint c : t) - { - if (c == 0x0D) - continue; - if (c == 0x0A) - { - tmp = 0; - continue; - } - tmp += getCharWidth(c) + spacing; - if (tmp > res) - res = tmp; - } - ttf->popTTFsize(); - return res; - } - - int TTF::getTextHeight(const Content& t, int lineheight) - { - ttf->pushTTFsize(mFontSize); - int res = 0; - bool newline = true; - for (Codepoint c : t) - { - if (c == 0x0A) - newline = true; - else if (c == 0x0D); - else if (newline) - { - newline = false; - res += lineheight; - } - } - ttf->popTTFsize(); - return res; - } - - void TTF::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing) - { - ttf->pushTTFsize(mFontSize); - *w = 0; - *h = 0; - int tmp = 0; - bool newline = true; - for (Codepoint c : text) - { - if (c == 0x0D) - continue; - if (c == 0x0A) - { - tmp = 0; - newline = true; - continue; - } - else if (newline) - { - newline = false; - *h += lineheight; - } - tmp += getCharWidth(c) + spacing; - if (tmp > *w) - *w = tmp; - } - ttf->popTTFsize(); - } - - TTF::TTFGlyph& TTF::bakeGlyph(unsigned int character) - { - int w, h, xoff, yoff; - ttf->pushTTFsize(mFontSize); - GLuint atlas = atlases.back(); - const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff); - int adw, lsb; - { - /* bake glyph */ - ttf->getHMetrics(character, &adw, &lsb); - ttf->popTTFsize(); - if (cursor.x() + adw > textureWidth) - { - cursor.x() = 0; - cursor.y() += descent; - if (cursor.y() + descent * 2 > textureHeight) - { - /* create new atlas */ - atlas = createAtlas(); - cursor.y() = 0; - } - } - gl.bindTexture2D(atlas); - gl.texSubImage(cursor.x() + xoff, cursor.y() + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); - gl.bindTexture2D(); - delete[] bitmap; - } - TTFGlyph glyph; - glyph.atlas = atlas; - glyph.bbox.x = cursor.x() / (float)textureWidth; - glyph.bbox.y = cursor.y() / (float)textureHeight; - glyph.bbox.w = adw / (float)textureWidth; - glyph.bbox.h = descent / (float)textureHeight; - glyph.width = adw; - glyph.height = descent; - glyphs.insert(std::pair<unsigned int, TTFGlyph>(character, glyph)); - cursor.x() += adw; - return glyphs[character]; - } - - TTF::TTFGlyph& TTF::findGlyph(unsigned int character) - { - map<unsigned int, TTFGlyph>::iterator it = glyphs.find(character); - if (it != glyphs.end()) - return it->second; - else - return bakeGlyph(character); - } - - } // namespace Fonts - } // namespace Graphics + using namespace std; + using namespace JinEngine::Math; + + const int TTF::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 }; + const int TTF::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 }; + + /* little endian unicode */ + static const char* unicodeLittleEndian(const char* p, unsigned* res) + { + } + + //TTF* TTF::createTTF(TTFData* fontData, unsigned int fontSzie) + //{ + // TTF* ttf; + // try + // { + // ttf = new TTF(fontData, fontSzie); + // } + // catch (...) + // { + // return nullptr; + // } + // return ttf; + //} + + TTF::TTF(TTFData* f, unsigned int fontSize) + : Font(fontSize) + , cursor(0, 0) + , ttf(f) + { + ttf->pushTTFsize(fontSize); + ttf->getVMetrics(&baseline, &descent); + estimateSize(); + ttf->popTTFsize(); + /* create a default texture */ + createAtlas(); + } + + /* estimate the size of atlas texture */ + void TTF::estimateSize() + { + for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level) + { + if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level]) + { + textureWidth = TEXTURE_WIDTHS[level]; + textureHeight = TEXTURE_HEIGHTS[level]; + break; + } + } + } + + TTF::~TTF() + { + } + + GLuint TTF::createAtlas() + { + GLuint t; + gl.flushError(); + t = gl.genTexture(); + gl.bindTexture2D(t); + gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE); + if (glGetError() != GL_NO_ERROR) + { + glDeleteTextures(1, &t); + + return 0; + } + atlases.push_back(t); + + return t; + } + + void TTF::render(const Content& t, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(t, lineheight, spacing); + render(page, x, y); + delete page; + } + + Page* TTF::typeset(const Content& text, int lineheight, int spacing) + { + Page* page = new Page(); + page->font = this; + vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + vector<GlyphVertex>& glyphvertices = page->glyphvertices; + int texture = -1; + TTFGlyph* glyph = nullptr; + GlyphVertex vertex; + Vector2<int> p(0, 0); + int i = 0; + + #define glyphvertices_push(_x, _y, _u, _v) \ + vertex.x = _x; vertex.y = _y;\ + vertex.u = _u; vertex.v = _v;\ + glyphvertices.push_back(vertex); + + #define glyphlize(c)\ + do{\ + glyph = &findGlyph(c); \ + if (texture != glyph->atlas) \ + { \ + GlyphArrayDrawInfo info; \ + info.start = i; \ + info.count = 0; \ + info.texture = glyph->atlas; \ + texture = glyph->atlas; \ + glyphinfolist.push_back(info); \ + } \ + glyphinfolist[glyphinfolist.size() - 1].count += 4; \ + TTFGlyph::Bbox& bbox = glyph->bbox; \ + glyphvertices_push(p.x(), p.y(), bbox.x, bbox.y); \ + glyphvertices_push(p.x(), p.y() + glyph->height, bbox.x, bbox.y + bbox.h); \ + glyphvertices_push(p.x() + glyph->width, p.y() + glyph->height, bbox.x + bbox.w, bbox.y + bbox.h); \ + glyphvertices_push(p.x() + glyph->width, p.y(), bbox.x + bbox.w, bbox.y); \ + }while(0) + + for (Codepoint c : text) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + /* new line */ + p.y() += lineheight; + p.x() = 0; + continue; + } + if (c == 0x09) + { + // tab = 4*space + unsigned cw = getCharWidth(0x20); + p.x() += cw * 4; + continue; + } + glyphlize(c); + p.x() += glyph->width + spacing; + i += 4; + } + getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing); + return page; + } + + Page* TTF::typeset(const Text& text, int lineheight, int spacing) + { + return typeset(*text, lineheight, spacing); + } + + void TTF::render(const Page* page, int x, int y) + { + Shader* shader = gl.getShader(); + const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + const vector<GlyphVertex>& glyphvertices = page->glyphvertices; + Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0); + shader->begin() + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); + for (int i = 0; i < glyphinfolist.size(); ++i) + { + const GlyphArrayDrawInfo& info = glyphinfolist[i]; + shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x) + .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); + gl.bindTexture2D(info.texture); + gl.drawArrays(GL_QUADS, 0, info.count); + + } + shader->end(); + } + + void TTF::render(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */) + { + render(*text, x, y, lineheight, spacing); + } + + int TTF::getCharWidth(int c) + { + int adw, lsb; + ttf->pushTTFsize(mFontSize); + ttf->getHMetrics(c, &adw, &lsb); + ttf->popTTFsize(); + return adw; + } + + int TTF::getCharHeight(int c) + { + return descent; + } + + int TTF::getTextWidth(const Content& t, int spacing) + { + ttf->pushTTFsize(mFontSize); + int res = 0; + int tmp = 0; + for (Codepoint c : t) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + continue; + } + tmp += getCharWidth(c) + spacing; + if (tmp > res) + res = tmp; + } + ttf->popTTFsize(); + return res; + } + + int TTF::getTextHeight(const Content& t, int lineheight) + { + ttf->pushTTFsize(mFontSize); + int res = 0; + bool newline = true; + for (Codepoint c : t) + { + if (c == 0x0A) + newline = true; + else if (c == 0x0D); + else if (newline) + { + newline = false; + res += lineheight; + } + } + ttf->popTTFsize(); + return res; + } + + void TTF::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing) + { + ttf->pushTTFsize(mFontSize); + *w = 0; + *h = 0; + int tmp = 0; + bool newline = true; + for (Codepoint c : text) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + newline = true; + continue; + } + else if (newline) + { + newline = false; + *h += lineheight; + } + tmp += getCharWidth(c) + spacing; + if (tmp > *w) + *w = tmp; + } + ttf->popTTFsize(); + } + + TTF::TTFGlyph& TTF::bakeGlyph(unsigned int character) + { + int w, h, xoff, yoff; + ttf->pushTTFsize(mFontSize); + GLuint atlas = atlases.back(); + const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff); + int adw, lsb; + { + /* bake glyph */ + ttf->getHMetrics(character, &adw, &lsb); + ttf->popTTFsize(); + if (cursor.x() + adw > textureWidth) + { + cursor.x() = 0; + cursor.y() += descent; + if (cursor.y() + descent * 2 > textureHeight) + { + /* create new atlas */ + atlas = createAtlas(); + cursor.y() = 0; + } + } + gl.bindTexture2D(atlas); + gl.texSubImage(cursor.x() + xoff, cursor.y() + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); + gl.bindTexture2D(); + delete[] bitmap; + } + TTFGlyph glyph; + glyph.atlas = atlas; + glyph.bbox.x = cursor.x() / (float)textureWidth; + glyph.bbox.y = cursor.y() / (float)textureHeight; + glyph.bbox.w = adw / (float)textureWidth; + glyph.bbox.h = descent / (float)textureHeight; + glyph.width = adw; + glyph.height = descent; + glyphs.insert(std::pair<unsigned int, TTFGlyph>(character, glyph)); + cursor.x() += adw; + return glyphs[character]; + } + + TTF::TTFGlyph& TTF::findGlyph(unsigned int character) + { + map<unsigned int, TTFGlyph>::iterator it = glyphs.find(character); + if (it != glyphs.end()) + return it->second; + else + return bakeGlyph(character); + } + + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/graphics/fonts/ttf.h b/src/libjin/graphics/fonts/ttf.h index 8439cd7..5b137ff 100644 --- a/src/libjin/graphics/fonts/ttf.h +++ b/src/libjin/graphics/fonts/ttf.h @@ -19,266 +19,266 @@ namespace JinEngine { - namespace Graphics - { - namespace Fonts - { - - class TTF; - - // - // TTFData - // |- TTF(14px) - // |- TTF(15px) - // . - // . - // . - // - class TTFData : public Object - { - public: - /// - /// - /// - TTFData(const unsigned char* data, unsigned int size); - - /// - /// - /// - ~TTFData(); - - /// - /// - /// - TTF* createTTF(unsigned ttfsize); - - /// - /// - /// - void pushTTFsize(unsigned ttfsize); - - /// - /// - /// - void popTTFsize(); - - /// - /// - /// - Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const; - - /// - /// - /// - Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const; - - /// - /// - /// - void getVMetrics(int* baseline, int* descent); - - /// - /// - /// - void getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing); - - private: - - /// - /// - /// - static const unsigned int FONT_SIZE = 12; - - /// - /// - /// - stbtt_fontinfo info; - - /// - /// - /// - struct - { - unsigned char* data; - unsigned int size; - } raw; - - /// - /// - /// - std::vector<float> scales; - - }; - - class TTF : public Font, public Object - { - public: - //static TTF* createTTF(TTFData* ttfData, unsigned ttfSzie); - - /// - /// - /// - Page* typeset(const Text& text, int lineheight, int spacing = 0) override; - - /// - /// - /// - Page* typeset(const Content& text, int lineheight, int spacing = 0) override; - - /// - /// - /// - void render(const Text& text, int x, int y, int lineheight, int spacing = 0) override; - - /// - /// - /// - void render(const Content& text, int x, int y, int lineheight, int spacing = 0) override; - - /// - /// - /// - void render(const Page* page, int x, int y) override; - - /// - /// - /// - ~TTF(); - - private: - - friend class TTFData; - - /// - /// - /// - struct TTFGlyph - { - GLuint atlas; - // normalized coordinates - struct Bbox - { - float x, y; - float w, h; - } bbox; - // glyph size in pixel - unsigned int width, height; - }; - - /// - /// - /// - static const int TEXTURE_SIZE_LEVELS_COUNT = 7; - - /// - /// - /// - static const int TEXTURE_SIZE_LEVEL_MAX = TEXTURE_SIZE_LEVELS_COUNT - 1; - - /// - /// - /// - static const int TEXTURE_WIDTHS[TEXTURE_SIZE_LEVELS_COUNT]; - - /// - /// - /// - static const int TEXTURE_HEIGHTS[TEXTURE_SIZE_LEVELS_COUNT]; - - /// - /// - /// - TTF(TTFData* ttf, Codepoint ttfSize); - - /// - /// - /// - void estimateSize(); - - /// - /// - /// - GLuint createAtlas(); - - /// - /// - /// - TTFGlyph& bakeGlyph(Codepoint character); - - /// - /// - /// - TTFGlyph& findGlyph(Codepoint character); - - /// - /// - /// - int getCharWidth(int c); - - /// - /// - /// - int getCharHeight(int c); - - /// - /// - /// - int getTextWidth(const Content& text, int spacing = 0); - - /// - /// - /// - int getTextHeight(const Content& text, int lineheight); - - /// - /// - /// - void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0); - - /// - /// - /// - int textureWidth; - - /// - /// - /// - int textureHeight; - - /// - /// - /// - std::vector<GLuint> atlases; - - /// - /// - /// - std::map<Codepoint, TTFGlyph> glyphs; - - /// - /// - /// - TTFData* ttf; - - /// - /// - /// - int baseline; - - /// - /// - /// - int descent; - - /// - /// - /// - Math::Vector2<float> cursor; - - }; - - } // namespace Fonts - } // namespace Graphics + namespace Graphics + { + namespace Fonts + { + + class TTF; + + // + // TTFData + // |- TTF(14px) + // |- TTF(15px) + // . + // . + // . + // + class TTFData : public Object + { + public: + /// + /// + /// + TTFData(const unsigned char* data, unsigned int size); + + /// + /// + /// + ~TTFData(); + + /// + /// + /// + TTF* createTTF(unsigned ttfsize); + + /// + /// + /// + void pushTTFsize(unsigned ttfsize); + + /// + /// + /// + void popTTFsize(); + + /// + /// + /// + Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const; + + /// + /// + /// + Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const; + + /// + /// + /// + void getVMetrics(int* baseline, int* descent); + + /// + /// + /// + void getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing); + + private: + + /// + /// + /// + static const unsigned int FONT_SIZE = 12; + + /// + /// + /// + stbtt_fontinfo info; + + /// + /// + /// + struct + { + unsigned char* data; + unsigned int size; + } raw; + + /// + /// + /// + std::vector<float> scales; + + }; + + class TTF : public Font, public Object + { + public: + //static TTF* createTTF(TTFData* ttfData, unsigned ttfSzie); + + /// + /// + /// + Page* typeset(const Text& text, int lineheight, int spacing = 0) override; + + /// + /// + /// + Page* typeset(const Content& text, int lineheight, int spacing = 0) override; + + /// + /// + /// + void render(const Text& text, int x, int y, int lineheight, int spacing = 0) override; + + /// + /// + /// + void render(const Content& text, int x, int y, int lineheight, int spacing = 0) override; + + /// + /// + /// + void render(const Page* page, int x, int y) override; + + /// + /// + /// + ~TTF(); + + private: + + friend class TTFData; + + /// + /// + /// + struct TTFGlyph + { + GLuint atlas; + // normalized coordinates + struct Bbox + { + float x, y; + float w, h; + } bbox; + // glyph size in pixel + unsigned int width, height; + }; + + /// + /// + /// + static const int TEXTURE_SIZE_LEVELS_COUNT = 7; + + /// + /// + /// + static const int TEXTURE_SIZE_LEVEL_MAX = TEXTURE_SIZE_LEVELS_COUNT - 1; + + /// + /// + /// + static const int TEXTURE_WIDTHS[TEXTURE_SIZE_LEVELS_COUNT]; + + /// + /// + /// + static const int TEXTURE_HEIGHTS[TEXTURE_SIZE_LEVELS_COUNT]; + + /// + /// + /// + TTF(TTFData* ttf, Codepoint ttfSize); + + /// + /// + /// + void estimateSize(); + + /// + /// + /// + GLuint createAtlas(); + + /// + /// + /// + TTFGlyph& bakeGlyph(Codepoint character); + + /// + /// + /// + TTFGlyph& findGlyph(Codepoint character); + + /// + /// + /// + int getCharWidth(int c); + + /// + /// + /// + int getCharHeight(int c); + + /// + /// + /// + int getTextWidth(const Content& text, int spacing = 0); + + /// + /// + /// + int getTextHeight(const Content& text, int lineheight); + + /// + /// + /// + void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0); + + /// + /// + /// + int textureWidth; + + /// + /// + /// + int textureHeight; + + /// + /// + /// + std::vector<GLuint> atlases; + + /// + /// + /// + std::map<Codepoint, TTFGlyph> glyphs; + + /// + /// + /// + TTFData* ttf; + + /// + /// + /// + int baseline; + + /// + /// + /// + int descent; + + /// + /// + /// + Math::Vector2<float> cursor; + + }; + + } // namespace Fonts + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics) diff --git a/src/libjin/graphics/graphic.cpp b/src/libjin/graphics/graphic.cpp index 7659e4e..67e416a 100644 --- a/src/libjin/graphics/graphic.cpp +++ b/src/libjin/graphics/graphic.cpp @@ -14,132 +14,132 @@ using namespace JinEngine::Graphics::Shaders; namespace JinEngine { - namespace Graphics - { - - Graphic::Graphic(int w, int h) - : mTexture(0) - , mSize(w, h) - { - mTexture = gl.genTexture(); - } - - Graphic::Graphic(const Bitmap* bitmap) - : mTexture(0) - { - mSize.w() = bitmap->getWidth(); - mSize.h() = bitmap->getHeight(); - - const Color* pixels = bitmap->getPixels(); - - mTexture = gl.genTexture(); - gl.bindTexture2D(mTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl.texImage(GL_RGBA8, mSize.w(), mSize.h(), GL_RGBA, GL_UNSIGNED_BYTE, pixels); - } - - Graphic::~Graphic() - { - glDeleteTextures(1, &mTexture); - } - - void Graphic::setFilter(GLint min_filter, GLint max_filter) - { - gl.bindTexture2D(mTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter); - } - - void Graphic::render(float x, float y, float sx, float sy, float r, float ox, float oy) const - { - Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy); - int w = getWidth(), h = getHeight(); - static float vertexCoords[8]; - static float textureCoords[8]; - // Set vertex coordinates. - vertexCoords[0] = 0; vertexCoords[1] = 0; - vertexCoords[2] = 0; vertexCoords[3] = h; - vertexCoords[4] = w; vertexCoords[5] = h; - vertexCoords[6] = w; vertexCoords[7] = 0; - // Set texture coordinates. - textureCoords[0] = 0; textureCoords[1] = 0; - textureCoords[2] = 0; textureCoords[3] = 1; - textureCoords[4] = 1; textureCoords[5] = 1; - textureCoords[6] = 1; textureCoords[7] = 0; - // Set shader. - Shader* shader = gl.getShader(); - shader->begin() - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) - .uploadVertices(2, GL_FLOAT, 0, vertexCoords) - .uploadUV(2, GL_FLOAT, 0, textureCoords); - - gl.bindTexture2D(mTexture); - gl.drawArrays(GL_QUADS, 0, 4); - - shader->end(); - } - - void Graphic::render(const Math::Quad& slice, float x, float y, float sx, float sy, float r, float ax, float ay) const - { - static float vertexCoords[8]; - static float textureCoords[8]; - - // Set vertex coordinates. - vertexCoords[0] = 0; vertexCoords[1] = 0; - vertexCoords[2] = 0; vertexCoords[3] = slice.h; - vertexCoords[4] = slice.w; vertexCoords[5] = slice.h; - vertexCoords[6] = slice.w; vertexCoords[7] = 0; - // Set texture coordinates. - float slx = slice.x / mSize.w(); - float sly = slice.y / mSize.h(); - float slw = slice.w / mSize.w(); - float slh = slice.h / mSize.h(); - textureCoords[0] = slx; textureCoords[1] = sly; - textureCoords[2] = slx; textureCoords[3] = sly + slh; - textureCoords[4] = slx + slw; textureCoords[5] = sly + slh; - textureCoords[6] = slx + slw; textureCoords[7] = sly; - - Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ax, ay); - - Shader* shader = gl.getShader(); - shader->begin() - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) - .uploadVertices(2, GL_FLOAT, 0, vertexCoords) - .uploadUV(2, GL_FLOAT, 0, textureCoords); - - gl.bindTexture2D(mTexture); - gl.drawArrays(GL_QUADS, 0, 4); - - shader->end(); - } - - void Graphic::render(const Math::Transform& transform) const - { - Vector2<float> position = transform.getPosition(); - Vector2<float> origin = transform.getOrigin(); - Vector2<float> scale = transform.getScale(); - float angle = transform.getRotation(); - render(position.x(), position.y(), scale.x(), scale.y(), angle, origin.x(), origin.y()); - } - - void Graphic::render(const Math::Quad& slice, const Math::Transform& transform) const - { - Vector2<float> position = transform.getPosition(); - Vector2<float> origin = transform.getOrigin(); - Vector2<float> scale = transform.getScale(); - float angle = transform.getRotation(); - render(slice, position.x(), position.y(), scale.x(), scale.y(), angle, origin.x(), origin.y()); - } - - //void Graphic::setFilter(GLint min, GLint max) - //{ - // glTexParameteri(GL_) - //} - - } // namespace Graphics + namespace Graphics + { + + Graphic::Graphic(int w, int h) + : mTexture(0) + , mSize(w, h) + { + mTexture = gl.genTexture(); + } + + Graphic::Graphic(const Bitmap* bitmap) + : mTexture(0) + { + mSize.w() = bitmap->getWidth(); + mSize.h() = bitmap->getHeight(); + + const Color* pixels = bitmap->getPixels(); + + mTexture = gl.genTexture(); + gl.bindTexture2D(mTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl.texImage(GL_RGBA8, mSize.w(), mSize.h(), GL_RGBA, GL_UNSIGNED_BYTE, pixels); + } + + Graphic::~Graphic() + { + glDeleteTextures(1, &mTexture); + } + + void Graphic::setFilter(GLint min_filter, GLint max_filter) + { + gl.bindTexture2D(mTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter); + } + + void Graphic::render(float x, float y, float sx, float sy, float r, float ox, float oy) const + { + Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy); + int w = getWidth(), h = getHeight(); + static float vertexCoords[8]; + static float textureCoords[8]; + // Set vertex coordinates. + vertexCoords[0] = 0; vertexCoords[1] = 0; + vertexCoords[2] = 0; vertexCoords[3] = h; + vertexCoords[4] = w; vertexCoords[5] = h; + vertexCoords[6] = w; vertexCoords[7] = 0; + // Set texture coordinates. + textureCoords[0] = 0; textureCoords[1] = 0; + textureCoords[2] = 0; textureCoords[3] = 1; + textureCoords[4] = 1; textureCoords[5] = 1; + textureCoords[6] = 1; textureCoords[7] = 0; + // Set shader. + Shader* shader = gl.getShader(); + shader->begin() + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) + .uploadVertices(2, GL_FLOAT, 0, vertexCoords) + .uploadUV(2, GL_FLOAT, 0, textureCoords); + + gl.bindTexture2D(mTexture); + gl.drawArrays(GL_QUADS, 0, 4); + + shader->end(); + } + + void Graphic::render(const Math::Quad& slice, float x, float y, float sx, float sy, float r, float ax, float ay) const + { + static float vertexCoords[8]; + static float textureCoords[8]; + + // Set vertex coordinates. + vertexCoords[0] = 0; vertexCoords[1] = 0; + vertexCoords[2] = 0; vertexCoords[3] = slice.h; + vertexCoords[4] = slice.w; vertexCoords[5] = slice.h; + vertexCoords[6] = slice.w; vertexCoords[7] = 0; + // Set texture coordinates. + float slx = slice.x / mSize.w(); + float sly = slice.y / mSize.h(); + float slw = slice.w / mSize.w(); + float slh = slice.h / mSize.h(); + textureCoords[0] = slx; textureCoords[1] = sly; + textureCoords[2] = slx; textureCoords[3] = sly + slh; + textureCoords[4] = slx + slw; textureCoords[5] = sly + slh; + textureCoords[6] = slx + slw; textureCoords[7] = sly; + + Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ax, ay); + + Shader* shader = gl.getShader(); + shader->begin() + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) + .uploadVertices(2, GL_FLOAT, 0, vertexCoords) + .uploadUV(2, GL_FLOAT, 0, textureCoords); + + gl.bindTexture2D(mTexture); + gl.drawArrays(GL_QUADS, 0, 4); + + shader->end(); + } + + void Graphic::render(const Math::Transform& transform) const + { + Vector2<float> position = transform.getPosition(); + Vector2<float> origin = transform.getOrigin(); + Vector2<float> scale = transform.getScale(); + float angle = transform.getRotation(); + render(position.x(), position.y(), scale.x(), scale.y(), angle, origin.x(), origin.y()); + } + + void Graphic::render(const Math::Quad& slice, const Math::Transform& transform) const + { + Vector2<float> position = transform.getPosition(); + Vector2<float> origin = transform.getOrigin(); + Vector2<float> scale = transform.getScale(); + float angle = transform.getRotation(); + render(slice, position.x(), position.y(), scale.x(), scale.y(), angle, origin.x(), origin.y()); + } + + //void Graphic::setFilter(GLint min, GLint max) + //{ + // glTexParameteri(GL_) + //} + + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/graphics/graphic.h b/src/libjin/graphics/graphic.h index 857785d..fdb1c9c 100644 --- a/src/libjin/graphics/graphic.h +++ b/src/libjin/graphics/graphic.h @@ -14,82 +14,82 @@ namespace JinEngine { - namespace Graphics - { - - /// - /// Class inherites Graphic doesn't keep any state such as origin, scale and other properties. Very low - /// level visualized resources. - /// - class Graphic : public Object, public Renderable - { - public: - /// - /// - /// - Graphic(int w = 0, int h = 0); - - /// - /// - /// - Graphic(const Bitmap* bitmap); - - /// - /// - /// - virtual ~Graphic(); - - /// - /// - /// - inline int getWidth() const { return mSize.w(); } - - /// - /// - /// - inline int getHeight() const { return mSize.h(); } - - /// - /// Get opengl texture token. - /// - /// @return OpenGL texture token. - /// - inline GLuint getGLTexture() const { return mTexture; } - - /// - /// - /// - void setFilter(GLint min, GLint max); - - /// - /// Render graphic single with given coordinates. - /// - void render(float x, float y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0) const; - - /// - /// Render part of graphic single with given coordinates. - /// - void render(const Math::Quad& slice, float x, float y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0) const; - - /// - /// Render with transform. - /// - void render(const Math::Transform& transform) const; - - /// - /// - /// - void render(const Math::Quad& slice, const Math::Transform& transform) const; - - protected: - Math::Vector2<uint> mSize; - - private: - GLuint mTexture; - - }; - - } // namespace Graphics + namespace Graphics + { + + /// + /// Class inherites Graphic doesn't keep any state such as origin, scale and other properties. Very low + /// level visualized resources. + /// + class Graphic : public Object, public Renderable + { + public: + /// + /// + /// + Graphic(int w = 0, int h = 0); + + /// + /// + /// + Graphic(const Bitmap* bitmap); + + /// + /// + /// + virtual ~Graphic(); + + /// + /// + /// + inline int getWidth() const { return mSize.w(); } + + /// + /// + /// + inline int getHeight() const { return mSize.h(); } + + /// + /// Get opengl texture token. + /// + /// @return OpenGL texture token. + /// + inline GLuint getGLTexture() const { return mTexture; } + + /// + /// + /// + void setFilter(GLint min, GLint max); + + /// + /// Render graphic single with given coordinates. + /// + void render(float x, float y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0) const; + + /// + /// Render part of graphic single with given coordinates. + /// + void render(const Math::Quad& slice, float x, float y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0) const; + + /// + /// Render with transform. + /// + void render(const Math::Transform& transform) const; + + /// + /// + /// + void render(const Math::Quad& slice, const Math::Transform& transform) const; + + protected: + Math::Vector2<uint> mSize; + + private: + GLuint mTexture; + + }; + + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics) diff --git a/src/libjin/graphics/image.cpp b/src/libjin/graphics/image.cpp index 42d717d..de36355 100644 --- a/src/libjin/graphics/image.cpp +++ b/src/libjin/graphics/image.cpp @@ -6,43 +6,43 @@ namespace JinEngine { - namespace Graphics - { - - using namespace Filesystem; - - Image::Image(const char* path) - : Bitmap() - { - AssetDatabase* fs = AssetDatabase::get(); - Buffer buffer; - fs->read(path, buffer); - Image(&buffer, buffer.size()); - } - - Image::Image(const void* imgData, size_t size) - : Bitmap() - { - if (imgData == nullptr) - return; - int w, h; - void* data = stbi_load_from_memory((uint8*)imgData, size, &w, &h, NULL, STBI_rgb_alpha); - if (data == nullptr) - return; - Image(); - pixels = (Color*)data; - width = w; - height = h; - } - - Image::Image() - : Bitmap() - { - } - - Image::~Image() - { - } - - } // namespace Graphics + namespace Graphics + { + + using namespace Filesystem; + + Image::Image(const char* path) + : Bitmap() + { + AssetDatabase* fs = AssetDatabase::get(); + Buffer buffer; + fs->read(path, buffer); + Image(&buffer, buffer.size()); + } + + Image::Image(const void* imgData, size_t size) + : Bitmap() + { + if (imgData == nullptr) + return; + int w, h; + void* data = stbi_load_from_memory((uint8*)imgData, size, &w, &h, NULL, STBI_rgb_alpha); + if (data == nullptr) + return; + Image(); + pixels = (Color*)data; + width = w; + height = h; + } + + Image::Image() + : Bitmap() + { + } + + Image::~Image() + { + } + + } // namespace Graphics } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/graphics/image.h b/src/libjin/graphics/image.h index 05a40e1..7fc4135 100644 --- a/src/libjin/graphics/image.h +++ b/src/libjin/graphics/image.h @@ -5,43 +5,43 @@ namespace JinEngine { - namespace Graphics - { - - /// - /// A readonly bitmap. - /// - /// Just like bitmap but only from image file. The pixels data is readonly. - /// - class Image : public Bitmap - { - public: - /// - /// Image constructor. - /// - Image(); - - Image(const char* path); - - Image(const void* imgData, size_t size); - - /// - /// Image destructor. - /// - ~Image(); - - private: - // Disable setters inherited from Bitmap. - void bind(Color* pixels, int w, int h); - void resetPixels(const Color* pixels, int w, int h); - void resetPixels(const Color& pixels, int w, int h); - void setPixel(const Color& pixel, int x, int y); - void setPixels(Color pixels); - void setPixels(Color* pixels); - - }; - - } // namespace Graphics + namespace Graphics + { + + /// + /// A readonly bitmap. + /// + /// Just like bitmap but only from image file. The pixels data is readonly. + /// + class Image : public Bitmap + { + public: + /// + /// Image constructor. + /// + Image(); + + Image(const char* path); + + Image(const void* imgData, size_t size); + + /// + /// Image destructor. + /// + ~Image(); + + private: + // Disable setters inherited from Bitmap. + void bind(Color* pixels, int w, int h); + void resetPixels(const Color* pixels, int w, int h); + void resetPixels(const Color& pixels, int w, int h); + void setPixel(const Color& pixel, int x, int y); + void setPixels(Color pixels); + void setPixels(Color* pixels); + + }; + + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/mesh.cpp b/src/libjin/graphics/mesh.cpp index 71ebf62..2847a4f 100644 --- a/src/libjin/graphics/mesh.cpp +++ b/src/libjin/graphics/mesh.cpp @@ -8,71 +8,71 @@ using namespace JinEngine::Graphics::Shaders; namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - Mesh::Mesh() - : mGraphic(nullptr) - { - } + Mesh::Mesh() + : mGraphic(nullptr) + { + } - void Mesh::setGraphic(const Graphic* graphic) - { - mGraphic = graphic; - } + void Mesh::setGraphic(const Graphic* graphic) + { + mGraphic = graphic; + } - void Mesh::pushVertex(float x, float y, float u, float v, Color color) - { - Vertex vert; - vert.xy.x() = x; vert.xy.y() = y; - vert.uv.u() = u; vert.uv.v() = v; - vert.color = color; - pushVertex(vert); - } + void Mesh::pushVertex(float x, float y, float u, float v, Color color) + { + Vertex vert; + vert.xy.x() = x; vert.xy.y() = y; + vert.uv.u() = u; vert.uv.v() = v; + vert.color = color; + pushVertex(vert); + } - void Mesh::pushVertex(const Vertex& vert) - { - mVertices.push_back(vert); - // Update bound - if (mVertices.size() == 2) - { - const Vertex& v0 = mVertices[0]; - mBound.l = min(v0.xy.x(), vert.xy.x()); - mBound.r = max(v0.xy.x(), vert.xy.x()); - mBound.t = min(v0.xy.y(), vert.xy.y()); - mBound.b = max(v0.xy.y(), vert.xy.y()); - } - else - { - float x = vert.xy.x(), y = vert.xy.y(); - mBound.l = x < mBound.l ? x : mBound.l; - mBound.r = x > mBound.r ? x : mBound.r; - mBound.t = y < mBound.t ? y : mBound.t; - mBound.b = y > mBound.b ? y : mBound.b; - } - } + void Mesh::pushVertex(const Vertex& vert) + { + mVertices.push_back(vert); + // Update bound + if (mVertices.size() == 2) + { + const Vertex& v0 = mVertices[0]; + mBound.l = min(v0.xy.x(), vert.xy.x()); + mBound.r = max(v0.xy.x(), vert.xy.x()); + mBound.t = min(v0.xy.y(), vert.xy.y()); + mBound.b = max(v0.xy.y(), vert.xy.y()); + } + else + { + float x = vert.xy.x(), y = vert.xy.y(); + mBound.l = x < mBound.l ? x : mBound.l; + mBound.r = x > mBound.r ? x : mBound.r; + mBound.t = y < mBound.t ? y : mBound.t; + mBound.b = y > mBound.b ? y : mBound.b; + } + } - void Mesh::render(float x, float y, float sx, float sy, float r, float ox, float oy) const - { - if (mGraphic == nullptr || mVertices.size() == 0) - return; + void Mesh::render(float x, float y, float sx, float sy, float r, float ox, float oy) const + { + if (mGraphic == nullptr || mVertices.size() == 0) + return; - Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy); + Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy); - Shader* shader = gl.getShader(); - shader->begin() - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) - .uploadVertices(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].xy)) - .uploadUV(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].uv)) - .uploadColor(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &(mVertices[0].color), GL_TRUE); + Shader* shader = gl.getShader(); + shader->begin() + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) + .uploadVertices(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].xy)) + .uploadUV(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].uv)) + .uploadColor(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &(mVertices[0].color), GL_TRUE); - gl.bindTexture2D(mGraphic->getGLTexture()); - gl.drawArrays(GL_POLYGON, 0, mVertices.size()); - + gl.bindTexture2D(mGraphic->getGLTexture()); + gl.drawArrays(GL_POLYGON, 0, mVertices.size()); + - shader->end(); - }; + shader->end(); + }; - } // namespace Graphics + } // namespace Graphics } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/graphics/mesh.h b/src/libjin/graphics/mesh.h index d17fcea..511a85c 100644 --- a/src/libjin/graphics/mesh.h +++ b/src/libjin/graphics/mesh.h @@ -10,43 +10,43 @@ namespace JinEngine { - namespace Graphics - { - - /// - /// A 2D mesh. - /// - class Mesh : public Renderable, public Object - { - public: - Mesh(); - - void setGraphic(const Graphic* graphic); - void pushVertex(float x, float y, float u, float v, Color color = Color::WHITE); - void pushVertex(const Vertex& vertex); - inline Math::BBox getBound() { return mBound; } - - void render(float x, float y, float sx, float sy, float r, float ox = 0, float oy = 0) const; - - private: - /// - /// Graphic binded. - /// - const Graphic* mGraphic; - - /// - /// Bound box of mesh. - /// - Math::BBox mBound; - - /// - /// - /// - std::vector<Vertex> mVertices; - - }; - - } // namespace Graphics + namespace Graphics + { + + /// + /// A 2D mesh. + /// + class Mesh : public Renderable, public Object + { + public: + Mesh(); + + void setGraphic(const Graphic* graphic); + void pushVertex(float x, float y, float u, float v, Color color = Color::WHITE); + void pushVertex(const Vertex& vertex); + inline Math::BBox getBound() { return mBound; } + + void render(float x, float y, float sx, float sy, float r, float ox = 0, float oy = 0) const; + + private: + /// + /// Graphic binded. + /// + const Graphic* mGraphic; + + /// + /// Bound box of mesh. + /// + Math::BBox mBound; + + /// + /// + /// + std::vector<Vertex> mVertices; + + }; + + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/opengl.cpp b/src/libjin/graphics/opengl.cpp index c1696f4..c00e206 100644 --- a/src/libjin/graphics/opengl.cpp +++ b/src/libjin/graphics/opengl.cpp @@ -15,403 +15,403 @@ using namespace JinEngine::Graphics::Shaders; namespace JinEngine { - namespace Graphics - { - - OpenGL gl; - - Canvas* const OpenGL::SCREEN = NULL; - - OpenGL::OpenGL() - { - memset(&mStats, 0, sizeof(mStats)); - memset(&mColor, 0xff, sizeof(mColor)); - // Set default modelview matrix. - mModelViewMatrices.push_back(Matrix()); - mModelViewMatrix.setIdentity(); - for (Matrix& m : mModelViewMatrices) - mModelViewMatrix *= m; - } - - OpenGL::~OpenGL() - { - } - - bool OpenGL::loadGL() - { - // Init glad library. - if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) - { - jin_log_error("init opengl context failed"); - return false; - } - - return true; - } - - void OpenGL::init() - { - enable(GL_BLEND); + namespace Graphics + { + + OpenGL gl; + + Canvas* const OpenGL::SCREEN = NULL; + + OpenGL::OpenGL() + { + memset(&mStats, 0, sizeof(mStats)); + memset(&mColor, 0xff, sizeof(mColor)); + // Set default modelview matrix. + mModelViewMatrices.push_back(Matrix()); + mModelViewMatrix.setIdentity(); + for (Matrix& m : mModelViewMatrices) + mModelViewMatrix *= m; + } + + OpenGL::~OpenGL() + { + } + + bool OpenGL::loadGL() + { + // Init glad library. + if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) + { + jin_log_error("init opengl context failed"); + return false; + } + + return true; + } + + void OpenGL::init() + { + enable(GL_BLEND); unbindCanvas(); unuseShader(); - setClearColor(0, 0, 0, 0xff); - setColor(0xff, 0xff, 0xff, 0xff); - setBlendMode(OpenGL::BlendMode::ALPHA); - } - - void OpenGL::enable(GLenum cap) - { - glEnable(cap); - } - - void OpenGL::disable(GLenum cap) - { - glDisable(cap); - } - - void OpenGL::setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) - { - glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); - } - - void OpenGL::popColor() - { - glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); - } - - void OpenGL::flushError() - { - while (glGetError() != GL_NO_ERROR); - } - - GLuint OpenGL::genTexture() - { - GLuint t; - glGenTextures(1, &t); - return t; - } - - void OpenGL::bindTexture2D(GLuint texture) - { - glBindTexture(GL_TEXTURE_2D, texture); - } - - void OpenGL::deleteTexture(GLuint texture) - { - glDeleteTextures(1, &texture); - } - - void OpenGL::setTexParameter(GLenum pname, GLint param) - { - glTexParameteri(GL_TEXTURE_2D, pname, param); - } - - void OpenGL::texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) - { - glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, pixels); - } - - void OpenGL::texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) - { - glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, format, type, pixels); - } - - void OpenGL::activeTextureUnit(unsigned int unit) - { - // glActiveTexture selects which texture unit subsequent texture state calls will affect. - glActiveTexture(GL_TEXTURE0 + unit); - } - - void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count) - { - glDrawArrays(mode, first, count); - ++mStats.drawCalls; - } - - void OpenGL::drawBuffer(GLenum mode) - { - - } - - void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) - { - - } - - void OpenGL::enableClientState(GLenum arr) - { - glEnableClientState(arr); - } - - void OpenGL::disableClientState(GLenum arr) - { - glDisableClientState(arr); - } - - GLuint OpenGL::genFrameBuffer() - { - GLuint fbo; - glGenFramebuffers(1, &fbo); - return fbo; - } - - void OpenGL::bindFrameBuffer(GLuint fbo) - { - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - } - - void OpenGL::ortho(int w, float radio) - { - glOrtho(0, w, w*radio, 0, -1, 1); - } - - void OpenGL::orthox(int w, int h) - { - glOrtho(0, w, h, 0, -1, 1); - } - - void OpenGL::setColor(Channel r, Channel g, Channel b, Channel a) - { - setColor(Color(r, g, b, a)); - } - - void OpenGL::setColor(Color c) - { - mColor = c; - glColor4f(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f); - } - - Color OpenGL::getColor() - { - return mColor; - } - - void OpenGL::clearMatrix() - { - mModelViewMatrices.clear(); - mModelViewMatrices.push_back(Matrix()); - mModelViewMatrix.setIdentity(); - } - - void OpenGL::pushMatrix() - { - mModelViewMatrices.push_back(Matrix()); - } - - void OpenGL::popMatrix() - { - if (mModelViewMatrices.size() == 1) - return; - mModelViewMatrices.pop_back(); - mModelViewMatrix.setIdentity(); - for (Matrix& m : mModelViewMatrices) - mModelViewMatrix *= m; - } - - void OpenGL::translate(float x, float y) - { - if (mModelViewMatrices.size() == 1) - return; - Matrix& m = mModelViewMatrices.back(); - m.translate(x, y); - mModelViewMatrix.translate(x, y); - } - - void OpenGL::scale(float sx, float sy) - { - if (mModelViewMatrices.size() == 1) - return; - Matrix& m = mModelViewMatrices.back(); - m.scale(sx, sy); - mModelViewMatrix.scale(sx, sy); - } - - void OpenGL::rotate(float r) - { - if (mModelViewMatrices.size() == 1) - return; - Matrix& m = mModelViewMatrices.back(); - m.rotate(r); - mModelViewMatrix.rotate(r); - } - - Matrix OpenGL::getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy) - { - Matrix m; - m.setTransformation(x, y, r, sx, sy, ox, oy); - return mModelViewMatrix*m; - } - - Math::Matrix OpenGL::getModelViewMatrix(const Math::Transform& tansform) - { - return mModelViewMatrix * tansform.getMatrix(); - } - - Matrix OpenGL::getModelViewMatrix() - { - return mModelViewMatrix; - } - - const Matrix& OpenGL::getProjectionMatrix() - { - return mProjectionMatrix; - } - - void OpenGL::setProjectionMatrix(float l, float r, float b, float t, float n, float f) - { - mProjectionMatrix.setOrtho(l, r, b, t, n, f); - } - - OpenGL::BlendMode OpenGL::getBlendMode() - { - return mBlendMode; - } - - void OpenGL::setBlendMode(BlendMode mode) - { - if (mBlendMode == mode) - return; - mBlendMode = mode; - - // result = src * srcFac FUNC dst * dstFac - - GLenum func = GL_FUNC_ADD; - GLenum srcRGB = GL_ONE; - GLenum srcA = GL_ONE; - GLenum dstRGB = GL_ZERO; - GLenum dstA = GL_ZERO; - - switch (mode) - { - case BlendMode::ADDITIVE: - srcRGB = GL_SRC_ALPHA; - srcA = GL_SRC_ALPHA; - dstRGB = GL_ONE; - dstA = GL_ONE; - break; - case BlendMode::PREMULTIPLIEDALPHA: - srcRGB = srcA = GL_ONE; - dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA; - break; - case BlendMode::ALPHA: - default: - srcRGB = GL_SRC_ALPHA; - srcA = GL_SRC_ALPHA; - dstRGB = GL_ONE_MINUS_SRC_ALPHA; - dstA = GL_ONE_MINUS_SRC_ALPHA; - - break; - } - - glBlendEquation(func); - glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA); - } - - void OpenGL::useShader(Shaders::Shader* shader) - { - if (mShader != shader && shader) - { - glUseProgram(shader->getGLProgramID()); - mShader = shader; - - ++mStats.shaderSwitches; - } - } - - void OpenGL::unuseShader() - { - if (mShader) - { - glUseProgram(0); - mShader = nullptr; - } - } - - Shaders::Shader* OpenGL::getShader() - { - return mShader; - } - - void OpenGL::bindCanvas(Canvas* canvas) - { - if (mCanvas != canvas && canvas) - { - GLuint fbo = canvas->getGLFrameBuffer(); - bindFrameBuffer(fbo); - int w = canvas->getWidth(); - int h = canvas->getHeight(); - glViewport(0, 0, w, h); - setProjectionMatrix(0, w, 0, h, -1, 1); - - mCanvas = canvas; - - setBlendMode(OpenGL::BlendMode::ALPHA); - - ++mStats.canvasSwitches; - } - } - - /** - * bind to default screen render buffer. - * do some coordinates transform work - * https://blog.csdn.net/liji_digital/article/details/79370841 - * https://blog.csdn.net/lyx2007825/article/details/8792475 - */ - void OpenGL::unbindCanvas() - { - // Default bind to default canvas. - if (getCanvas() == SCREEN) - return; - // Get window size as viewport. - Window* wnd = Window::get(); + setClearColor(0, 0, 0, 0xff); + setColor(0xff, 0xff, 0xff, 0xff); + setBlendMode(OpenGL::BlendMode::ALPHA); + } + + void OpenGL::enable(GLenum cap) + { + glEnable(cap); + } + + void OpenGL::disable(GLenum cap) + { + glDisable(cap); + } + + void OpenGL::setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) + { + glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); + } + + void OpenGL::popColor() + { + glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); + } + + void OpenGL::flushError() + { + while (glGetError() != GL_NO_ERROR); + } + + GLuint OpenGL::genTexture() + { + GLuint t; + glGenTextures(1, &t); + return t; + } + + void OpenGL::bindTexture2D(GLuint texture) + { + glBindTexture(GL_TEXTURE_2D, texture); + } + + void OpenGL::deleteTexture(GLuint texture) + { + glDeleteTextures(1, &texture); + } + + void OpenGL::setTexParameter(GLenum pname, GLint param) + { + glTexParameteri(GL_TEXTURE_2D, pname, param); + } + + void OpenGL::texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) + { + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, pixels); + } + + void OpenGL::texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, format, type, pixels); + } + + void OpenGL::activeTextureUnit(unsigned int unit) + { + // glActiveTexture selects which texture unit subsequent texture state calls will affect. + glActiveTexture(GL_TEXTURE0 + unit); + } + + void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count) + { + glDrawArrays(mode, first, count); + ++mStats.drawCalls; + } + + void OpenGL::drawBuffer(GLenum mode) + { + + } + + void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) + { + + } + + void OpenGL::enableClientState(GLenum arr) + { + glEnableClientState(arr); + } + + void OpenGL::disableClientState(GLenum arr) + { + glDisableClientState(arr); + } + + GLuint OpenGL::genFrameBuffer() + { + GLuint fbo; + glGenFramebuffers(1, &fbo); + return fbo; + } + + void OpenGL::bindFrameBuffer(GLuint fbo) + { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + } + + void OpenGL::ortho(int w, float radio) + { + glOrtho(0, w, w*radio, 0, -1, 1); + } + + void OpenGL::orthox(int w, int h) + { + glOrtho(0, w, h, 0, -1, 1); + } + + void OpenGL::setColor(Channel r, Channel g, Channel b, Channel a) + { + setColor(Color(r, g, b, a)); + } + + void OpenGL::setColor(Color c) + { + mColor = c; + glColor4f(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f); + } + + Color OpenGL::getColor() + { + return mColor; + } + + void OpenGL::clearMatrix() + { + mModelViewMatrices.clear(); + mModelViewMatrices.push_back(Matrix()); + mModelViewMatrix.setIdentity(); + } + + void OpenGL::pushMatrix() + { + mModelViewMatrices.push_back(Matrix()); + } + + void OpenGL::popMatrix() + { + if (mModelViewMatrices.size() == 1) + return; + mModelViewMatrices.pop_back(); + mModelViewMatrix.setIdentity(); + for (Matrix& m : mModelViewMatrices) + mModelViewMatrix *= m; + } + + void OpenGL::translate(float x, float y) + { + if (mModelViewMatrices.size() == 1) + return; + Matrix& m = mModelViewMatrices.back(); + m.translate(x, y); + mModelViewMatrix.translate(x, y); + } + + void OpenGL::scale(float sx, float sy) + { + if (mModelViewMatrices.size() == 1) + return; + Matrix& m = mModelViewMatrices.back(); + m.scale(sx, sy); + mModelViewMatrix.scale(sx, sy); + } + + void OpenGL::rotate(float r) + { + if (mModelViewMatrices.size() == 1) + return; + Matrix& m = mModelViewMatrices.back(); + m.rotate(r); + mModelViewMatrix.rotate(r); + } + + Matrix OpenGL::getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy) + { + Matrix m; + m.setTransformation(x, y, r, sx, sy, ox, oy); + return mModelViewMatrix*m; + } + + Math::Matrix OpenGL::getModelViewMatrix(const Math::Transform& tansform) + { + return mModelViewMatrix * tansform.getMatrix(); + } + + Matrix OpenGL::getModelViewMatrix() + { + return mModelViewMatrix; + } + + const Matrix& OpenGL::getProjectionMatrix() + { + return mProjectionMatrix; + } + + void OpenGL::setProjectionMatrix(float l, float r, float b, float t, float n, float f) + { + mProjectionMatrix.setOrtho(l, r, b, t, n, f); + } + + OpenGL::BlendMode OpenGL::getBlendMode() + { + return mBlendMode; + } + + void OpenGL::setBlendMode(BlendMode mode) + { + if (mBlendMode == mode) + return; + mBlendMode = mode; + + // result = src * srcFac FUNC dst * dstFac + + GLenum func = GL_FUNC_ADD; + GLenum srcRGB = GL_ONE; + GLenum srcA = GL_ONE; + GLenum dstRGB = GL_ZERO; + GLenum dstA = GL_ZERO; + + switch (mode) + { + case BlendMode::ADDITIVE: + srcRGB = GL_SRC_ALPHA; + srcA = GL_SRC_ALPHA; + dstRGB = GL_ONE; + dstA = GL_ONE; + break; + case BlendMode::PREMULTIPLIEDALPHA: + srcRGB = srcA = GL_ONE; + dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA; + break; + case BlendMode::ALPHA: + default: + srcRGB = GL_SRC_ALPHA; + srcA = GL_SRC_ALPHA; + dstRGB = GL_ONE_MINUS_SRC_ALPHA; + dstA = GL_ONE_MINUS_SRC_ALPHA; + + break; + } + + glBlendEquation(func); + glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA); + } + + void OpenGL::useShader(Shaders::Shader* shader) + { + if (mShader != shader && shader) + { + glUseProgram(shader->getGLProgramID()); + mShader = shader; + + ++mStats.shaderSwitches; + } + } + + void OpenGL::unuseShader() + { + if (mShader) + { + glUseProgram(0); + mShader = nullptr; + } + } + + Shaders::Shader* OpenGL::getShader() + { + return mShader; + } + + void OpenGL::bindCanvas(Canvas* canvas) + { + if (mCanvas != canvas && canvas) + { + GLuint fbo = canvas->getGLFrameBuffer(); + bindFrameBuffer(fbo); + int w = canvas->getWidth(); + int h = canvas->getHeight(); + glViewport(0, 0, w, h); + setProjectionMatrix(0, w, 0, h, -1, 1); + + mCanvas = canvas; + + setBlendMode(OpenGL::BlendMode::ALPHA); + + ++mStats.canvasSwitches; + } + } + + /** + * bind to default screen render buffer. + * do some coordinates transform work + * https://blog.csdn.net/liji_digital/article/details/79370841 + * https://blog.csdn.net/lyx2007825/article/details/8792475 + */ + void OpenGL::unbindCanvas() + { + // Default bind to default canvas. + if (getCanvas() == SCREEN) + return; + // Get window size as viewport. + Window* wnd = Window::get(); glBindFramebuffer(GL_FRAMEBUFFER, 0); - int w = wnd->getW(), h = wnd->getH(); - glViewport(0, 0, w, h); - setProjectionMatrix(0, w, h, 0, -1, 1); + int w = wnd->getW(), h = wnd->getH(); + glViewport(0, 0, w, h); + setProjectionMatrix(0, w, h, 0, -1, 1); setBlendMode(OpenGL::BlendMode::ALPHA); - mCanvas = SCREEN; - } - - Canvas* OpenGL::getCanvas() - { - return mCanvas; - } - - void OpenGL::setFont(Fonts::Font* font) - { - if (mFont != font && font) - { - mFont = font; - - ++mStats.fontSwitches; - } - } - - void OpenGL::unsetFont() - { - mFont = nullptr; - } - - Fonts::Font* OpenGL::getFont() - { - return mFont; - } - - void OpenGL::resetStats() - { - mStats.drawCalls = 0; - mStats.canvasSwitches = 0; - mStats.shaderSwitches = 0; - mStats.fontSwitches = 0; - } - - OpenGL::Stats& OpenGL::getStats() - { - return mStats; - } - - } // namespace Graphics + mCanvas = SCREEN; + } + + Canvas* OpenGL::getCanvas() + { + return mCanvas; + } + + void OpenGL::setFont(Fonts::Font* font) + { + if (mFont != font && font) + { + mFont = font; + + ++mStats.fontSwitches; + } + } + + void OpenGL::unsetFont() + { + mFont = nullptr; + } + + Fonts::Font* OpenGL::getFont() + { + return mFont; + } + + void OpenGL::resetStats() + { + mStats.drawCalls = 0; + mStats.canvasSwitches = 0; + mStats.shaderSwitches = 0; + mStats.fontSwitches = 0; + } + + OpenGL::Stats& OpenGL::getStats() + { + return mStats; + } + + } // namespace Graphics } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/graphics/opengl.h b/src/libjin/graphics/opengl.h index e97ebb6..c0a8a5d 100644 --- a/src/libjin/graphics/opengl.h +++ b/src/libjin/graphics/opengl.h @@ -13,258 +13,258 @@ namespace JinEngine { - namespace Graphics - { - // Wrap OpenGL API. + namespace Graphics + { + // Wrap OpenGL API. - namespace Shaders { class Shader; }; - namespace Fonts { class Font; }; + namespace Shaders { class Shader; }; + namespace Fonts { class Font; }; - class Texture; + class Texture; - class Canvas; + class Canvas; - class OpenGL - { - public: - /// - /// Blend mode. - /// https://www.andersriggelsen.dk/glblendfunc.php - /// - enum class BlendMode - { - ALPHA = 1, - ADDITIVE = 2, - PREMULTIPLIEDALPHA = 3, - }; + class OpenGL + { + public: + /// + /// Blend mode. + /// https://www.andersriggelsen.dk/glblendfunc.php + /// + enum class BlendMode + { + ALPHA = 1, + ADDITIVE = 2, + PREMULTIPLIEDALPHA = 3, + }; - struct Stats - { - int drawCalls; - //int drawCallsBatched; - int canvasSwitches; - int shaderSwitches; - int fontSwitches; - int textures; - int canvases; - int fonts; - //int64 textureMemory; - }; + struct Stats + { + int drawCalls; + //int drawCallsBatched; + int canvasSwitches; + int shaderSwitches; + int fontSwitches; + int textures; + int canvases; + int fonts; + //int64 textureMemory; + }; - static Canvas* const SCREEN; + static Canvas* const SCREEN; - OpenGL(); - ~OpenGL(); + OpenGL(); + ~OpenGL(); - bool loadGL(); + bool loadGL(); - void init(); + void init(); - void enable(GLenum cap); + void enable(GLenum cap); - void disable(GLenum cap); + void disable(GLenum cap); - void setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a); + void setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a); - void pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255); + void pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255); - void popColor(); - - void flushError(); - - GLuint genTexture(); - - void deleteTexture(GLuint texture); - - void bindTexture2D(GLuint texture = 0); - - void setTexParameter(GLenum pname, GLint param); - - void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL); - - void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); - - void activeTextureUnit(unsigned int unit = 0); + void popColor(); + + void flushError(); + + GLuint genTexture(); + + void deleteTexture(GLuint texture); + + void bindTexture2D(GLuint texture = 0); + + void setTexParameter(GLenum pname, GLint param); + + void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL); + + void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); + + void activeTextureUnit(unsigned int unit = 0); - void drawArrays(GLenum mode, GLint first, GLsizei count); + void drawArrays(GLenum mode, GLint first, GLsizei count); - void drawBuffer(GLenum mode); + void drawBuffer(GLenum mode); - void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); + void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); - void enableClientState(GLenum arr); + void enableClientState(GLenum arr); - void disableClientState(GLenum arr); + void disableClientState(GLenum arr); - GLuint genFrameBuffer(); + GLuint genFrameBuffer(); - void bindFrameBuffer(GLuint fbo); + void bindFrameBuffer(GLuint fbo); - void ortho(int w, float radio); + void ortho(int w, float radio); - void orthox(int w, int h); + void orthox(int w, int h); - void setColor(Channel r, Channel g, Channel b, Channel a); + void setColor(Channel r, Channel g, Channel b, Channel a); - void setColor(Color c); + void setColor(Color c); - Color getColor(); + Color getColor(); - void clearMatrix(); + void clearMatrix(); - void pushMatrix(); + void pushMatrix(); - void translate(float x, float y); + void translate(float x, float y); - void scale(float sx, float sy); + void scale(float sx, float sy); - void rotate(float r); + void rotate(float r); - void popMatrix(); + void popMatrix(); - /// - /// - /// - Math::Matrix getModelViewMatrix(const Math::Transform& tansform); - - /// - /// Get model view matrix. - /// - Math::Matrix getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy); + /// + /// + /// + Math::Matrix getModelViewMatrix(const Math::Transform& tansform); + + /// + /// Get model view matrix. + /// + Math::Matrix getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy); - /// - /// Get model view matrix. - /// - Math::Matrix getModelViewMatrix(); + /// + /// Get model view matrix. + /// + Math::Matrix getModelViewMatrix(); - /// - /// Set orthogonal matrix. - /// - void setProjectionMatrix(float l, float r, float b, float t, float n, float f); + /// + /// Set orthogonal matrix. + /// + void setProjectionMatrix(float l, float r, float b, float t, float n, float f); - /// - /// Get orthogonal matrix. - /// - const Math::Matrix& getProjectionMatrix(); + /// + /// Get orthogonal matrix. + /// + const Math::Matrix& getProjectionMatrix(); - /// - /// - /// - void useShader(Shaders::Shader* shader); + /// + /// + /// + void useShader(Shaders::Shader* shader); - /// - /// - /// - void unuseShader(); + /// + /// + /// + void unuseShader(); - /// - /// - /// - Shaders::Shader* getShader(); + /// + /// + /// + Shaders::Shader* getShader(); - /// - /// - /// - void setFont(Fonts::Font* font); + /// + /// + /// + void setFont(Fonts::Font* font); - /// - /// - /// - void unsetFont(); + /// + /// + /// + void unsetFont(); - /// - /// - /// - Fonts::Font* getFont(); + /// + /// + /// + Fonts::Font* getFont(); - /// - /// - /// - void bindCanvas(Canvas* canvas); + /// + /// + /// + void bindCanvas(Canvas* canvas); - /// - /// - /// - void unbindCanvas(); - - /// - /// - /// - Canvas* getCanvas(); + /// + /// + /// + void unbindCanvas(); + + /// + /// + /// + Canvas* getCanvas(); - /// - /// - /// - void setBlendMode(BlendMode mode); + /// + /// + /// + void setBlendMode(BlendMode mode); - /// - /// - /// - BlendMode getBlendMode(); - - /// - /// - /// - void resetStats(); - - /// - /// - /// - Stats& getStats(); - - private: - - /// - /// - /// - std::vector<Math::Matrix> mModelViewMatrices; - - /// - /// - /// - Math::Matrix mModelViewMatrix; - - /// - /// - /// - Math::Matrix mProjectionMatrix; - - /// - /// - /// - BlendMode mBlendMode; - - /// - /// - /// - Color mColor; - - /// - /// - /// - Canvas* mCanvas; - - /// - /// - /// - Shaders::Shader* mShader; - - /// - /// - /// - Fonts::Font* mFont; - - /// - /// - /// - Stats mStats; - - }; - - // Singleton. - extern OpenGL gl; - - } // namespace Graphics + /// + /// + /// + BlendMode getBlendMode(); + + /// + /// + /// + void resetStats(); + + /// + /// + /// + Stats& getStats(); + + private: + + /// + /// + /// + std::vector<Math::Matrix> mModelViewMatrices; + + /// + /// + /// + Math::Matrix mModelViewMatrix; + + /// + /// + /// + Math::Matrix mProjectionMatrix; + + /// + /// + /// + BlendMode mBlendMode; + + /// + /// + /// + Color mColor; + + /// + /// + /// + Canvas* mCanvas; + + /// + /// + /// + Shaders::Shader* mShader; + + /// + /// + /// + Fonts::Font* mFont; + + /// + /// + /// + Stats mStats; + + }; + + // Singleton. + extern OpenGL gl; + + } // namespace Graphics } // namespace JinEngine #endif // __JE_OPENGL_H__
\ No newline at end of file diff --git a/src/libjin/graphics/particles/particle.cpp b/src/libjin/graphics/particles/particle.cpp index 74600e0..ba07344 100644 --- a/src/libjin/graphics/particles/particle.cpp +++ b/src/libjin/graphics/particles/particle.cpp @@ -11,180 +11,180 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Graphics - { - namespace Particles - { - - static RandomGenerator rng(0xEA44944); - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // ScaledRangedValue - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - ScaledRangedValue::ScaledRangedValue(Percentage* points, uint n) - { - for (int i = 0; i < n; ++i) - { - float x = points[2 * i].value; - float y = points[2 * i + 1].value; - addPoint(x, y); - } - } - - void ScaledRangedValue::set(Math::Percentage* points, uint n) - { - clear(); - for (int i = 0; i < n; ++i) - { - float x = points[2 * i].value; - float y = points[2 * i + 1].value; - addPoint(x, y); - } - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // GradientColorValue - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - GradientColorValue::GradientColorValue() - : mCount(0) - { - } - - void GradientColorValue::addColor(Color col, Percentage time) - { - mColors.push_back(col); - mTimeline.push_back(time); - ++mCount; - } - - Color GradientColorValue::getColor(Percentage time) - { - int endIndex = -1; - int n = mCount; - for (int i = 1; i < n; i++) { - Percentage t = mTimeline[i]; - if (t.value > time.value) { - endIndex = i; - break; - } - } - if (endIndex == -1) return mColors[n - 1]; - int startIndex = endIndex - 1; - Color& startValue = mColors[startIndex]; - Color& endValue = mColors[endIndex]; - float t = time.value; - float start = mTimeline[startIndex].value; - float end = mTimeline[endIndex].value; - Color c; - c.r = startValue.r + (endValue.r - startValue.r) * ((t - start) / (end - start)); - c.g = startValue.g + (endValue.g - startValue.g) * ((t - start) / (end - start)); - c.b = startValue.b + (endValue.b - startValue.b) * ((t - start) / (end - start)); - c.a = startValue.a + (endValue.a - startValue.a) * ((t - start) / (end - start)); - return c; - } - - void GradientColorValue::insertColor(uint i, Color col, Math::Percentage time) - { - mColors.insert(mColors.begin() + i, col); - mTimeline.insert(mTimeline.begin() + i, time); - ++mCount; - } - - void GradientColorValue::removeColor(uint i) - { - mColors.erase(mColors.begin() + i); - mTimeline.erase(mTimeline.begin() + i); - --mCount; - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // Particle - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - Particle::Particle() - { - reset(); - } - - void Particle::reset() - { - updateFlags = ParticleUpdateMask::NONE; - transform.set(0, 0, 1, 1, 0, 0, 0); - lifeTime = 1.0f; - life = 0.0f; - velocity.set(0, 0); - linearAcceleration.set(0, 0); - radialAcceleration = 0.0f; - angularSpeed = 0; - color = Color::WHITE; - alive = true; - spriteIndex = 0; - } - - void Particle::update(float dt) - { - life += dt; - alive = life < lifeTime; - if (!alive) - return; - float t = life / lifeTime; - if ((updateFlags & UPDATE_COLOR) != 0) - color = def->colorDef.overTime.value.getColor(t); - // transparency - if (def->transparencyDef.overTime.enable) - color.a = 0xff * def->transparencyDef.overTime.value.getValue(t); - else - color.a = 0xff * def->transparencyDef.transparency.value; - if ((updateFlags & UPDATE_SCALE) != 0) - { - // Lerp scale. - float scale = def->scaleDef.overTime.value.getValue(t); - transform.setScale(scale, scale); - } - if ((updateFlags & UPDATE_POSITION) != 0) - { - // Calculate position. - if((updateFlags & UPDATE_VELOCITY) != 0) - velocity += linearAcceleration * dt; - transform.move(velocity * dt); - } - if ((updateFlags & UPDATE_ROTATION) != 0) - { - // Calculate rotation. - angularSpeed += radialAcceleration * dt; - transform.rotate(angularSpeed * dt); - } - if ((updateFlags & UPDATE_SPRITE) != 0) - { - int n = def->spritesDef.sprites.size(); - if (def->spritesDef.mode == SpriteMode::ANIMATED) - spriteIndex = lerp<int>(0, n - 1, t); - //jin_log_info("sprite index %d", spriteIndex); - } - } - - void Particle::render() - { - // Set blend. - OpenGL::BlendMode blend = gl.getBlendMode(); - if(def->blendDef.additive) - gl.setBlendMode(OpenGL::BlendMode::ADDITIVE); - Color c = gl.getColor(); - gl.setColor(color); - const Sprite* sprite = def->spritesDef.sprites[spriteIndex]; - if (sprite != nullptr) - { - Vector2<float>& position = transform.getPosition(); - Vector2<float>& scale = transform.getScale(); - float r = transform.getRotation(); - sprite->render(position.x(), position.y(), scale.x(), scale.y(), r); - } - gl.setColor(c); - gl.setBlendMode(blend); - } - - } - } + namespace Graphics + { + namespace Particles + { + + static RandomGenerator rng(0xEA44944); + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // ScaledRangedValue + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + ScaledRangedValue::ScaledRangedValue(Percentage* points, uint n) + { + for (int i = 0; i < n; ++i) + { + float x = points[2 * i].value; + float y = points[2 * i + 1].value; + addPoint(x, y); + } + } + + void ScaledRangedValue::set(Math::Percentage* points, uint n) + { + clear(); + for (int i = 0; i < n; ++i) + { + float x = points[2 * i].value; + float y = points[2 * i + 1].value; + addPoint(x, y); + } + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // GradientColorValue + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + GradientColorValue::GradientColorValue() + : mCount(0) + { + } + + void GradientColorValue::addColor(Color col, Percentage time) + { + mColors.push_back(col); + mTimeline.push_back(time); + ++mCount; + } + + Color GradientColorValue::getColor(Percentage time) + { + int endIndex = -1; + int n = mCount; + for (int i = 1; i < n; i++) { + Percentage t = mTimeline[i]; + if (t.value > time.value) { + endIndex = i; + break; + } + } + if (endIndex == -1) return mColors[n - 1]; + int startIndex = endIndex - 1; + Color& startValue = mColors[startIndex]; + Color& endValue = mColors[endIndex]; + float t = time.value; + float start = mTimeline[startIndex].value; + float end = mTimeline[endIndex].value; + Color c; + c.r = startValue.r + (endValue.r - startValue.r) * ((t - start) / (end - start)); + c.g = startValue.g + (endValue.g - startValue.g) * ((t - start) / (end - start)); + c.b = startValue.b + (endValue.b - startValue.b) * ((t - start) / (end - start)); + c.a = startValue.a + (endValue.a - startValue.a) * ((t - start) / (end - start)); + return c; + } + + void GradientColorValue::insertColor(uint i, Color col, Math::Percentage time) + { + mColors.insert(mColors.begin() + i, col); + mTimeline.insert(mTimeline.begin() + i, time); + ++mCount; + } + + void GradientColorValue::removeColor(uint i) + { + mColors.erase(mColors.begin() + i); + mTimeline.erase(mTimeline.begin() + i); + --mCount; + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // Particle + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + Particle::Particle() + { + reset(); + } + + void Particle::reset() + { + updateFlags = ParticleUpdateMask::NONE; + transform.set(0, 0, 1, 1, 0, 0, 0); + lifeTime = 1.0f; + life = 0.0f; + velocity.set(0, 0); + linearAcceleration.set(0, 0); + radialAcceleration = 0.0f; + angularSpeed = 0; + color = Color::WHITE; + alive = true; + spriteIndex = 0; + } + + void Particle::update(float dt) + { + life += dt; + alive = life < lifeTime; + if (!alive) + return; + float t = life / lifeTime; + if ((updateFlags & UPDATE_COLOR) != 0) + color = def->colorDef.overTime.value.getColor(t); + // transparency + if (def->transparencyDef.overTime.enable) + color.a = 0xff * def->transparencyDef.overTime.value.getValue(t); + else + color.a = 0xff * def->transparencyDef.transparency.value; + if ((updateFlags & UPDATE_SCALE) != 0) + { + // Lerp scale. + float scale = def->scaleDef.overTime.value.getValue(t); + transform.setScale(scale, scale); + } + if ((updateFlags & UPDATE_POSITION) != 0) + { + // Calculate position. + if((updateFlags & UPDATE_VELOCITY) != 0) + velocity += linearAcceleration * dt; + transform.move(velocity * dt); + } + if ((updateFlags & UPDATE_ROTATION) != 0) + { + // Calculate rotation. + angularSpeed += radialAcceleration * dt; + transform.rotate(angularSpeed * dt); + } + if ((updateFlags & UPDATE_SPRITE) != 0) + { + int n = def->spritesDef.sprites.size(); + if (def->spritesDef.mode == SpriteMode::ANIMATED) + spriteIndex = lerp<int>(0, n - 1, t); + //jin_log_info("sprite index %d", spriteIndex); + } + } + + void Particle::render() + { + // Set blend. + OpenGL::BlendMode blend = gl.getBlendMode(); + if(def->blendDef.additive) + gl.setBlendMode(OpenGL::BlendMode::ADDITIVE); + Color c = gl.getColor(); + gl.setColor(color); + const Sprite* sprite = def->spritesDef.sprites[spriteIndex]; + if (sprite != nullptr) + { + Vector2<float>& position = transform.getPosition(); + Vector2<float>& scale = transform.getScale(); + float r = transform.getRotation(); + sprite->render(position.x(), position.y(), scale.x(), scale.y(), r); + } + gl.setColor(c); + gl.setBlendMode(blend); + } + + } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/particles/particle.h b/src/libjin/graphics/particles/particle.h index 081ad26..25db6ae 100644 --- a/src/libjin/graphics/particles/particle.h +++ b/src/libjin/graphics/particles/particle.h @@ -12,211 +12,211 @@ namespace JinEngine { - namespace Graphics - { - namespace Particles - { - - class ParticleEmitter; - - class ScaledRangedValue : public Math::RangedValue - { - public: - ScaledRangedValue() {}; - ScaledRangedValue(Math::Percentage* points, uint n); - void set(Math::Percentage* points, uint n); - - }; - - class GradientColorValue - { - public: - GradientColorValue(); - - void addColor(Color col, Math::Percentage time); - Color getColor(Math::Percentage time); - void insertColor(uint i, Color col, Math::Percentage time); - void removeColor(uint i); - - private: - std::vector<Color> mColors; - std::vector<Math::Percentage> mTimeline; - uint mCount; - - }; - - /// - /// - /// - struct LifeTimeDef - { - bool enableRandom = false; - Struct(life, - struct - { - float floor, ceil; - } random; - float life = 1.0f; - ); - }; - - struct ScaleDef - { - float scale = 1; - Struct(overTime, - bool enable = false; - ScaledRangedValue value; - ); - }; - - struct ColorDef - { - Color color = Color::WHITE; - Struct(overTime, - bool enable = false; - GradientColorValue value; - ); - }; - - struct TransparencyDef - { - Math::Percentage transparency = 1.f; - Struct(overTime, - bool enable = false; - ScaledRangedValue value; - ); - }; - - struct linearAccelarationDef - { - Math::Vector2<float> linearAccelaration; - }; - - struct RadialAccelarationDef - { - float radialAccelaration = 0.f; - }; - - struct AngularSpeedDef - { - bool enableRandom = false; - Struct(angularSpeed, - struct - { - float floor = 0; - float ceil = 0; - } random; - float angularSpeed = 0; - ); - }; - - enum SpriteMode - { - SINGLE = 1, - RANDOM = 2, - ANIMATED = 3, - }; - - struct SpritesDef - { - SpriteMode mode = SpriteMode::SINGLE; - std::vector<const Sprite*> sprites; - }; - - struct BlendDef - { - bool additive = false; - }; - - /// - /// - /// - struct ParticleDef - { - public: - // Basic definitions. - LifeTimeDef lifeTimeDef; ///< - linearAccelarationDef linearAccelarationDef; ///< - RadialAccelarationDef radialAccelarationDef; ///< - AngularSpeedDef angularSpeedDef; ///< - SpritesDef spritesDef; ///< - BlendDef blendDef; ///< - // Optional definitions. - ScaleDef scaleDef; ///< - ColorDef colorDef; ///< - TransparencyDef transparencyDef; ///< - - private: - friend class ParticleEmitter; - - }; - - /// - /// A single particle contains various properties of particle, such as position, accelaration, color - /// and other attributes changed over time. - /// - class Particle : public Renderable, public Game::GameObject - { - public: - enum ParticleUpdateMask - { - NONE = 0, - UPDATE_COLOR = 1 << 0, - UPDATE_SCALE = 1 << 1, - UPDATE_POSITION = 1 << 2, - UPDATE_ROTATION = 1 << 3, - UPDATE_SPRITE = 1 << 4, - UPDATE_VELOCITY = 1 << 5, - }; - - /// - /// Default constructor. - /// - Particle(); - - /// - /// Reset to default. - /// - void reset(); - - /// - /// - /// - void update(float dt); - - /// - /// - /// - void render(); - - // Methods end. - - ParticleDef* def; - - uint updateFlags = ParticleUpdateMask::NONE; - - float lifeTime = 1.0f; - - float life = 0.0f; - - int spriteIndex = 0; - - Color color = Color::WHITE; - - Math::Transform transform; - - Math::Vector2<float> velocity; - Math::Vector2<float> linearAcceleration; - - float angularSpeed; - float radialAcceleration = 0; - - bool alive = true; - - }; - - } // namespace Particles - } // namespace Graphics + namespace Graphics + { + namespace Particles + { + + class ParticleEmitter; + + class ScaledRangedValue : public Math::RangedValue + { + public: + ScaledRangedValue() {}; + ScaledRangedValue(Math::Percentage* points, uint n); + void set(Math::Percentage* points, uint n); + + }; + + class GradientColorValue + { + public: + GradientColorValue(); + + void addColor(Color col, Math::Percentage time); + Color getColor(Math::Percentage time); + void insertColor(uint i, Color col, Math::Percentage time); + void removeColor(uint i); + + private: + std::vector<Color> mColors; + std::vector<Math::Percentage> mTimeline; + uint mCount; + + }; + + /// + /// + /// + struct LifeTimeDef + { + bool enableRandom = false; + Struct(life, + struct + { + float floor, ceil; + } random; + float life = 1.0f; + ); + }; + + struct ScaleDef + { + float scale = 1; + Struct(overTime, + bool enable = false; + ScaledRangedValue value; + ); + }; + + struct ColorDef + { + Color color = Color::WHITE; + Struct(overTime, + bool enable = false; + GradientColorValue value; + ); + }; + + struct TransparencyDef + { + Math::Percentage transparency = 1.f; + Struct(overTime, + bool enable = false; + ScaledRangedValue value; + ); + }; + + struct linearAccelarationDef + { + Math::Vector2<float> linearAccelaration; + }; + + struct RadialAccelarationDef + { + float radialAccelaration = 0.f; + }; + + struct AngularSpeedDef + { + bool enableRandom = false; + Struct(angularSpeed, + struct + { + float floor = 0; + float ceil = 0; + } random; + float angularSpeed = 0; + ); + }; + + enum SpriteMode + { + SINGLE = 1, + RANDOM = 2, + ANIMATED = 3, + }; + + struct SpritesDef + { + SpriteMode mode = SpriteMode::SINGLE; + std::vector<const Sprite*> sprites; + }; + + struct BlendDef + { + bool additive = false; + }; + + /// + /// + /// + struct ParticleDef + { + public: + // Basic definitions. + LifeTimeDef lifeTimeDef; ///< + linearAccelarationDef linearAccelarationDef; ///< + RadialAccelarationDef radialAccelarationDef; ///< + AngularSpeedDef angularSpeedDef; ///< + SpritesDef spritesDef; ///< + BlendDef blendDef; ///< + // Optional definitions. + ScaleDef scaleDef; ///< + ColorDef colorDef; ///< + TransparencyDef transparencyDef; ///< + + private: + friend class ParticleEmitter; + + }; + + /// + /// A single particle contains various properties of particle, such as position, accelaration, color + /// and other attributes changed over time. + /// + class Particle : public Renderable, public Game::GameObject + { + public: + enum ParticleUpdateMask + { + NONE = 0, + UPDATE_COLOR = 1 << 0, + UPDATE_SCALE = 1 << 1, + UPDATE_POSITION = 1 << 2, + UPDATE_ROTATION = 1 << 3, + UPDATE_SPRITE = 1 << 4, + UPDATE_VELOCITY = 1 << 5, + }; + + /// + /// Default constructor. + /// + Particle(); + + /// + /// Reset to default. + /// + void reset(); + + /// + /// + /// + void update(float dt); + + /// + /// + /// + void render(); + + // Methods end. + + ParticleDef* def; + + uint updateFlags = ParticleUpdateMask::NONE; + + float lifeTime = 1.0f; + + float life = 0.0f; + + int spriteIndex = 0; + + Color color = Color::WHITE; + + Math::Transform transform; + + Math::Vector2<float> velocity; + Math::Vector2<float> linearAcceleration; + + float angularSpeed; + float radialAcceleration = 0; + + bool alive = true; + + }; + + } // namespace Particles + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/particles/particle_emitter.cpp b/src/libjin/graphics/particles/particle_emitter.cpp index 725b826..56dfb23 100644 --- a/src/libjin/graphics/particles/particle_emitter.cpp +++ b/src/libjin/graphics/particles/particle_emitter.cpp @@ -9,110 +9,110 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Graphics - { - namespace Particles - { + namespace Graphics + { + namespace Particles + { - static const uint8 ACCURACY_4 = 4; - static const uint8 ACCURACY_5 = 5; - static const uint8 ACCURACY_6 = 6; + static const uint8 ACCURACY_4 = 4; + static const uint8 ACCURACY_5 = 5; + static const uint8 ACCURACY_6 = 6; - // Particle emitter - static RandomGenerator rng(0xEA44944); + // Particle emitter + static RandomGenerator rng(0xEA44944); - ParticleEmitter::ParticleEmitter(ParticleSystem& ps) - : mPS(ps) - , mDef(ps.mDef.emitterDef) - , mPDef(ps.mDef.particleDef) - , mTime(0) - { - } + ParticleEmitter::ParticleEmitter(ParticleSystem& ps) + : mPS(ps) + , mDef(ps.mDef.emitterDef) + , mPDef(ps.mDef.particleDef) + , mTime(0) + { + } - void ParticleEmitter::update(float dt) - { - mTime += dt; - for (;mTime >= mInterval; mTime -= mInterval) - { - emit(); - // Random rate. - if (mDef.emitRateDef.enableRandom) - mInterval = rng.randf(mDef.emitRateDef.rate.random.floor, mDef.emitRateDef.rate.random.ceil, ACCURACY_5); - else - mInterval = mDef.emitRateDef.rate.rate; - } - } + void ParticleEmitter::update(float dt) + { + mTime += dt; + for (;mTime >= mInterval; mTime -= mInterval) + { + emit(); + // Random rate. + if (mDef.emitRateDef.enableRandom) + mInterval = rng.randf(mDef.emitRateDef.rate.random.floor, mDef.emitRateDef.rate.random.ceil, ACCURACY_5); + else + mInterval = mDef.emitRateDef.rate.rate; + } + } - void ParticleEmitter::emit() - { - Particle* p = mPS.claim(); - if (p == nullptr) - return; - p->reset(); - p->def = &mPDef; - // Init position. - if (mDef.positionDef.enableRandom) - { - float x = rng.randf(mDef.positionDef.position.random.floor.x(), mDef.positionDef.position.random.ceil.x(), ACCURACY_4); - float y = rng.randf(mDef.positionDef.position.random.floor.y(), mDef.positionDef.position.random.ceil.y(), ACCURACY_4); - x += mPS.mPosition.x(); - y += mPS.mPosition.y(); - p->transform.setPosition(x, y); - } - else - { - p->transform.setPosition(mDef.positionDef.position.position + mPS.mPosition); - } - // Init speed. - float r = 0; - if (mDef.directionDef.enableRandom) - r = rng.randf(mDef.directionDef.direction.random.floor, mDef.directionDef.direction.random.ceil, ACCURACY_4); - else - r = mDef.directionDef.direction.direction; - float f = 0; - if (mDef.forceDef.enableRandom) - f = rng.randf(mDef.forceDef.force.random.floor, mDef.forceDef.force.random.ceil, ACCURACY_4); - else - f = mDef.forceDef.force.force; - p->velocity.set(f*cos(r), f*sin(r)); - if (f != 0) p->updateFlags |= Particle::UPDATE_POSITION; - // Init life time. - if (mPDef.lifeTimeDef.enableRandom) - p->lifeTime = rng.randf(mPDef.lifeTimeDef.life.random.floor, mPDef.lifeTimeDef.life.random.ceil, ACCURACY_4); - else - p->lifeTime = mPDef.lifeTimeDef.life.life; - // Init linear accelaration. - p->linearAcceleration = mPDef.linearAccelarationDef.linearAccelaration; - if(!p->linearAcceleration.isZero()) - p->updateFlags |= (Particle::UPDATE_VELOCITY | Particle::UPDATE_POSITION); - // Init angular accelaration. - p->radialAcceleration = mPDef.radialAccelarationDef.radialAccelaration; - // Init Angular speed. - if (mPDef.angularSpeedDef.enableRandom) - p->angularSpeed = rng.randf(mPDef.angularSpeedDef.angularSpeed.random.floor, mPDef.angularSpeedDef.angularSpeed.random.ceil, ACCURACY_4); - else - p->angularSpeed = mPDef.angularSpeedDef.angularSpeed.angularSpeed; - if (p->angularSpeed != 0) - p->updateFlags |= Particle::UPDATE_ROTATION; - // Scale over time. - if (mPDef.scaleDef.overTime.enable) - p->updateFlags |= Particle::UPDATE_SCALE; - else - p->transform.setScale(mPDef.scaleDef.scale, mPDef.scaleDef.scale); - // Color over time. - if (mPDef.colorDef.overTime.enable) - p->updateFlags |= Particle::UPDATE_COLOR; - else - p->color = mPDef.colorDef.color; - // Sprite - if (mPDef.spritesDef.mode != SpriteMode::SINGLE) - { - p->updateFlags |= Particle::UPDATE_SPRITE; - if (mPDef.spritesDef.mode == SpriteMode::RANDOM) - p->spriteIndex = rng.rand(0, mPDef.spritesDef.sprites.size() - 1); - } - } + void ParticleEmitter::emit() + { + Particle* p = mPS.claim(); + if (p == nullptr) + return; + p->reset(); + p->def = &mPDef; + // Init position. + if (mDef.positionDef.enableRandom) + { + float x = rng.randf(mDef.positionDef.position.random.floor.x(), mDef.positionDef.position.random.ceil.x(), ACCURACY_4); + float y = rng.randf(mDef.positionDef.position.random.floor.y(), mDef.positionDef.position.random.ceil.y(), ACCURACY_4); + x += mPS.mPosition.x(); + y += mPS.mPosition.y(); + p->transform.setPosition(x, y); + } + else + { + p->transform.setPosition(mDef.positionDef.position.position + mPS.mPosition); + } + // Init speed. + float r = 0; + if (mDef.directionDef.enableRandom) + r = rng.randf(mDef.directionDef.direction.random.floor, mDef.directionDef.direction.random.ceil, ACCURACY_4); + else + r = mDef.directionDef.direction.direction; + float f = 0; + if (mDef.forceDef.enableRandom) + f = rng.randf(mDef.forceDef.force.random.floor, mDef.forceDef.force.random.ceil, ACCURACY_4); + else + f = mDef.forceDef.force.force; + p->velocity.set(f*cos(r), f*sin(r)); + if (f != 0) p->updateFlags |= Particle::UPDATE_POSITION; + // Init life time. + if (mPDef.lifeTimeDef.enableRandom) + p->lifeTime = rng.randf(mPDef.lifeTimeDef.life.random.floor, mPDef.lifeTimeDef.life.random.ceil, ACCURACY_4); + else + p->lifeTime = mPDef.lifeTimeDef.life.life; + // Init linear accelaration. + p->linearAcceleration = mPDef.linearAccelarationDef.linearAccelaration; + if(!p->linearAcceleration.isZero()) + p->updateFlags |= (Particle::UPDATE_VELOCITY | Particle::UPDATE_POSITION); + // Init angular accelaration. + p->radialAcceleration = mPDef.radialAccelarationDef.radialAccelaration; + // Init Angular speed. + if (mPDef.angularSpeedDef.enableRandom) + p->angularSpeed = rng.randf(mPDef.angularSpeedDef.angularSpeed.random.floor, mPDef.angularSpeedDef.angularSpeed.random.ceil, ACCURACY_4); + else + p->angularSpeed = mPDef.angularSpeedDef.angularSpeed.angularSpeed; + if (p->angularSpeed != 0) + p->updateFlags |= Particle::UPDATE_ROTATION; + // Scale over time. + if (mPDef.scaleDef.overTime.enable) + p->updateFlags |= Particle::UPDATE_SCALE; + else + p->transform.setScale(mPDef.scaleDef.scale, mPDef.scaleDef.scale); + // Color over time. + if (mPDef.colorDef.overTime.enable) + p->updateFlags |= Particle::UPDATE_COLOR; + else + p->color = mPDef.colorDef.color; + // Sprite + if (mPDef.spritesDef.mode != SpriteMode::SINGLE) + { + p->updateFlags |= Particle::UPDATE_SPRITE; + if (mPDef.spritesDef.mode == SpriteMode::RANDOM) + p->spriteIndex = rng.rand(0, mPDef.spritesDef.sprites.size() - 1); + } + } - } - } + } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/particles/particle_emitter.h b/src/libjin/graphics/particles/particle_emitter.h index 9f9465a..8e386da 100644 --- a/src/libjin/graphics/particles/particle_emitter.h +++ b/src/libjin/graphics/particles/particle_emitter.h @@ -8,129 +8,129 @@ namespace JinEngine { - namespace Graphics - { - namespace Particles - { - - struct PositionDef - { - bool enableRandom = false; - Struct(position, - struct - { - Math::Vector2<float> floor; - Math::Vector2<float> ceil; - } random; - Math::Vector2<float> position; - ); - }; - - struct DirectionDef - { - bool enableRandom = false; - Struct(direction, - struct - { - float floor = 0; - float ceil = 0; - } random; - float direction = 0; - ); - }; - - /// - /// How many particles emitted per second. - /// - struct EmitRateDef - { - bool enableRandom = false; - Struct(rate, - struct - { - float floor = 1; - float ceil = 1; - } random; - float rate = 1; - ); - }; - - /// - /// Initial speed of particle. - /// - struct ForceDef - { - bool enableRandom = false; - Struct(force, - struct - { - float floor = 1; - float ceil = 1; - } random; - float force = 1; - ); - }; - - /// - /// Definition of particle emitter. - /// - struct ParticleEmitterDef - { - EmitRateDef emitRateDef; ///< Emit rate. - - PositionDef positionDef; ///< Emit position(relativily to the particle system center). - DirectionDef directionDef; ///< Emit direction. - ForceDef forceDef; ///< Emit force. - }; - - class ParticleSystem; - - /// - /// Emit a single particle. - /// - class ParticleEmitter - { - public: - /// - /// - /// - ParticleEmitter(ParticleSystem& ps); - - /// - /// - /// - void update(float dt); - - private: - /// - /// - /// - ParticleSystem& mPS; - - ParticleEmitterDef& mDef; - - ParticleDef& mPDef; - - /// - /// Emit particle according to emitter definition and particle definition, particle system should - /// assign particle value to the particle in particle pool, but not use this return particle. - /// - void emit(); - - /// - /// - /// - float mTime; - - /// - /// - /// - float mInterval; - - }; - - } // namespace Particles - } // namespace Graphics + namespace Graphics + { + namespace Particles + { + + struct PositionDef + { + bool enableRandom = false; + Struct(position, + struct + { + Math::Vector2<float> floor; + Math::Vector2<float> ceil; + } random; + Math::Vector2<float> position; + ); + }; + + struct DirectionDef + { + bool enableRandom = false; + Struct(direction, + struct + { + float floor = 0; + float ceil = 0; + } random; + float direction = 0; + ); + }; + + /// + /// How many particles emitted per second. + /// + struct EmitRateDef + { + bool enableRandom = false; + Struct(rate, + struct + { + float floor = 1; + float ceil = 1; + } random; + float rate = 1; + ); + }; + + /// + /// Initial speed of particle. + /// + struct ForceDef + { + bool enableRandom = false; + Struct(force, + struct + { + float floor = 1; + float ceil = 1; + } random; + float force = 1; + ); + }; + + /// + /// Definition of particle emitter. + /// + struct ParticleEmitterDef + { + EmitRateDef emitRateDef; ///< Emit rate. + + PositionDef positionDef; ///< Emit position(relativily to the particle system center). + DirectionDef directionDef; ///< Emit direction. + ForceDef forceDef; ///< Emit force. + }; + + class ParticleSystem; + + /// + /// Emit a single particle. + /// + class ParticleEmitter + { + public: + /// + /// + /// + ParticleEmitter(ParticleSystem& ps); + + /// + /// + /// + void update(float dt); + + private: + /// + /// + /// + ParticleSystem& mPS; + + ParticleEmitterDef& mDef; + + ParticleDef& mPDef; + + /// + /// Emit particle according to emitter definition and particle definition, particle system should + /// assign particle value to the particle in particle pool, but not use this return particle. + /// + void emit(); + + /// + /// + /// + float mTime; + + /// + /// + /// + float mInterval; + + }; + + } // namespace Particles + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/particles/particle_pool.h b/src/libjin/graphics/particles/particle_pool.h index 618a965..b72a1ab 100644 --- a/src/libjin/graphics/particles/particle_pool.h +++ b/src/libjin/graphics/particles/particle_pool.h @@ -7,18 +7,18 @@ namespace JinEngine { - namespace Graphics - { - namespace Particles - { + namespace Graphics + { + namespace Particles + { - /// - /// Particle pool for reducing memory fragmentation. - /// - typedef Pool<Particle> ParticlePool; + /// + /// Particle pool for reducing memory fragmentation. + /// + typedef Pool<Particle> ParticlePool; - } // namespace Particles - } // namespace Graphics + } // namespace Particles + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/particles/particle_system.cpp b/src/libjin/graphics/particles/particle_system.cpp index 984f42b..2552c5a 100644 --- a/src/libjin/graphics/particles/particle_system.cpp +++ b/src/libjin/graphics/particles/particle_system.cpp @@ -6,261 +6,261 @@ namespace JinEngine { - namespace Graphics - { - namespace Particles - { - - ParticleSystem::ParticleSystem(uint maxCount) - : mEmitter(*this) - , mParticlePool(maxCount, sizeof(Particle)) - { - } - - ParticleSystem::ParticleSystem(const ParticleSystemDef& def) - : mDef(def) - , mEmitter(*this) - , mParticlePool(def.maxParticleCount, sizeof(Particle)) - { - } - - ParticleSystem::~ParticleSystem() - { - } - - void ParticleSystem::setPosition(float x, float y) - { - mPosition.x() = x; - mPosition.y() = y; - } - - void ParticleSystem::update(float dt) - { - mEmitter.update(dt); - for (int i = 0; i < mAliveParticles.size(); ++i) - { - Particle* p = mAliveParticles[i]; - if (p->alive == false) - { - recycle(i, p); - --i; - } - else - { - p->update(dt); - } - } - } - - void ParticleSystem::render() - { - for (Particle* p : mAliveParticles) - p->render(); - } - - Particle* ParticleSystem::claim() - { - Particle* p = new (mParticlePool.GetNextWithoutInitializing()) Particle(); - mAliveParticles.push_back(p); - //jin_log_info("particle count %d", mAliveParticles.size()); - return p; - } - - void ParticleSystem::recycle(int i, Particle* p) - { - if (i >= mAliveParticles.size()) - return; - mAliveParticles.erase(mAliveParticles.begin() + i); - mParticlePool.Delete(p); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // Particle Emitter modification. - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - void ParticleSystem::setEmitRate(float floor, float ceil) - { - mDef.emitterDef.emitRateDef.enableRandom = true; - mDef.emitterDef.emitRateDef.rate.random.floor = floor; - mDef.emitterDef.emitRateDef.rate.random.ceil = ceil; - } - - void ParticleSystem::setEmitRate(float rate) - { - mDef.emitterDef.emitRateDef.enableRandom = false; - mDef.emitterDef.emitRateDef.rate.rate = rate; - } - - void ParticleSystem::setEmitForce(float floor, float ceil) - { - mDef.emitterDef.forceDef.enableRandom = true; - mDef.emitterDef.forceDef.force.random.floor = floor; - mDef.emitterDef.forceDef.force.random.ceil = ceil; - } - - void ParticleSystem::setEmitForce(float force) - { - mDef.emitterDef.forceDef.enableRandom = false; - mDef.emitterDef.forceDef.force.force = force; - } - - void ParticleSystem::setEmitDirection(float floor, float ceil) - { - mDef.emitterDef.directionDef.enableRandom = true; - mDef.emitterDef.directionDef.direction.random.floor = floor; - mDef.emitterDef.directionDef.direction.random.ceil = ceil; - } - - void ParticleSystem::setEmitDirection(float dir) - { - mDef.emitterDef.directionDef.enableRandom = false; - mDef.emitterDef.directionDef.direction.direction = dir; - } - - void ParticleSystem::setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil) - { - mDef.emitterDef.positionDef.enableRandom = true; - mDef.emitterDef.positionDef.position.random.floor = floor; - mDef.emitterDef.positionDef.position.random.ceil = ceil; - } - - void ParticleSystem::setEmitPosition(const Math::Vector2<float>& position) - { - mDef.emitterDef.positionDef.enableRandom = false; - mDef.emitterDef.positionDef.position.position = position; - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // Particle Emitter modification. - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - void ParticleSystem::setParticleLife(float floor, float ceil) - { - mDef.particleDef.lifeTimeDef.enableRandom = true; - mDef.particleDef.lifeTimeDef.life.random.floor = floor; - mDef.particleDef.lifeTimeDef.life.random.ceil = ceil; - } - - void ParticleSystem::setParticleLife(float time) - { - mDef.particleDef.lifeTimeDef.enableRandom = true; - mDef.particleDef.lifeTimeDef.life.life = time; - } - - void ParticleSystem::setParticleLinearAccelaration(Math::Vector2<float> ac) - { - mDef.particleDef.linearAccelarationDef.linearAccelaration = ac; - } - - void ParticleSystem::setParticleRadialAccelaration(float ra) - { - mDef.particleDef.radialAccelarationDef.radialAccelaration = ra; - } - - void ParticleSystem::setParticleAngularSpeed(float floor, float ceil) - { - mDef.particleDef.angularSpeedDef.enableRandom = true; - mDef.particleDef.angularSpeedDef.angularSpeed.random.floor = floor; - mDef.particleDef.angularSpeedDef.angularSpeed.random.ceil = ceil; - } - - void ParticleSystem::setParticleAngularSpeed(float speed) - { - mDef.particleDef.angularSpeedDef.enableRandom = false; - mDef.particleDef.angularSpeedDef.angularSpeed.angularSpeed = speed; - } - - void ParticleSystem::setParticleSpritesMode(SpriteMode mode) - { - mDef.particleDef.spritesDef.mode = mode; - } - - void ParticleSystem::addParticleSprite(const Sprite* sprite) - { - mDef.particleDef.spritesDef.sprites.push_back(sprite); - } - - void ParticleSystem::addParticleSprites(uint count, ...) - { - va_list args; - va_start(args, count); - while (count--) - { - Sprite* spr = va_arg(args, Sprite*); - addParticleSprite(spr); - } - va_end(args); - } - - void ParticleSystem::addParticleSprites(const std::vector<const Sprite*>& sprs) - { - for (const Sprite* spr : sprs) - { - addParticleSprite(spr); - } - } - - void ParticleSystem::removeParticleSprite(uint i) - { - mDef.particleDef.spritesDef.sprites.erase(mDef.particleDef.spritesDef.sprites.begin() + i); - } - - void ParticleSystem::enableParticleBlendAdditive(bool enable) - { - mDef.particleDef.blendDef.additive = enable; - } - - void ParticleSystem::setParticleScale(float scale) - { - mDef.particleDef.scaleDef.overTime.enable = false; - mDef.particleDef.scaleDef.scale = scale; - } - - void ParticleSystem::addParticleScalePoint(float scale, float t) - { - mDef.particleDef.scaleDef.overTime.enable = true; - mDef.particleDef.scaleDef.overTime.value.addPoint(t, scale); - } - - void ParticleSystem::removeParticleScalePoint(uint i) - { - mDef.particleDef.scaleDef.overTime.value.removePoint(i); - } - - void ParticleSystem::setParticleColor(Color tint) - { - mDef.particleDef.colorDef.overTime.enable = false; - mDef.particleDef.colorDef.color = tint; - } - - void ParticleSystem::addParticleColorPoint(Color tint, float t) - { - mDef.particleDef.colorDef.overTime.enable = true; - mDef.particleDef.colorDef.overTime.value.addColor(tint, t); - } - - void ParticleSystem::removeParticleColorPoint(uint i) - { - mDef.particleDef.colorDef.overTime.value.removeColor(i); - } - - void ParticleSystem::setParticleTransparency(float transparency) - { - mDef.particleDef.transparencyDef.overTime.enable = false; - mDef.particleDef.transparencyDef.transparency = transparency; - } - - void ParticleSystem::addParticleTransparencyPoint(float transparency, float t) - { - mDef.particleDef.transparencyDef.overTime.enable = true; - mDef.particleDef.transparencyDef.overTime.value.addPoint(t, transparency); - } - - void ParticleSystem::removeParticleTransparencyPoint(uint i) - { - mDef.particleDef.transparencyDef.overTime.value.removePoint(i); - } - - } - } + namespace Graphics + { + namespace Particles + { + + ParticleSystem::ParticleSystem(uint maxCount) + : mEmitter(*this) + , mParticlePool(maxCount, sizeof(Particle)) + { + } + + ParticleSystem::ParticleSystem(const ParticleSystemDef& def) + : mDef(def) + , mEmitter(*this) + , mParticlePool(def.maxParticleCount, sizeof(Particle)) + { + } + + ParticleSystem::~ParticleSystem() + { + } + + void ParticleSystem::setPosition(float x, float y) + { + mPosition.x() = x; + mPosition.y() = y; + } + + void ParticleSystem::update(float dt) + { + mEmitter.update(dt); + for (int i = 0; i < mAliveParticles.size(); ++i) + { + Particle* p = mAliveParticles[i]; + if (p->alive == false) + { + recycle(i, p); + --i; + } + else + { + p->update(dt); + } + } + } + + void ParticleSystem::render() + { + for (Particle* p : mAliveParticles) + p->render(); + } + + Particle* ParticleSystem::claim() + { + Particle* p = new (mParticlePool.GetNextWithoutInitializing()) Particle(); + mAliveParticles.push_back(p); + //jin_log_info("particle count %d", mAliveParticles.size()); + return p; + } + + void ParticleSystem::recycle(int i, Particle* p) + { + if (i >= mAliveParticles.size()) + return; + mAliveParticles.erase(mAliveParticles.begin() + i); + mParticlePool.Delete(p); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // Particle Emitter modification. + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ParticleSystem::setEmitRate(float floor, float ceil) + { + mDef.emitterDef.emitRateDef.enableRandom = true; + mDef.emitterDef.emitRateDef.rate.random.floor = floor; + mDef.emitterDef.emitRateDef.rate.random.ceil = ceil; + } + + void ParticleSystem::setEmitRate(float rate) + { + mDef.emitterDef.emitRateDef.enableRandom = false; + mDef.emitterDef.emitRateDef.rate.rate = rate; + } + + void ParticleSystem::setEmitForce(float floor, float ceil) + { + mDef.emitterDef.forceDef.enableRandom = true; + mDef.emitterDef.forceDef.force.random.floor = floor; + mDef.emitterDef.forceDef.force.random.ceil = ceil; + } + + void ParticleSystem::setEmitForce(float force) + { + mDef.emitterDef.forceDef.enableRandom = false; + mDef.emitterDef.forceDef.force.force = force; + } + + void ParticleSystem::setEmitDirection(float floor, float ceil) + { + mDef.emitterDef.directionDef.enableRandom = true; + mDef.emitterDef.directionDef.direction.random.floor = floor; + mDef.emitterDef.directionDef.direction.random.ceil = ceil; + } + + void ParticleSystem::setEmitDirection(float dir) + { + mDef.emitterDef.directionDef.enableRandom = false; + mDef.emitterDef.directionDef.direction.direction = dir; + } + + void ParticleSystem::setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil) + { + mDef.emitterDef.positionDef.enableRandom = true; + mDef.emitterDef.positionDef.position.random.floor = floor; + mDef.emitterDef.positionDef.position.random.ceil = ceil; + } + + void ParticleSystem::setEmitPosition(const Math::Vector2<float>& position) + { + mDef.emitterDef.positionDef.enableRandom = false; + mDef.emitterDef.positionDef.position.position = position; + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // Particle Emitter modification. + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ParticleSystem::setParticleLife(float floor, float ceil) + { + mDef.particleDef.lifeTimeDef.enableRandom = true; + mDef.particleDef.lifeTimeDef.life.random.floor = floor; + mDef.particleDef.lifeTimeDef.life.random.ceil = ceil; + } + + void ParticleSystem::setParticleLife(float time) + { + mDef.particleDef.lifeTimeDef.enableRandom = true; + mDef.particleDef.lifeTimeDef.life.life = time; + } + + void ParticleSystem::setParticleLinearAccelaration(Math::Vector2<float> ac) + { + mDef.particleDef.linearAccelarationDef.linearAccelaration = ac; + } + + void ParticleSystem::setParticleRadialAccelaration(float ra) + { + mDef.particleDef.radialAccelarationDef.radialAccelaration = ra; + } + + void ParticleSystem::setParticleAngularSpeed(float floor, float ceil) + { + mDef.particleDef.angularSpeedDef.enableRandom = true; + mDef.particleDef.angularSpeedDef.angularSpeed.random.floor = floor; + mDef.particleDef.angularSpeedDef.angularSpeed.random.ceil = ceil; + } + + void ParticleSystem::setParticleAngularSpeed(float speed) + { + mDef.particleDef.angularSpeedDef.enableRandom = false; + mDef.particleDef.angularSpeedDef.angularSpeed.angularSpeed = speed; + } + + void ParticleSystem::setParticleSpritesMode(SpriteMode mode) + { + mDef.particleDef.spritesDef.mode = mode; + } + + void ParticleSystem::addParticleSprite(const Sprite* sprite) + { + mDef.particleDef.spritesDef.sprites.push_back(sprite); + } + + void ParticleSystem::addParticleSprites(uint count, ...) + { + va_list args; + va_start(args, count); + while (count--) + { + Sprite* spr = va_arg(args, Sprite*); + addParticleSprite(spr); + } + va_end(args); + } + + void ParticleSystem::addParticleSprites(const std::vector<const Sprite*>& sprs) + { + for (const Sprite* spr : sprs) + { + addParticleSprite(spr); + } + } + + void ParticleSystem::removeParticleSprite(uint i) + { + mDef.particleDef.spritesDef.sprites.erase(mDef.particleDef.spritesDef.sprites.begin() + i); + } + + void ParticleSystem::enableParticleBlendAdditive(bool enable) + { + mDef.particleDef.blendDef.additive = enable; + } + + void ParticleSystem::setParticleScale(float scale) + { + mDef.particleDef.scaleDef.overTime.enable = false; + mDef.particleDef.scaleDef.scale = scale; + } + + void ParticleSystem::addParticleScalePoint(float scale, float t) + { + mDef.particleDef.scaleDef.overTime.enable = true; + mDef.particleDef.scaleDef.overTime.value.addPoint(t, scale); + } + + void ParticleSystem::removeParticleScalePoint(uint i) + { + mDef.particleDef.scaleDef.overTime.value.removePoint(i); + } + + void ParticleSystem::setParticleColor(Color tint) + { + mDef.particleDef.colorDef.overTime.enable = false; + mDef.particleDef.colorDef.color = tint; + } + + void ParticleSystem::addParticleColorPoint(Color tint, float t) + { + mDef.particleDef.colorDef.overTime.enable = true; + mDef.particleDef.colorDef.overTime.value.addColor(tint, t); + } + + void ParticleSystem::removeParticleColorPoint(uint i) + { + mDef.particleDef.colorDef.overTime.value.removeColor(i); + } + + void ParticleSystem::setParticleTransparency(float transparency) + { + mDef.particleDef.transparencyDef.overTime.enable = false; + mDef.particleDef.transparencyDef.transparency = transparency; + } + + void ParticleSystem::addParticleTransparencyPoint(float transparency, float t) + { + mDef.particleDef.transparencyDef.overTime.enable = true; + mDef.particleDef.transparencyDef.overTime.value.addPoint(t, transparency); + } + + void ParticleSystem::removeParticleTransparencyPoint(uint i) + { + mDef.particleDef.transparencyDef.overTime.value.removePoint(i); + } + + } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/particles/particle_system.h b/src/libjin/graphics/particles/particle_system.h index 83351a9..d3e3369 100644 --- a/src/libjin/graphics/particles/particle_system.h +++ b/src/libjin/graphics/particles/particle_system.h @@ -14,182 +14,182 @@ namespace JinEngine { - namespace Graphics - { - namespace Particles - { - - /// - /// Definition of particle system. - /// - struct ParticleSystemDef - { - ParticleSystemDef() {} - uint maxParticleCount = 1; ///< Max count of particles in pool. 1 by default. - ParticleEmitterDef emitterDef; ///< Particle emitter definition. - ParticleDef particleDef; ///< Particle definition. - }; - - /// - /// Particle emitter, handle all particles it emitts. - /// - class ParticleSystem : public Renderable, public Game::GameObject - { - public: - /// - /// Particle system constructor - /// - /// @param def Definition of particle system. - /// - ParticleSystem(const ParticleSystemDef& def); - - /// - /// - /// - ParticleSystem(uint maxCount = 64); - - /// - /// - /// - ParticleSystem(const std::string & config); - - /// - /// Particle system destructor. - /// - ~ParticleSystem(); - - /// - /// - /// - void setDefinition(const ParticleSystemDef& def); - - /// - /// Load definition from config. - /// - void setDefinition(const std::string& config); - - /// - /// Update particle system and all alive particles. - /// - void update(float dt); - - /// - /// Render particle system. - /// - void render(); - - /// - /// Set particle system position. - /// - void setPosition(float x, float y); - - /// - /// Set scale. - /// - void setScale(float sx, float sy); - - /// - /// Pause particle spawn. - /// - void pause(bool isPause); - - /// - /// Clear all particles. - /// - void clear(); - - ////////////////////////////////////////////////////////////////////////////////////////////////// - // Particle Emitter modification. - ////////////////////////////////////////////////////////////////////////////////////////////////// - - void setEmitRate(float floor, float ceil); - void setEmitRate(float rate); - - void setEmitForce(float floor, float ceil); - void setEmitForce(float force); - - void setEmitDirection(float floor, float ceil); - void setEmitDirection(float dir); - - void setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil); - void setEmitPosition(const Math::Vector2<float>& position); - - ////////////////////////////////////////////////////////////////////////////////////////////////// - // Particle modification. - ////////////////////////////////////////////////////////////////////////////////////////////////// - - void setParticleLife(float floor, float ceil); - void setParticleLife(float time); - - void setParticleLinearAccelaration(Math::Vector2<float> ac); - - void setParticleRadialAccelaration(float ra); - - void setParticleAngularSpeed(float floor, float ceil); - void setParticleAngularSpeed(float speed); - - void setParticleSpritesMode(SpriteMode mode); - void addParticleSprite(const Sprite* sprite); - void addParticleSprites(uint count, ...); - void addParticleSprites(const std::vector<const Sprite*>& sprs); - void removeParticleSprite(uint i); - - void enableParticleBlendAdditive(bool enable); - - void setParticleScale(float scale); - void addParticleScalePoint(float scale, float t); - void removeParticleScalePoint(uint i); - - void setParticleColor(Color tint); - void addParticleColorPoint(Color tint, float t); - void removeParticleColorPoint(uint i); - - void setParticleTransparency(float transparency); - void addParticleTransparencyPoint(float transparency, float t); - void removeParticleTransparencyPoint(uint i); + namespace Graphics + { + namespace Particles + { + + /// + /// Definition of particle system. + /// + struct ParticleSystemDef + { + ParticleSystemDef() {} + uint maxParticleCount = 1; ///< Max count of particles in pool. 1 by default. + ParticleEmitterDef emitterDef; ///< Particle emitter definition. + ParticleDef particleDef; ///< Particle definition. + }; + + /// + /// Particle emitter, handle all particles it emitts. + /// + class ParticleSystem : public Renderable, public Game::GameObject + { + public: + /// + /// Particle system constructor + /// + /// @param def Definition of particle system. + /// + ParticleSystem(const ParticleSystemDef& def); + + /// + /// + /// + ParticleSystem(uint maxCount = 64); + + /// + /// + /// + ParticleSystem(const std::string & config); + + /// + /// Particle system destructor. + /// + ~ParticleSystem(); + + /// + /// + /// + void setDefinition(const ParticleSystemDef& def); + + /// + /// Load definition from config. + /// + void setDefinition(const std::string& config); + + /// + /// Update particle system and all alive particles. + /// + void update(float dt); + + /// + /// Render particle system. + /// + void render(); + + /// + /// Set particle system position. + /// + void setPosition(float x, float y); + + /// + /// Set scale. + /// + void setScale(float sx, float sy); + + /// + /// Pause particle spawn. + /// + void pause(bool isPause); + + /// + /// Clear all particles. + /// + void clear(); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Particle Emitter modification. + ////////////////////////////////////////////////////////////////////////////////////////////////// + + void setEmitRate(float floor, float ceil); + void setEmitRate(float rate); + + void setEmitForce(float floor, float ceil); + void setEmitForce(float force); + + void setEmitDirection(float floor, float ceil); + void setEmitDirection(float dir); + + void setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil); + void setEmitPosition(const Math::Vector2<float>& position); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Particle modification. + ////////////////////////////////////////////////////////////////////////////////////////////////// + + void setParticleLife(float floor, float ceil); + void setParticleLife(float time); + + void setParticleLinearAccelaration(Math::Vector2<float> ac); + + void setParticleRadialAccelaration(float ra); + + void setParticleAngularSpeed(float floor, float ceil); + void setParticleAngularSpeed(float speed); + + void setParticleSpritesMode(SpriteMode mode); + void addParticleSprite(const Sprite* sprite); + void addParticleSprites(uint count, ...); + void addParticleSprites(const std::vector<const Sprite*>& sprs); + void removeParticleSprite(uint i); + + void enableParticleBlendAdditive(bool enable); + + void setParticleScale(float scale); + void addParticleScalePoint(float scale, float t); + void removeParticleScalePoint(uint i); + + void setParticleColor(Color tint); + void addParticleColorPoint(Color tint, float t); + void removeParticleColorPoint(uint i); + + void setParticleTransparency(float transparency); + void addParticleTransparencyPoint(float transparency, float t); + void removeParticleTransparencyPoint(uint i); - private: - friend class ParticleEmitter; - - /// - /// Particle system position. - /// - Math::Vector2<float> mPosition; + private: + friend class ParticleEmitter; + + /// + /// Particle system position. + /// + Math::Vector2<float> mPosition; - /// - /// - /// - Particle* claim(); + /// + /// + /// + Particle* claim(); - /// - /// - /// - void recycle(int i, Particle* p); + /// + /// + /// + void recycle(int i, Particle* p); - /// - /// Particle system definition. - /// - ParticleSystemDef mDef; + /// + /// Particle system definition. + /// + ParticleSystemDef mDef; - /// - /// Particle emitter. - /// - ParticleEmitter mEmitter; + /// + /// Particle emitter. + /// + ParticleEmitter mEmitter; - /// - /// Particle pool. - /// - ParticlePool mParticlePool; + /// + /// Particle pool. + /// + ParticlePool mParticlePool; - /// - /// Alive particles, that means these particles could join to the life cycle loop. - /// - std::vector<Particle*> mAliveParticles; + /// + /// Alive particles, that means these particles could join to the life cycle loop. + /// + std::vector<Particle*> mAliveParticles; - }; + }; - } // namespace Particles - } // namespace Graphics + } // namespace Particles + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/renderable.h b/src/libjin/graphics/renderable.h index ca9888e..8d8772c 100644 --- a/src/libjin/graphics/renderable.h +++ b/src/libjin/graphics/renderable.h @@ -3,39 +3,39 @@ namespace JinEngine { - namespace Graphics - { - - namespace Shaders { class Shader; }; - - enum class Origin - { - TOPLEFT, - TOPCENTER, - TOPRIGHT, - MIDDLELEFT, - MIDDLECENTER, - MIDDLERIGHT, - BOTTOMLEFT, - BOTTOMCENTER, - BOTTOMRIGHT - }; - - class Renderable - { - public: - //void setShader(const Shaders::Shader* shader); - - virtual void render(float x, float y, float sx, float sy, float r) const {}; - virtual void render(float x, float y, float sx, float sy, float r, float ox, float oy) const {}; - virtual void render(float x, float y, float sx, float sy, float r, Origin origin) const {}; - - protected: - //const Shaders::Shader* mShader; - - }; - - } + namespace Graphics + { + + namespace Shaders { class Shader; }; + + enum class Origin + { + TOPLEFT, + TOPCENTER, + TOPRIGHT, + MIDDLELEFT, + MIDDLECENTER, + MIDDLERIGHT, + BOTTOMLEFT, + BOTTOMCENTER, + BOTTOMRIGHT + }; + + class Renderable + { + public: + //void setShader(const Shaders::Shader* shader); + + virtual void render(float x, float y, float sx, float sy, float r) const {}; + virtual void render(float x, float y, float sx, float sy, float r, float ox, float oy) const {}; + virtual void render(float x, float y, float sx, float sy, float r, Origin origin) const {}; + + protected: + //const Shaders::Shader* mShader; + + }; + + } } #endif
\ No newline at end of file diff --git a/src/libjin/graphics/shaders/built-in/default.shader.h b/src/libjin/graphics/shaders/built-in/default.shader.h index 3f57c44..0a7267b 100644 --- a/src/libjin/graphics/shaders/built-in/default.shader.h +++ b/src/libjin/graphics/shaders/built-in/default.shader.h @@ -5,7 +5,7 @@ static const char* default_shader = R"( Vertex vert(Vertex v) { - return v; + return v; } #END_VERTEX_SHADER @@ -14,7 +14,7 @@ Vertex vert(Vertex v) Color frag(Color col, Texture tex, Vertex v) { - return col * texel(tex, v.uv); + return col * texel(tex, v.uv); } #END_FRAGMENT_SHADER diff --git a/src/libjin/graphics/shaders/built-in/font.shader.h b/src/libjin/graphics/shaders/built-in/font.shader.h index e04c225..9d15284 100644 --- a/src/libjin/graphics/shaders/built-in/font.shader.h +++ b/src/libjin/graphics/shaders/built-in/font.shader.h @@ -5,7 +5,7 @@ static const char* font_shader = R"( Vertex vert(Vertex v) { - return v; + return v; } #END_VERTEX_SHADER @@ -14,7 +14,7 @@ Vertex vert(Vertex v) Color frag(Color col, Texture tex, Vertex v) { - return Color(col.rgb, texel(tex, v.uv).a); + return Color(col.rgb, texel(tex, v.uv).a); } #END_FRAGMENT_SHADER diff --git a/src/libjin/graphics/shaders/built-in/texture.shader.h b/src/libjin/graphics/shaders/built-in/texture.shader.h index d1fc86f..9e4a545 100644 --- a/src/libjin/graphics/shaders/built-in/texture.shader.h +++ b/src/libjin/graphics/shaders/built-in/texture.shader.h @@ -5,7 +5,7 @@ static const char* texture_shader = R"( Vertex vert(Vertex v) { - return v; + return v; } #END_VERTEX_SHADER @@ -14,7 +14,7 @@ Vertex vert(Vertex v) Color frag(Color col, Texture tex, Vertex v) { - return col * texel(tex, v.uv); + return col * texel(tex, v.uv); } #END_FRAGMENT_SHADER diff --git a/src/libjin/graphics/shaders/jsl_compiler.cpp b/src/libjin/graphics/shaders/jsl_compiler.cpp index 44908e8..ea247c0 100644 --- a/src/libjin/graphics/shaders/jsl_compiler.cpp +++ b/src/libjin/graphics/shaders/jsl_compiler.cpp @@ -11,146 +11,146 @@ using namespace JinEngine::Filesystem; namespace JinEngine { - namespace Graphics - { - namespace Shaders - { + namespace Graphics + { + namespace Shaders + { - /// - /// Uniforms: - /// jin_ProjectionMatrix --+ - /// jin_ModelViewMatrix |- Uniforms - /// jin_MainTexture | - /// jin_RenderTargetSize | - /// jin_Time --+ - /// - /// Built-in variables in vertex shader: - /// jin_VertexCoords --+ - /// jin_TextureCoords |- Attributes - /// jin_VertexColor --+ - /// jin_Color ---- GLSL built in - /// - /// Built-in variables in fragment shader: - /// jin_Color --+ - /// jin_XY |- Inputs - /// jin_UV | - /// jin_COLOR --+ - /// + /// + /// Uniforms: + /// jin_ProjectionMatrix --+ + /// jin_ModelViewMatrix |- Uniforms + /// jin_MainTexture | + /// jin_RenderTargetSize | + /// jin_Time --+ + /// + /// Built-in variables in vertex shader: + /// jin_VertexCoords --+ + /// jin_TextureCoords |- Attributes + /// jin_VertexColor --+ + /// jin_Color ---- GLSL built in + /// + /// Built-in variables in fragment shader: + /// jin_Color --+ + /// jin_XY |- Inputs + /// jin_UV | + /// jin_COLOR --+ + /// - JinEngine::String SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix"; - JinEngine::String SHADER_MODELVIEW_MATRIX = "jin_ModelViewMatrix"; - JinEngine::String SHADER_MAIN_TEXTURE = "jin_MainTexture"; - JinEngine::String SHADER_VERTEX_COORDS = "jin_VertexCoords"; - JinEngine::String SHADER_TEXTURE_COORDS = "jin_TextureCoords"; - JinEngine::String SHADER_VERTEX_COLOR = "jin_VertexColor"; - JinEngine::String SHADER_TIME = "jin_Time"; - JinEngine::String SHADER_RENDERTARGET_SIZE = "jin_RenderTargetSize"; - JinEngine::String SHADER_VERSION = "#version 130 core \n"; - JinEngine::String SHADER_DEFINITIONS = - // Types - "#define Number float \n" - "#define Texture sampler2D \n" - "#define Canvas sampler2D \n" - "#define Color vec4 \n" - "#define Vec2 vec2 \n" - "#define Vec3 vec3 \n" - "#define Vec4 vec4 \n" - // Functions - "#define texel texture2D \n" - // Structs - "struct Vertex \n" - "{ \n" - " vec2 xy; \n" - " vec2 uv; \n" - " vec4 color; \n" - "}; \n" - "\n"; - JinEngine::String SHADER_UNIFORMS = - "uniform Texture " + SHADER_MAIN_TEXTURE + "; \n" // Main texture goes first. - "uniform mat4 " + SHADER_PROJECTION_MATRIX + "; \n" - "uniform mat4 " + SHADER_MODELVIEW_MATRIX + "; \n" - "uniform vec2 " + SHADER_TIME + "; \n" - "uniform vec2 " + SHADER_RENDERTARGET_SIZE + "; \n"; + JinEngine::String SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix"; + JinEngine::String SHADER_MODELVIEW_MATRIX = "jin_ModelViewMatrix"; + JinEngine::String SHADER_MAIN_TEXTURE = "jin_MainTexture"; + JinEngine::String SHADER_VERTEX_COORDS = "jin_VertexCoords"; + JinEngine::String SHADER_TEXTURE_COORDS = "jin_TextureCoords"; + JinEngine::String SHADER_VERTEX_COLOR = "jin_VertexColor"; + JinEngine::String SHADER_TIME = "jin_Time"; + JinEngine::String SHADER_RENDERTARGET_SIZE = "jin_RenderTargetSize"; + JinEngine::String SHADER_VERSION = "#version 130 core \n"; + JinEngine::String SHADER_DEFINITIONS = + // Types + "#define Number float \n" + "#define Texture sampler2D \n" + "#define Canvas sampler2D \n" + "#define Color vec4 \n" + "#define Vec2 vec2 \n" + "#define Vec3 vec3 \n" + "#define Vec4 vec4 \n" + // Functions + "#define texel texture2D \n" + // Structs + "struct Vertex \n" + "{ \n" + " vec2 xy; \n" + " vec2 uv; \n" + " vec4 color; \n" + "}; \n" + "\n"; + JinEngine::String SHADER_UNIFORMS = + "uniform Texture " + SHADER_MAIN_TEXTURE + "; \n" // Main texture goes first. + "uniform mat4 " + SHADER_PROJECTION_MATRIX + "; \n" + "uniform mat4 " + SHADER_MODELVIEW_MATRIX + "; \n" + "uniform vec2 " + SHADER_TIME + "; \n" + "uniform vec2 " + SHADER_RENDERTARGET_SIZE + "; \n"; - JinEngine::String JSLCompiler::formatVertexShader(const JinEngine::String& vert) - { - static JinEngine::String vert_part1 = - SHADER_VERSION + - SHADER_DEFINITIONS + - SHADER_UNIFORMS + - "in vec2 " + SHADER_VERTEX_COORDS + "; \n" - "in vec2 " + SHADER_TEXTURE_COORDS + "; \n" - "in vec4 " + SHADER_VERTEX_COLOR + "; \n"; // Color data in unsigned byte. - static JinEngine::String vert_part2 = - "\n" - "out vec4 jin_Color; \n" - "out vec2 jin_XY; \n" - "out vec2 jin_UV; \n" - "out vec4 jin_COLOR; \n" - "void main()\n" - "{\n" - " vec4 v = " + SHADER_MODELVIEW_MATRIX + " * vec4(" + SHADER_VERTEX_COORDS + ", 0, 1.0); \n" - " Vertex _v = vert(Vertex(v.xy, " + SHADER_TEXTURE_COORDS + ", " + SHADER_VERTEX_COLOR + ")); \n" - " gl_Position = " + SHADER_PROJECTION_MATRIX + " * vec4(_v.xy, 0, 1.0f); \n" - " jin_Color = gl_Color; \n" - " jin_XY = _v.xy; \n" - " jin_UV = _v.uv; \n" - " jin_COLOR = _v.color; \n" - "}"; - return vert_part1 + vert + vert_part2; - } + JinEngine::String JSLCompiler::formatVertexShader(const JinEngine::String& vert) + { + static JinEngine::String vert_part1 = + SHADER_VERSION + + SHADER_DEFINITIONS + + SHADER_UNIFORMS + + "in vec2 " + SHADER_VERTEX_COORDS + "; \n" + "in vec2 " + SHADER_TEXTURE_COORDS + "; \n" + "in vec4 " + SHADER_VERTEX_COLOR + "; \n"; // Color data in unsigned byte. + static JinEngine::String vert_part2 = + "\n" + "out vec4 jin_Color; \n" + "out vec2 jin_XY; \n" + "out vec2 jin_UV; \n" + "out vec4 jin_COLOR; \n" + "void main()\n" + "{\n" + " vec4 v = " + SHADER_MODELVIEW_MATRIX + " * vec4(" + SHADER_VERTEX_COORDS + ", 0, 1.0); \n" + " Vertex _v = vert(Vertex(v.xy, " + SHADER_TEXTURE_COORDS + ", " + SHADER_VERTEX_COLOR + ")); \n" + " gl_Position = " + SHADER_PROJECTION_MATRIX + " * vec4(_v.xy, 0, 1.0f); \n" + " jin_Color = gl_Color; \n" + " jin_XY = _v.xy; \n" + " jin_UV = _v.uv; \n" + " jin_COLOR = _v.color; \n" + "}"; + return vert_part1 + vert + vert_part2; + } - JinEngine::String JSLCompiler::formatFragmentShader(const JinEngine::String& frag) - { - static JinEngine::String frag_part1 = - SHADER_VERSION + - SHADER_DEFINITIONS + - SHADER_UNIFORMS + - "in vec4 jin_Color; \n" - "in vec2 jin_XY; \n" - "in vec2 jin_UV; \n" - "in vec4 jin_COLOR; \n"; - static JinEngine::String frag_part2 = - "\n" - "out vec4 jin_OutColor; \n" - "void main() \n" - "{ \n" - " jin_OutColor = frag(jin_Color, " + SHADER_MAIN_TEXTURE + ", Vertex(jin_XY, jin_UV, jin_COLOR)); \n" - "} \n"; - return frag_part1 + frag + frag_part2; - } + JinEngine::String JSLCompiler::formatFragmentShader(const JinEngine::String& frag) + { + static JinEngine::String frag_part1 = + SHADER_VERSION + + SHADER_DEFINITIONS + + SHADER_UNIFORMS + + "in vec4 jin_Color; \n" + "in vec2 jin_XY; \n" + "in vec2 jin_UV; \n" + "in vec4 jin_COLOR; \n"; + static JinEngine::String frag_part2 = + "\n" + "out vec4 jin_OutColor; \n" + "void main() \n" + "{ \n" + " jin_OutColor = frag(jin_Color, " + SHADER_MAIN_TEXTURE + ", Vertex(jin_XY, jin_UV, jin_COLOR)); \n" + "} \n"; + return frag_part1 + frag + frag_part2; + } - bool JSLCompiler::compile(const string& jsl, string* vertex_shader, string* fragment_shader) - { - // parse shader source, need some optimizations - int loc_VERTEX_SHADER = jsl.find("#VERTEX_SHADER"); - int loc_END_VERTEX_SHADER = jsl.find("#END_VERTEX_SHADER"); - int loc_FRAGMENT_SHADER = jsl.find("#FRAGMENT_SHADER"); - int loc_END_FRAGMENT_SHADER = jsl.find("#END_FRAGMENT_SHADER"); - if ( loc_VERTEX_SHADER == string::npos - || loc_END_VERTEX_SHADER == string::npos - || loc_FRAGMENT_SHADER == string::npos - || loc_END_FRAGMENT_SHADER == string::npos - ) - return false; - // Load vertex and fragment shader source into buffers. - { - // Compile JSL vertex program. - int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); - *vertex_shader = jsl.substr(start, loc_END_VERTEX_SHADER - start); - vertex_shader->assign(formatVertexShader(*vertex_shader)); - } - { - // Compile JSL fragment program. - int start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); - *fragment_shader = jsl.substr(start, loc_END_FRAGMENT_SHADER - start); - fragment_shader->assign(formatFragmentShader(*fragment_shader)); - } - return true; - } + bool JSLCompiler::compile(const string& jsl, string* vertex_shader, string* fragment_shader) + { + // parse shader source, need some optimizations + int loc_VERTEX_SHADER = jsl.find("#VERTEX_SHADER"); + int loc_END_VERTEX_SHADER = jsl.find("#END_VERTEX_SHADER"); + int loc_FRAGMENT_SHADER = jsl.find("#FRAGMENT_SHADER"); + int loc_END_FRAGMENT_SHADER = jsl.find("#END_FRAGMENT_SHADER"); + if ( loc_VERTEX_SHADER == string::npos + || loc_END_VERTEX_SHADER == string::npos + || loc_FRAGMENT_SHADER == string::npos + || loc_END_FRAGMENT_SHADER == string::npos + ) + return false; + // Load vertex and fragment shader source into buffers. + { + // Compile JSL vertex program. + int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); + *vertex_shader = jsl.substr(start, loc_END_VERTEX_SHADER - start); + vertex_shader->assign(formatVertexShader(*vertex_shader)); + } + { + // Compile JSL fragment program. + int start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); + *fragment_shader = jsl.substr(start, loc_END_FRAGMENT_SHADER - start); + fragment_shader->assign(formatFragmentShader(*fragment_shader)); + } + return true; + } - } // namespace Shaders - } // namespace Graphics + } // namespace Shaders + } // namespace Graphics } // namespace JinEngine #endif // (jin_graphics) && (jin_graphics & jin_graphics_shader)
\ No newline at end of file diff --git a/src/libjin/graphics/shaders/jsl_compiler.h b/src/libjin/graphics/shaders/jsl_compiler.h index ad3bdbb..f7aa48a 100644 --- a/src/libjin/graphics/shaders/jsl_compiler.h +++ b/src/libjin/graphics/shaders/jsl_compiler.h @@ -11,45 +11,45 @@ namespace JinEngine { - namespace Graphics - { - namespace Shaders - { - - extern JinEngine::String SHADER_PROJECTION_MATRIX; - extern JinEngine::String SHADER_MODELVIEW_MATRIX; - extern JinEngine::String SHADER_MAIN_TEXTURE; - extern JinEngine::String SHADER_VERTEX_COORDS; - extern JinEngine::String SHADER_TEXTURE_COORDS; - extern JinEngine::String SHADER_VERTEX_COLOR; - extern JinEngine::String SHADER_TIME; - extern JinEngine::String SHADER_RENDERTARGET_SIZE; - - /// - /// Compile JSL into GLSL. - /// - class JSLCompiler : public Singleton<JSLCompiler> - { - public: - /// - /// Compile JSL shader source into GLSL. - /// - /// @param jsl JSL shader source. - /// @param glsl_vertex Output of vertex glsl shader source. - /// @param glsl_fragment Output of fragment glsl shader source. - /// @return True if compile successful, otherwise return false. - /// - bool compile(const std::string& jsl, std::string* glsl_vertex, std::string* glsl_fragment); - - private: - JinEngine::String formatVertexShader(const JinEngine::String& vert); - - JinEngine::String formatFragmentShader(const JinEngine::String& frag); - - }; - - } // namespace Shaders - } // namespace Graphics + namespace Graphics + { + namespace Shaders + { + + extern JinEngine::String SHADER_PROJECTION_MATRIX; + extern JinEngine::String SHADER_MODELVIEW_MATRIX; + extern JinEngine::String SHADER_MAIN_TEXTURE; + extern JinEngine::String SHADER_VERTEX_COORDS; + extern JinEngine::String SHADER_TEXTURE_COORDS; + extern JinEngine::String SHADER_VERTEX_COLOR; + extern JinEngine::String SHADER_TIME; + extern JinEngine::String SHADER_RENDERTARGET_SIZE; + + /// + /// Compile JSL into GLSL. + /// + class JSLCompiler : public Singleton<JSLCompiler> + { + public: + /// + /// Compile JSL shader source into GLSL. + /// + /// @param jsl JSL shader source. + /// @param glsl_vertex Output of vertex glsl shader source. + /// @param glsl_fragment Output of fragment glsl shader source. + /// @return True if compile successful, otherwise return false. + /// + bool compile(const std::string& jsl, std::string* glsl_vertex, std::string* glsl_fragment); + + private: + JinEngine::String formatVertexShader(const JinEngine::String& vert); + + JinEngine::String formatFragmentShader(const JinEngine::String& frag); + + }; + + } // namespace Shaders + } // namespace Graphics } // namespace JinEngine #endif // (jin_graphics) && (jin_graphics & jin_graphics_shader) diff --git a/src/libjin/graphics/shaders/shader.cpp b/src/libjin/graphics/shaders/shader.cpp index 36f6603..44b2cb0 100644 --- a/src/libjin/graphics/shaders/shader.cpp +++ b/src/libjin/graphics/shaders/shader.cpp @@ -20,302 +20,302 @@ using namespace JinEngine::Time; namespace JinEngine { - namespace Graphics - { - namespace Shaders - { - - // - // default_texture - // base_shader - // SHADER_FORMAT_SIZE - // formatShader - // - #include "built-in/default.shader.h" - - // - // https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value - // The default value of a sampler variable is 0. From the GLSL 3.30 spec, - // section "4.3.5 Uniforms": - // - // The link time initial value is either the value of the variable's - // initializer, if present, or 0 if no initializer is present.Sampler - // types cannot have initializers. - // - // Since a value of 0 means that it's sampling from texture unit 0, it will - // work without ever setting the value as long as you bind your textures to - // unit 0. This is well defined behavior. - // - // Since texture unit 0 is also the default until you call glActiveTexture() - // with a value other than GL_TEXTURE0, it's very common to always use unit - // 0 as long as shaders do not need more than one texture.Which means that - // often times, setting the sampler uniforms is redundant for simple - // applications. - // - // I would still prefer to always set the values.If nothing else, it makes - // it clear to anybody reading your code that you really mean to sample from - // texture unit 0, and did not just forget to set the value. - // - const int MAIN_TEXTURE_UNIT = 0; - - static GLint textureUnit = 0; - - GLint Shader::mAttributeIndex = 0; - - Shader::Shader(const string& program) - { - if (!compile(program)) - { - jin_log_error("Compile jsl shader failed."); - throw Exception("Compile jsl shader failed"); - } - } - - Shader::~Shader() - { - if (gl.getShader() == this) - gl.unuseShader(); - // Delete shader program. - glDeleteShader(mPID); - } - - Shader& Shader::begin() - { - - textureUnit = MAIN_TEXTURE_UNIT; - - // Send uniforms. - sendInt(SHADER_MAIN_TEXTURE, MAIN_TEXTURE_UNIT); - sendVec2(SHADER_TIME, Time::getSecond(), Time::getDeltaTime()); - Canvas* rt = gl.getCanvas(); - if (rt == OpenGL::SCREEN) - { - sendVec2(SHADER_RENDERTARGET_SIZE, Window::get()->getW(), Window::get()->getH()); - } - else if(rt != nullptr) - { - sendVec2(SHADER_RENDERTARGET_SIZE, rt->getWidth(), rt->getHeight()); - } - - gl.activeTextureUnit(MAIN_TEXTURE_UNIT); - - return *this; - } - - void Shader::end() - { - // Reset attribute index. - for (; mAttributeIndex > 0; --mAttributeIndex) - glDisableVertexAttribArray(mAttributeIndex); - } - - bool Shader::compile(const string& program) - { - string vertex_shader, fragment_shader; - // Compile JSL shader source into GLSL shader source. - JSLCompiler* compiler = JSLCompiler::get(); - if (!compiler->compile(program, &vertex_shader, &fragment_shader)) - { - return false; - } - - #define glsl(SHADER_MODE, SHADER, SRC) \ - do{ \ - const GLchar* src = SRC.c_str(); \ - glShaderSource(SHADER, 1, &src, NULL); \ - glCompileShader(SHADER); \ - GLint success; \ - glGetShaderiv(SHADER, GL_COMPILE_STATUS, &success); \ - if (success == GL_FALSE) \ - return false; \ - }while(0) - - // Compile vertex shader. - GLuint vid = glCreateShader(GL_VERTEX_SHADER); - glsl(GL_VERTEX_SHADER, vid, vertex_shader); - // Compile fragment shader. - GLuint fid = glCreateShader(GL_FRAGMENT_SHADER); - glsl(GL_FRAGMENT_SHADER, fid, fragment_shader); - - #undef glsl - // Create OpenGL shader program. - mPID = glCreateProgram(); - glAttachShader(mPID, vid); - glAttachShader(mPID, fid); - glLinkProgram(mPID); - GLint success; - glGetProgramiv(mPID, GL_LINK_STATUS, &success); - if (success == GL_FALSE) - return false; - } - - static inline GLint getMaxTextureUnits() - { - GLint maxTextureUnits = 0; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - return maxTextureUnits; - } - - GLint Shader::claimTextureUnit(/*const std::string& name*/) - { - return textureUnit++; - } - - GLint Shader::getUniformLocation(const char* uniform) - { - map<std::string, GLint>::iterator it = mUniformsLocation.find(uniform); - if (it != mUniformsLocation.end()) - return it->second; - GLint loc = glGetUniformLocation(mPID, uniform); - mUniformsLocation.insert(pair<std::string, GLint>(uniform, loc)); - return loc; - } - - #define check_jsl() \ - if (gl.getShader() != this) \ - return *this - - Shader & Shader::sendInt(const char* name, int value) - { - check_jsl(); - int loc = getUniformLocation(name); - glUniform1i(loc, value); - return *this; - } - - Shader& Shader::sendFloat(const char* variable, float number) - { - check_jsl(); - int loc = getUniformLocation(variable); - glUniform1f(loc, number); - return *this; - } - - // - // https://www.douban.com/note/627332677/ - // struct TextureUnit - // { - // GLuint targetTexture1D; - // GLuint targetTexture2D; - // GLuint targetTexture3D; - // GLuint targetTextureCube; - // ... - // }; - // - // TextureUnit mTextureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] - // GLuint mCurrentTextureUnit = 0; - // - Shader& Shader::sendTexture(const char* variable, const Texture* tex) - { - check_jsl(); - GLint location = getUniformLocation(variable); - if (location == -1) - return *this; - GLint unit = claimTextureUnit(/*variable*/); - if (unit == 0) - { - // TODO: 쳣 - return *this; - } - gl.activeTextureUnit(unit); - gl.bindTexture2D(tex->getGLTexture()); - glUniform1i(location, unit); - gl.activeTextureUnit(MAIN_TEXTURE_UNIT); - return *this; - } - - Shader& Shader::sendCanvas(const char* variable, const Canvas* canvas) - { - check_jsl(); - GLint location = getUniformLocation(variable); - if (location == -1) - return *this; - GLint unit = claimTextureUnit(/*variable*/); - if (unit == 0) - { - // TODO: 쳣 - return *this; - } - glActiveTexture(GL_TEXTURE0 + unit); - gl.bindTexture2D(canvas->getGLTexture()); - glUniform1i(location, unit); - - glActiveTexture(GL_TEXTURE0); - return *this; - } - - Shader& Shader::sendVec2(const char* name, float x, float y) - { - check_jsl(); - int loc = getUniformLocation(name); - glUniform2f(loc, x, y); - return *this; - } - - Shader& Shader::sendVec3(const char* name, float x, float y, float z) - { - check_jsl(); - int loc = getUniformLocation(name); - glUniform3f(loc, x, y, z); - return *this; - } - - Shader& Shader::sendVec4(const char* name, float x, float y, float z, float w) - { - check_jsl(); - int loc = getUniformLocation(name); - glUniform4f(loc, x, y, z, w); - return *this; - } - - Shader& Shader::sendColor(const char* name, const Color* col) - { - check_jsl(); - int loc = getUniformLocation(name); - glUniform4f(loc, - col->r / 255.f, - col->g / 255.f, - col->b / 255.f, - col->a / 255.f - ); - return *this; - } - - Shader& Shader::sendMatrix4(const char* name, const Math::Matrix* mat4) - { - int loc = getUniformLocation(name); - glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); - return *this; - } - - Shader& Shader::uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) - { - uploadAttribute(SHADER_VERTEX_COORDS, n, type, stride, pointers, normalized); - return *this; - } - - Shader& Shader::uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) - { - uploadAttribute(SHADER_TEXTURE_COORDS, n, type, stride, pointers, normalized); - return *this; - } - - Shader& Shader::uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) - { - uploadAttribute(SHADER_VERTEX_COLOR, n, type, stride, pointers, normalized); - return *this; - } - - Shader& Shader::uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) - { - GLint loc = glGetAttribLocation(mPID, name); - glEnableVertexAttribArray(mAttributeIndex++); - glVertexAttribPointer(loc, n, type, normalized, stride, pointers); - return *this; - } - - } // namespace Shaders - } // namespace Graphics + namespace Graphics + { + namespace Shaders + { + + // + // default_texture + // base_shader + // SHADER_FORMAT_SIZE + // formatShader + // + #include "built-in/default.shader.h" + + // + // https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value + // The default value of a sampler variable is 0. From the GLSL 3.30 spec, + // section "4.3.5 Uniforms": + // + // The link time initial value is either the value of the variable's + // initializer, if present, or 0 if no initializer is present.Sampler + // types cannot have initializers. + // + // Since a value of 0 means that it's sampling from texture unit 0, it will + // work without ever setting the value as long as you bind your textures to + // unit 0. This is well defined behavior. + // + // Since texture unit 0 is also the default until you call glActiveTexture() + // with a value other than GL_TEXTURE0, it's very common to always use unit + // 0 as long as shaders do not need more than one texture.Which means that + // often times, setting the sampler uniforms is redundant for simple + // applications. + // + // I would still prefer to always set the values.If nothing else, it makes + // it clear to anybody reading your code that you really mean to sample from + // texture unit 0, and did not just forget to set the value. + // + const int MAIN_TEXTURE_UNIT = 0; + + static GLint textureUnit = 0; + + GLint Shader::mAttributeIndex = 0; + + Shader::Shader(const string& program) + { + if (!compile(program)) + { + jin_log_error("Compile jsl shader failed."); + throw Exception("Compile jsl shader failed"); + } + } + + Shader::~Shader() + { + if (gl.getShader() == this) + gl.unuseShader(); + // Delete shader program. + glDeleteShader(mPID); + } + + Shader& Shader::begin() + { + + textureUnit = MAIN_TEXTURE_UNIT; + + // Send uniforms. + sendInt(SHADER_MAIN_TEXTURE, MAIN_TEXTURE_UNIT); + sendVec2(SHADER_TIME, Time::getSecond(), Time::getDeltaTime()); + Canvas* rt = gl.getCanvas(); + if (rt == OpenGL::SCREEN) + { + sendVec2(SHADER_RENDERTARGET_SIZE, Window::get()->getW(), Window::get()->getH()); + } + else if(rt != nullptr) + { + sendVec2(SHADER_RENDERTARGET_SIZE, rt->getWidth(), rt->getHeight()); + } + + gl.activeTextureUnit(MAIN_TEXTURE_UNIT); + + return *this; + } + + void Shader::end() + { + // Reset attribute index. + for (; mAttributeIndex > 0; --mAttributeIndex) + glDisableVertexAttribArray(mAttributeIndex); + } + + bool Shader::compile(const string& program) + { + string vertex_shader, fragment_shader; + // Compile JSL shader source into GLSL shader source. + JSLCompiler* compiler = JSLCompiler::get(); + if (!compiler->compile(program, &vertex_shader, &fragment_shader)) + { + return false; + } + + #define glsl(SHADER_MODE, SHADER, SRC) \ + do{ \ + const GLchar* src = SRC.c_str(); \ + glShaderSource(SHADER, 1, &src, NULL); \ + glCompileShader(SHADER); \ + GLint success; \ + glGetShaderiv(SHADER, GL_COMPILE_STATUS, &success); \ + if (success == GL_FALSE) \ + return false; \ + }while(0) + + // Compile vertex shader. + GLuint vid = glCreateShader(GL_VERTEX_SHADER); + glsl(GL_VERTEX_SHADER, vid, vertex_shader); + // Compile fragment shader. + GLuint fid = glCreateShader(GL_FRAGMENT_SHADER); + glsl(GL_FRAGMENT_SHADER, fid, fragment_shader); + + #undef glsl + // Create OpenGL shader program. + mPID = glCreateProgram(); + glAttachShader(mPID, vid); + glAttachShader(mPID, fid); + glLinkProgram(mPID); + GLint success; + glGetProgramiv(mPID, GL_LINK_STATUS, &success); + if (success == GL_FALSE) + return false; + } + + static inline GLint getMaxTextureUnits() + { + GLint maxTextureUnits = 0; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + return maxTextureUnits; + } + + GLint Shader::claimTextureUnit(/*const std::string& name*/) + { + return textureUnit++; + } + + GLint Shader::getUniformLocation(const char* uniform) + { + map<std::string, GLint>::iterator it = mUniformsLocation.find(uniform); + if (it != mUniformsLocation.end()) + return it->second; + GLint loc = glGetUniformLocation(mPID, uniform); + mUniformsLocation.insert(pair<std::string, GLint>(uniform, loc)); + return loc; + } + + #define check_jsl() \ + if (gl.getShader() != this) \ + return *this + + Shader & Shader::sendInt(const char* name, int value) + { + check_jsl(); + int loc = getUniformLocation(name); + glUniform1i(loc, value); + return *this; + } + + Shader& Shader::sendFloat(const char* variable, float number) + { + check_jsl(); + int loc = getUniformLocation(variable); + glUniform1f(loc, number); + return *this; + } + + // + // https://www.douban.com/note/627332677/ + // struct TextureUnit + // { + // GLuint targetTexture1D; + // GLuint targetTexture2D; + // GLuint targetTexture3D; + // GLuint targetTextureCube; + // ... + // }; + // + // TextureUnit mTextureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] + // GLuint mCurrentTextureUnit = 0; + // + Shader& Shader::sendTexture(const char* variable, const Texture* tex) + { + check_jsl(); + GLint location = getUniformLocation(variable); + if (location == -1) + return *this; + GLint unit = claimTextureUnit(/*variable*/); + if (unit == 0) + { + // TODO: 쳣 + return *this; + } + gl.activeTextureUnit(unit); + gl.bindTexture2D(tex->getGLTexture()); + glUniform1i(location, unit); + gl.activeTextureUnit(MAIN_TEXTURE_UNIT); + return *this; + } + + Shader& Shader::sendCanvas(const char* variable, const Canvas* canvas) + { + check_jsl(); + GLint location = getUniformLocation(variable); + if (location == -1) + return *this; + GLint unit = claimTextureUnit(/*variable*/); + if (unit == 0) + { + // TODO: 쳣 + return *this; + } + glActiveTexture(GL_TEXTURE0 + unit); + gl.bindTexture2D(canvas->getGLTexture()); + glUniform1i(location, unit); + + glActiveTexture(GL_TEXTURE0); + return *this; + } + + Shader& Shader::sendVec2(const char* name, float x, float y) + { + check_jsl(); + int loc = getUniformLocation(name); + glUniform2f(loc, x, y); + return *this; + } + + Shader& Shader::sendVec3(const char* name, float x, float y, float z) + { + check_jsl(); + int loc = getUniformLocation(name); + glUniform3f(loc, x, y, z); + return *this; + } + + Shader& Shader::sendVec4(const char* name, float x, float y, float z, float w) + { + check_jsl(); + int loc = getUniformLocation(name); + glUniform4f(loc, x, y, z, w); + return *this; + } + + Shader& Shader::sendColor(const char* name, const Color* col) + { + check_jsl(); + int loc = getUniformLocation(name); + glUniform4f(loc, + col->r / 255.f, + col->g / 255.f, + col->b / 255.f, + col->a / 255.f + ); + return *this; + } + + Shader& Shader::sendMatrix4(const char* name, const Math::Matrix* mat4) + { + int loc = getUniformLocation(name); + glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); + return *this; + } + + Shader& Shader::uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) + { + uploadAttribute(SHADER_VERTEX_COORDS, n, type, stride, pointers, normalized); + return *this; + } + + Shader& Shader::uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) + { + uploadAttribute(SHADER_TEXTURE_COORDS, n, type, stride, pointers, normalized); + return *this; + } + + Shader& Shader::uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) + { + uploadAttribute(SHADER_VERTEX_COLOR, n, type, stride, pointers, normalized); + return *this; + } + + Shader& Shader::uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized) + { + GLint loc = glGetAttribLocation(mPID, name); + glEnableVertexAttribArray(mAttributeIndex++); + glVertexAttribPointer(loc, n, type, normalized, stride, pointers); + return *this; + } + + } // namespace Shaders + } // namespace Graphics } // namespace JinEngine #endif // (jin_graphics) && (jin_graphics & jin_graphics_shader)
\ No newline at end of file diff --git a/src/libjin/graphics/shaders/shader.h b/src/libjin/graphics/shaders/shader.h index e8756ac..c0e9086 100644 --- a/src/libjin/graphics/shaders/shader.h +++ b/src/libjin/graphics/shaders/shader.h @@ -17,186 +17,186 @@ namespace JinEngine { - namespace Graphics - { - namespace Shaders - { - - /// - /// Built in shader program. - /// - /// Built in shader program written with custom shading language called JSL (jin shading language). A - /// JSL program is compiled into glsl, so most glsl built in functions and structs are available in - /// JSL. - /// - class Shader : public Object - { - public: - /// - /// Shader constructor. - /// - Shader(const std::string& program); - - /// - /// Destructor of shader. - /// - virtual ~Shader(); - - /// - /// Prepare shader and set default uniforms. - /// - Shader& begin(); - - /// - /// End use shader. - /// - void end(); - - /// - /// Send float value to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param number Value of uniform variable to be sent. - /// - Shader& sendFloat(const char* name, float number); - - /// - /// Send texture to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param texture Texture to be sent. - /// - Shader& sendTexture(const char* name, const Texture* texture); - - /// - /// Send integer value to shader - /// - /// @param name Name of the uniform variable to be assigned. - /// @param value Value to be sent. - /// - Shader& sendInt(const char* name, int value); - - /// - /// Send 2D vector to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param x X value of the vector to be sent. - /// @param y Y value of the vector to be sent. - /// - Shader& sendVec2(const char* name, float x, float y); - - /// - /// Send 3D vector to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param x X value of the vector to be sent. - /// @param y Y value of the vector to be sent. - /// @param z Z value of the vector to be sent. - /// - Shader& sendVec3(const char* name, float x, float y, float z); - - /// - /// Send 4D vector to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param x X value of the vector to be sent. - /// @param y Y value of the vector to be sent. - /// @param z Z value of the vector to be sent. - /// @param w W value of the vector to be sent. - /// - Shader& sendVec4(const char* name, float x, float y, float z, float w); - - /// - /// Send canvas to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param canvas Canvas to be sent. - /// - Shader& sendCanvas(const char* name, const Canvas* canvas); - - /// - /// Send color to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param color Color to be sent. - /// - Shader& sendColor(const char* name, const Color* color); - - /// - /// Send 4 by 4 matrix to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param mat4 Matrix to be sent. - /// - Shader& sendMatrix4(const char* name, const Math::Matrix* mat4); - - /// - /// Set vertices value. - /// - /// @param n Number of vertices. - /// @param type Data type of each component in the array. - /// @param stride Byte offset between consecutive generic vertex attributes. - /// @param pointers Pointer to the first component of the first generic vertex attribute in the array. - /// - Shader& uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); - - /// - /// Set texture UV coordinates. - /// - /// @param n Number of vertices. - /// @param type Data type of each component in the array. - /// @param stride Byte offset between consecutive generic vertex attributes. - /// @param pointers Pointer to the first component of the first generic vertex attribute in the array. - /// - Shader& uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); - - /// - /// Upload vertex color array. - /// - Shader& uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); - - /// - /// Set attribute. - /// - Shader& uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); - - /// - /// Program ID. - /// - inline GLuint getGLProgramID() { return mPID; }; - - protected: - /// - /// Get texture unit of the uniform texture. If not, assign one. - /// - /// @param name Name of the texture uniform variable. - /// @return Texture unit which texture variable be assigned. - /// - GLint claimTextureUnit(/*const std::string& name*/); - - GLint getUniformLocation(const char* uniforms); - - /// - /// Compile JSL program into GLSL source. - /// - /// @param program JSL source code. - /// @return Return true if compile successed, otherwise return false. - /// - bool compile(const std::string& program); - - //static GLint mTextureUnit; - static GLint mAttributeIndex; - - GLuint mPID; - //GLint mCurrentTextureUnit; - //std::map<std::string, GLint> mTextureUnits; - - std::map<std::string, GLint> mUniformsLocation; - - }; - - } // namespace Shaders - } // namespace Graphics + namespace Graphics + { + namespace Shaders + { + + /// + /// Built in shader program. + /// + /// Built in shader program written with custom shading language called JSL (jin shading language). A + /// JSL program is compiled into glsl, so most glsl built in functions and structs are available in + /// JSL. + /// + class Shader : public Object + { + public: + /// + /// Shader constructor. + /// + Shader(const std::string& program); + + /// + /// Destructor of shader. + /// + virtual ~Shader(); + + /// + /// Prepare shader and set default uniforms. + /// + Shader& begin(); + + /// + /// End use shader. + /// + void end(); + + /// + /// Send float value to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param number Value of uniform variable to be sent. + /// + Shader& sendFloat(const char* name, float number); + + /// + /// Send texture to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param texture Texture to be sent. + /// + Shader& sendTexture(const char* name, const Texture* texture); + + /// + /// Send integer value to shader + /// + /// @param name Name of the uniform variable to be assigned. + /// @param value Value to be sent. + /// + Shader& sendInt(const char* name, int value); + + /// + /// Send 2D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// + Shader& sendVec2(const char* name, float x, float y); + + /// + /// Send 3D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// @param z Z value of the vector to be sent. + /// + Shader& sendVec3(const char* name, float x, float y, float z); + + /// + /// Send 4D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// @param z Z value of the vector to be sent. + /// @param w W value of the vector to be sent. + /// + Shader& sendVec4(const char* name, float x, float y, float z, float w); + + /// + /// Send canvas to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param canvas Canvas to be sent. + /// + Shader& sendCanvas(const char* name, const Canvas* canvas); + + /// + /// Send color to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param color Color to be sent. + /// + Shader& sendColor(const char* name, const Color* color); + + /// + /// Send 4 by 4 matrix to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param mat4 Matrix to be sent. + /// + Shader& sendMatrix4(const char* name, const Math::Matrix* mat4); + + /// + /// Set vertices value. + /// + /// @param n Number of vertices. + /// @param type Data type of each component in the array. + /// @param stride Byte offset between consecutive generic vertex attributes. + /// @param pointers Pointer to the first component of the first generic vertex attribute in the array. + /// + Shader& uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); + + /// + /// Set texture UV coordinates. + /// + /// @param n Number of vertices. + /// @param type Data type of each component in the array. + /// @param stride Byte offset between consecutive generic vertex attributes. + /// @param pointers Pointer to the first component of the first generic vertex attribute in the array. + /// + Shader& uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); + + /// + /// Upload vertex color array. + /// + Shader& uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); + + /// + /// Set attribute. + /// + Shader& uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE); + + /// + /// Program ID. + /// + inline GLuint getGLProgramID() { return mPID; }; + + protected: + /// + /// Get texture unit of the uniform texture. If not, assign one. + /// + /// @param name Name of the texture uniform variable. + /// @return Texture unit which texture variable be assigned. + /// + GLint claimTextureUnit(/*const std::string& name*/); + + GLint getUniformLocation(const char* uniforms); + + /// + /// Compile JSL program into GLSL source. + /// + /// @param program JSL source code. + /// @return Return true if compile successed, otherwise return false. + /// + bool compile(const std::string& program); + + //static GLint mTextureUnit; + static GLint mAttributeIndex; + + GLuint mPID; + //GLint mCurrentTextureUnit; + //std::map<std::string, GLint> mTextureUnits; + + std::map<std::string, GLint> mUniformsLocation; + + }; + + } // namespace Shaders + } // namespace Graphics } // namespace JinEngine #endif // (jin_graphics) && (jin_graphics & jin_graphics_shader) diff --git a/src/libjin/graphics/shapes.cpp b/src/libjin/graphics/shapes.cpp index 23fc888..228f4c8 100644 --- a/src/libjin/graphics/shapes.cpp +++ b/src/libjin/graphics/shapes.cpp @@ -13,136 +13,136 @@ using namespace JinEngine::Graphics::Shaders; namespace JinEngine { - namespace Graphics - { - - using namespace Math; - - void point(int x, int y) - { - float verts[] = { x + 0.5f , y + 0.5f }; - - Matrix modelMatrix = gl.getModelViewMatrix(); - - Shader* shader = gl.getShader(); - shader->begin() - .uploadVertices(2, GL_FLOAT, 0, verts) - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); - - gl.drawArrays(GL_POINTS, 0, 1); - - shader->end(); - } - - void points(int n, GLshort* p) - { - Matrix modelMatrix = gl.getModelViewMatrix(); - - Shader* shader = gl.getShader(); - shader->begin() - .uploadVertices(2, GL_SHORT, 0, p) - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); - - gl.drawArrays(GL_POINTS, 0, n); - - shader->end(); - } - - void line(int x1, int y1, int x2, int y2) - { - float verts[] = { - x1 + 0.5f, y1 + 0.5f, - x2 + 0.5f, y2 + 0.5f - }; - - Matrix modelMatrix = gl.getModelViewMatrix(); - - Shader* shader = gl.getShader(); - shader->begin() - .uploadVertices(2, GL_FLOAT, 0, verts) - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); - - gl.drawArrays(GL_LINES, 0, 2); - - shader->end(); - } - - void circle(RenderMode mode, int x, int y, int r) - { - r = r < 0 ? 0 : r; - - int points = 40; - float two_pi = static_cast<float>(PI * 2); - if (points <= 0) points = 1; - float angle_shift = (two_pi / points); - float phi = .0f; - - float *coords = new float[2 * (points + 1)]; - for (int i = 0; i < points; ++i, phi += angle_shift) - { - coords[2 * i] = x + r * cos(phi); - coords[2 * i + 1] = y + r * sin(phi); - } - - coords[2 * points] = coords[0]; - coords[2 * points + 1] = coords[1]; - - polygon(mode, coords, points); - - delete[] coords; - } - - void rect(RenderMode mode, int x, int y, int w, int h) - { - float coords[] = { x + 0.5f, y + 0.5f, x + w + 0.5f, y + 0.5f, x + w + 0.5f, y + h + 0.5f, x + 0.5f, y + h + 0.5f }; - polygon(mode, coords, 4); - } - - void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3) - { - float coords[] = { x1 + 0.5f, y1 + 0.5f, x2 + 0.5f, y2 + 0.5f, x3 + 0.5f, y3 + 0.5f }; - polygon(mode, coords, 3); - } - - void polygon_line(float* p, int count) - { - Shader* shader = gl.getShader(); - Matrix modelMatrix = gl.getModelViewMatrix(); - shader->begin() - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) - .uploadVertices(2, GL_FLOAT, 0, p); - - gl.drawArrays(GL_LINE_LOOP, 0, count); - - shader->end(); - } - - void polygon(RenderMode mode, float* p, int count) - { - if (mode == LINE) - { - polygon_line(p, count); - } - else if (mode == FILL) - { - Shader* shader = gl.getShader(); - Matrix modelMatrix = gl.getModelViewMatrix(); - shader->begin() - .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) - .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) - .uploadVertices(2, GL_FLOAT, 0, p); - - gl.drawArrays(GL_POLYGON, 0, count); - - shader->end(); - } - } - - } // namespace Graphics + namespace Graphics + { + + using namespace Math; + + void point(int x, int y) + { + float verts[] = { x + 0.5f , y + 0.5f }; + + Matrix modelMatrix = gl.getModelViewMatrix(); + + Shader* shader = gl.getShader(); + shader->begin() + .uploadVertices(2, GL_FLOAT, 0, verts) + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); + + gl.drawArrays(GL_POINTS, 0, 1); + + shader->end(); + } + + void points(int n, GLshort* p) + { + Matrix modelMatrix = gl.getModelViewMatrix(); + + Shader* shader = gl.getShader(); + shader->begin() + .uploadVertices(2, GL_SHORT, 0, p) + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); + + gl.drawArrays(GL_POINTS, 0, n); + + shader->end(); + } + + void line(int x1, int y1, int x2, int y2) + { + float verts[] = { + x1 + 0.5f, y1 + 0.5f, + x2 + 0.5f, y2 + 0.5f + }; + + Matrix modelMatrix = gl.getModelViewMatrix(); + + Shader* shader = gl.getShader(); + shader->begin() + .uploadVertices(2, GL_FLOAT, 0, verts) + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); + + gl.drawArrays(GL_LINES, 0, 2); + + shader->end(); + } + + void circle(RenderMode mode, int x, int y, int r) + { + r = r < 0 ? 0 : r; + + int points = 40; + float two_pi = static_cast<float>(PI * 2); + if (points <= 0) points = 1; + float angle_shift = (two_pi / points); + float phi = .0f; + + float *coords = new float[2 * (points + 1)]; + for (int i = 0; i < points; ++i, phi += angle_shift) + { + coords[2 * i] = x + r * cos(phi); + coords[2 * i + 1] = y + r * sin(phi); + } + + coords[2 * points] = coords[0]; + coords[2 * points + 1] = coords[1]; + + polygon(mode, coords, points); + + delete[] coords; + } + + void rect(RenderMode mode, int x, int y, int w, int h) + { + float coords[] = { x + 0.5f, y + 0.5f, x + w + 0.5f, y + 0.5f, x + w + 0.5f, y + h + 0.5f, x + 0.5f, y + h + 0.5f }; + polygon(mode, coords, 4); + } + + void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3) + { + float coords[] = { x1 + 0.5f, y1 + 0.5f, x2 + 0.5f, y2 + 0.5f, x3 + 0.5f, y3 + 0.5f }; + polygon(mode, coords, 3); + } + + void polygon_line(float* p, int count) + { + Shader* shader = gl.getShader(); + Matrix modelMatrix = gl.getModelViewMatrix(); + shader->begin() + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) + .uploadVertices(2, GL_FLOAT, 0, p); + + gl.drawArrays(GL_LINE_LOOP, 0, count); + + shader->end(); + } + + void polygon(RenderMode mode, float* p, int count) + { + if (mode == LINE) + { + polygon_line(p, count); + } + else if (mode == FILL) + { + Shader* shader = gl.getShader(); + Matrix modelMatrix = gl.getModelViewMatrix(); + shader->begin() + .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix) + .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()) + .uploadVertices(2, GL_FLOAT, 0, p); + + gl.drawArrays(GL_POLYGON, 0, count); + + shader->end(); + } + } + + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/graphics/shapes.h b/src/libjin/graphics/shapes.h index 6c25eeb..99979d8 100644 --- a/src/libjin/graphics/shapes.h +++ b/src/libjin/graphics/shapes.h @@ -9,24 +9,24 @@ namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - enum RenderMode { - NONE = 0, - FILL , - LINE - }; + enum RenderMode { + NONE = 0, + FILL , + LINE + }; - extern void line(int x1, int y1, int x2, int y2); - extern void rect(RenderMode mode, int x, int y, int w, int h); - extern void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3); - extern void circle(RenderMode mode, int x, int y, int r); - extern void point(int x, int y); - extern void points(int n, GLshort* p, GLubyte* c); - extern void polygon(RenderMode mode, float* p, int count); + extern void line(int x1, int y1, int x2, int y2); + extern void rect(RenderMode mode, int x, int y, int w, int h); + extern void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3); + extern void circle(RenderMode mode, int x, int y, int r); + extern void point(int x, int y); + extern void points(int n, GLshort* p, GLubyte* c); + extern void polygon(RenderMode mode, float* p, int count); - } // namespace Graphics + } // namespace Graphics } // namespace JinEngine #endif // jin_graphics diff --git a/src/libjin/graphics/sprite.cpp b/src/libjin/graphics/sprite.cpp index d74c1ef..a09a315 100644 --- a/src/libjin/graphics/sprite.cpp +++ b/src/libjin/graphics/sprite.cpp @@ -6,90 +6,90 @@ using namespace JinEngine::Graphics; namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin) - : mGraphic(graphic) - , mQuad(quad) - { - setOrigin(origin); - } + Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin) + : mGraphic(graphic) + , mQuad(quad) + { + setOrigin(origin); + } - Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy) - : mGraphic(graphic) - , mQuad(quad) - , mOrigin(ox, oy) - { - } + Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy) + : mGraphic(graphic) + , mQuad(quad) + , mOrigin(ox, oy) + { + } - Sprite::Sprite(const Graphic* graphic, Origin origin) - : mGraphic(graphic) - , mQuad(0, 0, graphic->getWidth(), graphic->getHeight()) - { - setOrigin(origin); - } + Sprite::Sprite(const Graphic* graphic, Origin origin) + : mGraphic(graphic) + , mQuad(0, 0, graphic->getWidth(), graphic->getHeight()) + { + setOrigin(origin); + } - Sprite::Sprite(const Graphic* graphic, float ox, float oy) - : mGraphic(graphic) - , mQuad(0, 0, graphic->getWidth(), graphic->getHeight()) - , mOrigin(ox, oy) - { - } + Sprite::Sprite(const Graphic* graphic, float ox, float oy) + : mGraphic(graphic) + , mQuad(0, 0, graphic->getWidth(), graphic->getHeight()) + , mOrigin(ox, oy) + { + } - Sprite::~Sprite() - { - } + Sprite::~Sprite() + { + } - Math::Vector2<int> Sprite::getSize() - { - return Math::Vector2<int>(mQuad.w, mQuad.h); - } + Math::Vector2<int> Sprite::getSize() + { + return Math::Vector2<int>(mQuad.w, mQuad.h); + } - void Sprite::render(float x, float y, float sx, float sy, float r) const - { - if (mGraphic != nullptr) - mGraphic->render(mQuad, x, y, sx, sy, r, mOrigin.x(), mOrigin.y()); - } + void Sprite::render(float x, float y, float sx, float sy, float r) const + { + if (mGraphic != nullptr) + mGraphic->render(mQuad, x, y, sx, sy, r, mOrigin.x(), mOrigin.y()); + } - void Sprite::setOrigin(Origin origin) - { - int l = 0, r = 0, t = 0, b = 0; - Vector2<int> size = getSize(); - r = size.w(); - b = size.h(); - Vector2<float>* org = const_cast<Vector2<float>*>(&mOrigin); - switch (origin) - { - case Origin::TOPLEFT: - org->set(l, t); - break; - case Origin::TOPCENTER: - org->set(r / 2.f, t); - break; - case Origin::TOPRIGHT: - org->set(r, t); - break; - case Origin::MIDDLELEFT: - org->set(l, b / 2.f); - break; - case Origin::MIDDLECENTER: - org->set(r / 2.f, b / 2.f); - break; - case Origin::MIDDLERIGHT: - org->set(r, b / 2.f); - break; - case Origin::BOTTOMLEFT: - org->set(l, b); - break; - case Origin::BOTTOMCENTER: - org->set(r / 2.f, b); - break; - case Origin::BOTTOMRIGHT: - org->set(r, b); - break; - } - } + void Sprite::setOrigin(Origin origin) + { + int l = 0, r = 0, t = 0, b = 0; + Vector2<int> size = getSize(); + r = size.w(); + b = size.h(); + Vector2<float>* org = const_cast<Vector2<float>*>(&mOrigin); + switch (origin) + { + case Origin::TOPLEFT: + org->set(l, t); + break; + case Origin::TOPCENTER: + org->set(r / 2.f, t); + break; + case Origin::TOPRIGHT: + org->set(r, t); + break; + case Origin::MIDDLELEFT: + org->set(l, b / 2.f); + break; + case Origin::MIDDLECENTER: + org->set(r / 2.f, b / 2.f); + break; + case Origin::MIDDLERIGHT: + org->set(r, b / 2.f); + break; + case Origin::BOTTOMLEFT: + org->set(l, b); + break; + case Origin::BOTTOMCENTER: + org->set(r / 2.f, b); + break; + case Origin::BOTTOMRIGHT: + org->set(r, b); + break; + } + } - } // namespace Graphics + } // namespace Graphics } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/graphics/sprite.h b/src/libjin/graphics/sprite.h index 2acebe0..a143c17 100644 --- a/src/libjin/graphics/sprite.h +++ b/src/libjin/graphics/sprite.h @@ -10,46 +10,46 @@ namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - /// - /// A sprite is unit of rendering. Animation is based on sprite, but not texture or other graphic stuff. - /// - class Sprite : public Object, public Renderable - { - public: + /// + /// A sprite is unit of rendering. Animation is based on sprite, but not texture or other graphic stuff. + /// + class Sprite : public Object, public Renderable + { + public: - Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin); + Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin); - Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy); + Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy); - Sprite(const Graphic* graphic, Origin origin); + Sprite(const Graphic* graphic, Origin origin); - Sprite(const Graphic* graphic, float ox, float oy); + Sprite(const Graphic* graphic, float ox, float oy); - virtual ~Sprite(); + virtual ~Sprite(); - Math::Vector2<int> getSize(); + Math::Vector2<int> getSize(); - void render(float x, float y, float sx, float sy, float r) const override; + void render(float x, float y, float sx, float sy, float r) const override; - private: + private: - void setOrigin(Origin origin); + void setOrigin(Origin origin); - const Math::Vector2<float> mOrigin; + const Math::Vector2<float> mOrigin; - /// - /// Quad of graphic. - /// - const Math::Quad mQuad; + /// + /// Quad of graphic. + /// + const Math::Quad mQuad; - const Graphic* mGraphic; + const Graphic* mGraphic; - }; + }; - } // namespace Graphics + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/sprite_batch.cpp b/src/libjin/graphics/sprite_batch.cpp index 82e480f..7cab9be 100644 --- a/src/libjin/graphics/sprite_batch.cpp +++ b/src/libjin/graphics/sprite_batch.cpp @@ -2,10 +2,10 @@ namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/sprite_batch.h b/src/libjin/graphics/sprite_batch.h index 0aad172..a224ded 100644 --- a/src/libjin/graphics/sprite_batch.h +++ b/src/libjin/graphics/sprite_batch.h @@ -8,22 +8,22 @@ namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - class SpriteBatch : public Object, public Renderable - { - public: + class SpriteBatch : public Object, public Renderable + { + public: - private: - static void createDefaultShader(); + private: + static void createDefaultShader(); - //Shaders::Shader + //Shaders::Shader - }; + }; - } // namespace Graphics + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/sprite_sheet.cpp b/src/libjin/graphics/sprite_sheet.cpp index 24ec4fd..36fde61 100644 --- a/src/libjin/graphics/sprite_sheet.cpp +++ b/src/libjin/graphics/sprite_sheet.cpp @@ -10,71 +10,71 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - SpriteSheet::SpriteSheet(const Graphic* graphic) - : mGraphic(graphic) - { - } + SpriteSheet::SpriteSheet(const Graphic* graphic) + : mGraphic(graphic) + { + } - Sprite* SpriteSheet::createSprite(const Math::Quad& quad, Origin origin) - { - Sprite* spr = new Sprite(mGraphic, quad, origin); - return spr; - } + Sprite* SpriteSheet::createSprite(const Math::Quad& quad, Origin origin) + { + Sprite* spr = new Sprite(mGraphic, quad, origin); + return spr; + } - Sprite* SpriteSheet::createSprite(const Math::Quad& quad, float ox, float oy) - { - Sprite* spr = new Sprite(mGraphic, quad, ox, oy); - return spr; - } + Sprite* SpriteSheet::createSprite(const Math::Quad& quad, float ox, float oy) + { + Sprite* spr = new Sprite(mGraphic, quad, ox, oy); + return spr; + } - std::vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin, uint offx, uint offy) - { - vector<Sprite*> sprites; - int i = 0; - for (int r = 0; r < row; ++r) - { - for (int c = 0; c < colum; ++c) - { - Quad quad; - quad.x = (r * colum + c) * w + offx; - quad.y = r * h + offy; - quad.w = w; - quad.h = h; - Sprite* spr = new Sprite(mGraphic, quad, origin); - sprites.push_back(spr); - if ((++i) == count) - goto done; - } - } - done: - return sprites; - } + std::vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin, uint offx, uint offy) + { + vector<Sprite*> sprites; + int i = 0; + for (int r = 0; r < row; ++r) + { + for (int c = 0; c < colum; ++c) + { + Quad quad; + quad.x = (r * colum + c) * w + offx; + quad.y = r * h + offy; + quad.w = w; + quad.h = h; + Sprite* spr = new Sprite(mGraphic, quad, origin); + sprites.push_back(spr); + if ((++i) == count) + goto done; + } + } + done: + return sprites; + } - vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, float ox, float oy, uint offx, uint offy) - { - vector<Sprite*> sprites; - int i = 0; - for (int r = 0; r < row; ++r) - { - for (int c = 0; c < colum; ++c) - { - Quad quad; - quad.x = (r * colum + c) * w + offx; - quad.y = r * h + offy; - quad.w = w; - quad.h = h; - Sprite* spr = new Sprite(mGraphic, quad, ox, oy); - sprites.push_back(spr); - if ((++i) == count) - goto done; - } - } - done: - return sprites; - } + vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, float ox, float oy, uint offx, uint offy) + { + vector<Sprite*> sprites; + int i = 0; + for (int r = 0; r < row; ++r) + { + for (int c = 0; c < colum; ++c) + { + Quad quad; + quad.x = (r * colum + c) * w + offx; + quad.y = r * h + offy; + quad.w = w; + quad.h = h; + Sprite* spr = new Sprite(mGraphic, quad, ox, oy); + sprites.push_back(spr); + if ((++i) == count) + goto done; + } + } + done: + return sprites; + } - } + } }
\ No newline at end of file diff --git a/src/libjin/graphics/sprite_sheet.h b/src/libjin/graphics/sprite_sheet.h index eb50b2c..1ca72a5 100644 --- a/src/libjin/graphics/sprite_sheet.h +++ b/src/libjin/graphics/sprite_sheet.h @@ -9,37 +9,37 @@ namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - class SpriteSheet : public Object - { - public: - SpriteSheet(const Graphic* graphic); + class SpriteSheet : public Object + { + public: + SpriteSheet(const Graphic* graphic); - /// - /// Create a new sprite in sheet. - /// - Sprite* createSprite(const Math::Quad& quad, Origin origin); + /// + /// Create a new sprite in sheet. + /// + Sprite* createSprite(const Math::Quad& quad, Origin origin); - /// - /// Create a new sprite in sheet. - /// - Sprite* createSprite(const Math::Quad& quad, float ox, float oy); + /// + /// Create a new sprite in sheet. + /// + Sprite* createSprite(const Math::Quad& quad, float ox, float oy); - /// - /// - /// - std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin = Origin::TOPLEFT, uint offx = 0, uint offy = 0); + /// + /// + /// + std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin = Origin::TOPLEFT, uint offx = 0, uint offy = 0); - std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, float ox = 0, float oy = 0, uint offx = 0, uint offy = 0); + std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, float ox = 0, float oy = 0, uint offx = 0, uint offy = 0); - private: - const Graphic* const mGraphic; + private: + const Graphic* const mGraphic; - }; + }; - } // namespace Graphics + } // namespace Graphics } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/graphics/texture.cpp b/src/libjin/graphics/texture.cpp index ba8a33a..45432d1 100644 --- a/src/libjin/graphics/texture.cpp +++ b/src/libjin/graphics/texture.cpp @@ -12,34 +12,34 @@ using namespace JinEngine::Math; namespace JinEngine { - namespace Graphics - { - - Texture::Texture() - : Graphic() - { - ++gl.getStats().textures; - } - - Texture::Texture(const char* path) - { - Bitmap* bitmap = new Bitmap(path); - new (this) Texture(bitmap); - delete bitmap; - } - - Texture::Texture(const Bitmap* bitmap) - : Graphic(bitmap) - { - ++gl.getStats().textures; - } - - Texture::~Texture() - { - --gl.getStats().textures; - } - - } // namespace Graphics + namespace Graphics + { + + Texture::Texture() + : Graphic() + { + ++gl.getStats().textures; + } + + Texture::Texture(const char* path) + { + Bitmap* bitmap = new Bitmap(path); + new (this) Texture(bitmap); + delete bitmap; + } + + Texture::Texture(const Bitmap* bitmap) + : Graphic(bitmap) + { + ++gl.getStats().textures; + } + + Texture::~Texture() + { + --gl.getStats().textures; + } + + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/graphics/texture.h b/src/libjin/graphics/texture.h index 7bba557..6d5e5be 100644 --- a/src/libjin/graphics/texture.h +++ b/src/libjin/graphics/texture.h @@ -9,38 +9,38 @@ namespace JinEngine { - namespace Graphics - { - - /// - /// - /// - class Texture : public Graphic - { - public: - /// - /// - /// - Texture(); - - /// - /// - /// - Texture(const char* path); - - /// - /// - /// - Texture(const Bitmap* bitmap); - - /// - /// - /// - ~Texture(); - - }; - - } // namespace Graphics + namespace Graphics + { + + /// + /// + /// + class Texture : public Graphic + { + public: + /// + /// + /// + Texture(); + + /// + /// + /// + Texture(const char* path); + + /// + /// + /// + Texture(const Bitmap* bitmap); + + /// + /// + /// + ~Texture(); + + }; + + } // namespace Graphics } // namespace JinEngine #endif // jin_graphics diff --git a/src/libjin/graphics/vertex.h b/src/libjin/graphics/vertex.h index 192117e..2fac1cc 100644 --- a/src/libjin/graphics/vertex.h +++ b/src/libjin/graphics/vertex.h @@ -7,17 +7,17 @@ namespace JinEngine { - namespace Graphics - { + namespace Graphics + { - struct Vertex - { - Math::Vector2<float> xy; - Math::Vector2<float> uv; - Color color; - }; + struct Vertex + { + Math::Vector2<float> xy; + Math::Vector2<float> uv; + Color color; + }; - } + } } #endif
\ No newline at end of file diff --git a/src/libjin/graphics/window.cpp b/src/libjin/graphics/window.cpp index 479961b..0f43a28 100644 --- a/src/libjin/graphics/window.cpp +++ b/src/libjin/graphics/window.cpp @@ -17,106 +17,106 @@ using namespace JinEngine::Graphics::Shaders; namespace JinEngine { - namespace Graphics - { - - bool Window::startSystem(const SettingBase* s) - { - jin_log_info("Initialize window system."); - - if (SDL_Init(SDL_INIT_VIDEO) < 0) - return false; - - const Setting* setting = (Setting*)s; - mSize.w() = setting->width; - mSize.h() = setting->height; - mFps = setting->fps; - bool vsync = setting->vsync; - const char* title = setting->title; - const char* icon = setting->icon; - - if (mWnd) - { - SDL_DestroyWindow(mWnd); - SDL_FlushEvent(SDL_WINDOWEVENT); - } - - SDL_GLContext ctx = NULL; - - if (ctx) - { - SDL_GL_DeleteContext(ctx); - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); - - int wx = SDL_WINDOWPOS_UNDEFINED, - wy = SDL_WINDOWPOS_UNDEFINED; - - int flag = SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL; - if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN; - if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE; - - mWnd = SDL_CreateWindow(title, wx, wy, mSize.w(), mSize.h(), flag); - if (mWnd == NULL) - return false; - - // Set window icon. - //try - //{ - // Bitmap* bitmap = new Bitmap(icon); - // SDL_Surface *surface; - // Color* pixels = const_cast<Color*>(bitmap->getPixels()); - // uint w = bitmap->getWidth(), h = bitmap->getHeight(); - // surface = SDL_CreateRGBSurfaceFrom( - // pixels, w, h, 32, w * 4, Color::RMASK, Color::GMASK, Color::BMASK, Color::AMASK); - // SDL_SetWindowIcon(mWnd, surface); - // SDL_FreeSurface(surface); - //} catch (...) {} - - ctx = SDL_GL_CreateContext(mWnd); - if (ctx == NULL) - return false; - - gl.loadGL(); - - SDL_GL_SetSwapInterval(vsync ? 1 : 0); - SDL_GL_MakeCurrent(mWnd, ctx); - - // Default configuration. - gl.init(); - - return true; - } - - void Window::quitSystem() - { - jin_log_info("Quit window system."); - - SDL_DestroyWindow(mWnd); - } - - void Window::present() - { - if (mWnd) - SDL_GL_SwapWindow(mWnd); - gl.resetStats(); - } - - void Window::setTitle(const char* title) - { - SDL_SetWindowTitle(mWnd, title); - }; - - } // namespace Graphics + namespace Graphics + { + + bool Window::startSystem(const SettingBase* s) + { + jin_log_info("Initialize window system."); + + if (SDL_Init(SDL_INIT_VIDEO) < 0) + return false; + + const Setting* setting = (Setting*)s; + mSize.w() = setting->width; + mSize.h() = setting->height; + mFps = setting->fps; + bool vsync = setting->vsync; + const char* title = setting->title; + const char* icon = setting->icon; + + if (mWnd) + { + SDL_DestroyWindow(mWnd); + SDL_FlushEvent(SDL_WINDOWEVENT); + } + + SDL_GLContext ctx = NULL; + + if (ctx) + { + SDL_GL_DeleteContext(ctx); + } + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); + + int wx = SDL_WINDOWPOS_UNDEFINED, + wy = SDL_WINDOWPOS_UNDEFINED; + + int flag = SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL; + if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN; + if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE; + + mWnd = SDL_CreateWindow(title, wx, wy, mSize.w(), mSize.h(), flag); + if (mWnd == NULL) + return false; + + // Set window icon. + //try + //{ + // Bitmap* bitmap = new Bitmap(icon); + // SDL_Surface *surface; + // Color* pixels = const_cast<Color*>(bitmap->getPixels()); + // uint w = bitmap->getWidth(), h = bitmap->getHeight(); + // surface = SDL_CreateRGBSurfaceFrom( + // pixels, w, h, 32, w * 4, Color::RMASK, Color::GMASK, Color::BMASK, Color::AMASK); + // SDL_SetWindowIcon(mWnd, surface); + // SDL_FreeSurface(surface); + //} catch (...) {} + + ctx = SDL_GL_CreateContext(mWnd); + if (ctx == NULL) + return false; + + gl.loadGL(); + + SDL_GL_SetSwapInterval(vsync ? 1 : 0); + SDL_GL_MakeCurrent(mWnd, ctx); + + // Default configuration. + gl.init(); + + return true; + } + + void Window::quitSystem() + { + jin_log_info("Quit window system."); + + SDL_DestroyWindow(mWnd); + } + + void Window::present() + { + if (mWnd) + SDL_GL_SwapWindow(mWnd); + gl.resetStats(); + } + + void Window::setTitle(const char* title) + { + SDL_SetWindowTitle(mWnd, title); + }; + + } // namespace Graphics } // namespace JinEngine #endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/graphics/window.h b/src/libjin/graphics/window.h index c279e9b..605cebe 100644 --- a/src/libjin/graphics/window.h +++ b/src/libjin/graphics/window.h @@ -11,94 +11,94 @@ namespace JinEngine { - namespace Graphics - { - /// - /// - /// - class Window - : public Subsystem<Window> - { - public: - /// - /// - /// - struct Setting : SettingBase - { - public: - const char* title; ///< window title - const char* icon; ///< window icon - bool fullscreen; ///< full screen - int width, height; ///< window size - bool vsync; ///< vsync - int fps; ///< frame per second - bool resizable; ///< resizable - }; - - /// - /// - /// - Window() {}; - - /// - /// - /// - virtual ~Window() {}; - - /// - /// - /// - void setTitle(const char* title); - - /// - /// - /// - inline int getW(){ return mSize.w(); } - - /// - /// - /// - inline int getH(){ return mSize.h(); } - - /// - /// - /// - inline int getFPS(){ return mFps; } - - /// - /// - /// - void present(); - - /// - /// - /// - inline void hide() { SDL_HideWindow(mWnd); }; - - /// - /// - /// - void show() { SDL_ShowWindow(mWnd); }; - - private: - - /// - /// - /// - bool startSystem(const SettingBase* setting) override; - - /// - /// - /// - void quitSystem() override; - - SDL_Window* mWnd; - JinEngine::Math::Vector2<unsigned int> mSize; - int mFps; - - }; - - } // namespace Graphics + namespace Graphics + { + /// + /// + /// + class Window + : public Subsystem<Window> + { + public: + /// + /// + /// + struct Setting : SettingBase + { + public: + const char* title; ///< window title + const char* icon; ///< window icon + bool fullscreen; ///< full screen + int width, height; ///< window size + bool vsync; ///< vsync + int fps; ///< frame per second + bool resizable; ///< resizable + }; + + /// + /// + /// + Window() {}; + + /// + /// + /// + virtual ~Window() {}; + + /// + /// + /// + void setTitle(const char* title); + + /// + /// + /// + inline int getW(){ return mSize.w(); } + + /// + /// + /// + inline int getH(){ return mSize.h(); } + + /// + /// + /// + inline int getFPS(){ return mFps; } + + /// + /// + /// + void present(); + + /// + /// + /// + inline void hide() { SDL_HideWindow(mWnd); }; + + /// + /// + /// + void show() { SDL_ShowWindow(mWnd); }; + + private: + + /// + /// + /// + bool startSystem(const SettingBase* setting) override; + + /// + /// + /// + void quitSystem() override; + + SDL_Window* mWnd; + JinEngine::Math::Vector2<unsigned int> mSize; + int mFps; + + }; + + } // namespace Graphics } // namespace JinEngine #endif // jin_graphics diff --git a/src/libjin/input/event.h b/src/libjin/input/event.h index f13f1d4..b23974c 100644 --- a/src/libjin/input/event.h +++ b/src/libjin/input/event.h @@ -5,115 +5,115 @@ namespace JinEngine { - namespace Input - { - #if jin_input == jin_input_sdl - #include "SDL.h" - - typedef SDL_Event Event; - typedef SDL_Keycode Key; - typedef SDL_MouseWheelEvent Wheel; + namespace Input + { + #if jin_input == jin_input_sdl + #include "SDL.h" + + typedef SDL_Event Event; + typedef SDL_Keycode Key; + typedef SDL_MouseWheelEvent Wheel; - /// - /// - /// - enum EventType { - QUIT = SDL_QUIT, - /* keyboard events */ - KEY_DOWN = SDL_KEYDOWN, - KEY_UP = SDL_KEYUP, - /* mouse events */ - MOUSE_MOTION = SDL_MOUSEMOTION, - MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, - MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, - MOUSE_WHEEL = SDL_MOUSEWHEEL, - /* joypad events */ - JOYBUTTONDOWN = SDL_JOYBUTTONDOWN, - JOYBUTTONUP = SDL_JOYBUTTONUP, - JOYAXISMOTION = SDL_JOYAXISMOTION, - JOYBALLMOTION = SDL_JOYBALLMOTION, - JOYHATMOTION = SDL_JOYHATMOTION, - JOYDEVICEADDED = SDL_JOYDEVICEADDED, - JOYDEVICEREMOVED = SDL_JOYDEVICEREMOVED, - CONTROLLERBUTTONDOWN = SDL_CONTROLLERBUTTONDOWN, - CONTROLLERBUTTONUP = SDL_CONTROLLERBUTTONUP, - CONTROLLERAXISMOTION = SDL_CONTROLLERAXISMOTION, - /* window evnets */ - WINDOW_EVENT = SDL_WINDOWEVENT, - }; + /// + /// + /// + enum EventType { + QUIT = SDL_QUIT, + /* keyboard events */ + KEY_DOWN = SDL_KEYDOWN, + KEY_UP = SDL_KEYUP, + /* mouse events */ + MOUSE_MOTION = SDL_MOUSEMOTION, + MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, + MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, + MOUSE_WHEEL = SDL_MOUSEWHEEL, + /* joypad events */ + JOYBUTTONDOWN = SDL_JOYBUTTONDOWN, + JOYBUTTONUP = SDL_JOYBUTTONUP, + JOYAXISMOTION = SDL_JOYAXISMOTION, + JOYBALLMOTION = SDL_JOYBALLMOTION, + JOYHATMOTION = SDL_JOYHATMOTION, + JOYDEVICEADDED = SDL_JOYDEVICEADDED, + JOYDEVICEREMOVED = SDL_JOYDEVICEREMOVED, + CONTROLLERBUTTONDOWN = SDL_CONTROLLERBUTTONDOWN, + CONTROLLERBUTTONUP = SDL_CONTROLLERBUTTONUP, + CONTROLLERAXISMOTION = SDL_CONTROLLERAXISMOTION, + /* window evnets */ + WINDOW_EVENT = SDL_WINDOWEVENT, + }; - /// - /// - /// - enum WindowEvent { - WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , - WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , - WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , - WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , - WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , - WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , - WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , - WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , - WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , - WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , - WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , - WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, - WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , - WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , - WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , - WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , - }; + /// + /// + /// + enum WindowEvent { + WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , + WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , + WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , + WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , + WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , + WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , + WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , + WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , + WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , + WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , + WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , + WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, + WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , + WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , + WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , + WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , + }; - /// - /// - /// - inline int pollEvent(Event* e) - { - return SDL_PollEvent(e); - } + /// + /// + /// + inline int pollEvent(Event* e) + { + return SDL_PollEvent(e); + } - /// - /// - /// - inline const char* getKeyName(Key key) - { - return SDL_GetKeyName(key); - } + /// + /// + /// + inline const char* getKeyName(Key key) + { + return SDL_GetKeyName(key); + } - /// - /// - /// - inline const char* getButtonName(int button) - { - switch (button) - { - case 1: return "Left"; - case 2: return "Middle"; - case 3: return "Right"; - case 4: return "WheelUp"; - case 5: return "WheelDown"; - default: return "?"; - } - } + /// + /// + /// + inline const char* getButtonName(int button) + { + switch (button) + { + case 1: return "Left"; + case 2: return "Middle"; + case 3: return "Right"; + case 4: return "WheelUp"; + case 5: return "WheelDown"; + default: return "?"; + } + } - /* - inline const char* getWheelName(Wheel wheel) - { - if (wheel.x() == -1) - return "left"; - else if (wheel.x() == 1) - return "right"; - else if (wheel.y() == -1) - return "near"; - else if (wheel.y() == 1) - return "far"; - else - return "none"; - } - */ + /* + inline const char* getWheelName(Wheel wheel) + { + if (wheel.x() == -1) + return "left"; + else if (wheel.x() == 1) + return "right"; + else if (wheel.y() == -1) + return "near"; + else if (wheel.y() == 1) + return "far"; + else + return "none"; + } + */ - #endif // jin_input == jin_input_sdl - } // namespace Input + #endif // jin_input == jin_input_sdl + } // namespace Input } // namespace JinEngine #endif // defined(jin_input) diff --git a/src/libjin/input/joypad.h b/src/libjin/input/joypad.h index fb5dc38..c753008 100644 --- a/src/libjin/input/joypad.h +++ b/src/libjin/input/joypad.h @@ -5,52 +5,52 @@ namespace JinEngine { - namespace Input - { + namespace Input + { - /// - /// - /// - inline const char* getJoyButtonName(int button) - { - switch (button) - { - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A: return "A"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B : return "B"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X : return "X"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y: return "Y"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: return "Back"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE: return "Guide"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return "Start"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: return "LeftStick"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: return "RightStick"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return "LeftShoulder"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return "RightShoulder"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP: return "DpadUp"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN: return "DpadDown"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT: return "DpadLeft"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return "DpadRight"; break; - default: return NULL; - } - } + /// + /// + /// + inline const char* getJoyButtonName(int button) + { + switch (button) + { + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A: return "A"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B : return "B"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X : return "X"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y: return "Y"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: return "Back"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE: return "Guide"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return "Start"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: return "LeftStick"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: return "RightStick"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return "LeftShoulder"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return "RightShoulder"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP: return "DpadUp"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN: return "DpadDown"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT: return "DpadLeft"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return "DpadRight"; break; + default: return NULL; + } + } - /// - /// - /// - inline const char* getJoyAxisName(int axis) - { - switch (axis) - { - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: return "LeftX"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: return "LeftY"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX: return "RightX"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY: return "RightY"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT: return "TriggerLeft"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return "TriggerRight"; break; - } - } + /// + /// + /// + inline const char* getJoyAxisName(int axis) + { + switch (axis) + { + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: return "LeftX"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: return "LeftY"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX: return "RightX"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY: return "RightY"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT: return "TriggerLeft"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return "TriggerRight"; break; + } + } - } // namespace Input + } // namespace Input } // namespace JinEngine #endif // __JE_JOYPAD_H__ diff --git a/src/libjin/input/keyboard.h b/src/libjin/input/keyboard.h index ffaad66..54e7f2e 100644 --- a/src/libjin/input/keyboard.h +++ b/src/libjin/input/keyboard.h @@ -3,18 +3,18 @@ namespace JinEngine { - namespace Input - { + namespace Input + { - /// - /// - /// - class Keyboard - { + /// + /// + /// + class Keyboard + { - }; + }; - } // namespace Input + } // namespace Input } // namespace JinEngine #endif // __JE_KEYBOARD_H__ diff --git a/src/libjin/input/mouse.cpp b/src/libjin/input/mouse.cpp index 4971137..98e641b 100644 --- a/src/libjin/input/mouse.cpp +++ b/src/libjin/input/mouse.cpp @@ -1,5 +1,5 @@ #include "../core/configuration.h" -#if defined(jin_input) +#if defined(jin_input) #include "SDL.h" @@ -7,22 +7,22 @@ namespace JinEngine { - namespace Input - { + namespace Input + { - void Mouse::getState(int* x, int* y) - { - #ifdef jin_input == jin_input_sdl - SDL_GetMouseState(x, y); - #endif - } + void Mouse::getState(int* x, int* y) + { + #ifdef jin_input == jin_input_sdl + SDL_GetMouseState(x, y); + #endif + } - void Mouse::setVisible(bool visible) - { - SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); - } + void Mouse::setVisible(bool visible) + { + SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); + } - } // namespace Input + } // namespace Input } // namespace JinEngine #endif // defined(jin_input)
\ No newline at end of file diff --git a/src/libjin/input/mouse.h b/src/libjin/input/mouse.h index feb982b..09d79dc 100644 --- a/src/libjin/input/mouse.h +++ b/src/libjin/input/mouse.h @@ -7,38 +7,38 @@ namespace JinEngine { - namespace Input - { - - /// - /// - /// - class Mouse : public Singleton<Mouse> - { - public: - /// - /// - /// - Mouse() {}; - - /// - /// - /// - ~Mouse() {}; - - /// - /// - /// - void getState(int* x, int* y); - - /// - /// - /// - void setVisible(bool visible); - - }; - - } // namespace Input + namespace Input + { + + /// + /// + /// + class Mouse : public Singleton<Mouse> + { + public: + /// + /// + /// + Mouse() {}; + + /// + /// + /// + ~Mouse() {}; + + /// + /// + /// + void getState(int* x, int* y); + + /// + /// + /// + void setVisible(bool visible); + + }; + + } // namespace Input } // namespace JinEngine #endif // defined(jin_input) diff --git a/src/libjin/jin.h b/src/libjin/jin.h index 9040bbc..d7eba66 100644 --- a/src/libjin/jin.h +++ b/src/libjin/jin.h @@ -5,7 +5,7 @@ #include "utils/utils.h" #if jin_audio == jin_audio_sdl - #include "audio/sdl/sdl_audio.h" + #include "audio/sdl/sdl_audio.h" #endif #include "game/application.h" #include "filesystem/asset_database.h" diff --git a/src/libjin/math/bbox.h b/src/libjin/math/bbox.h index ce88080..97b67cb 100644 --- a/src/libjin/math/bbox.h +++ b/src/libjin/math/bbox.h @@ -3,28 +3,28 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - /// - /// - /// - struct BBox - { - BBox() - : l(0), r(0), t(0), b(0) - { - } + /// + /// + /// + struct BBox + { + BBox() + : l(0), r(0), t(0), b(0) + { + } - BBox(float _l, float _r, float _t, float _b) - : l(+l), r(_r), t(_t), b(_b) - { - } + BBox(float _l, float _r, float _t, float _b) + : l(+l), r(_r), t(_t), b(_b) + { + } - float l, r, t, b; - }; + float l, r, t, b; + }; - } // namespace Math + } // namespace Math } // namespace JinEngine #endif // __JE_BBOX_H__
\ No newline at end of file diff --git a/src/libjin/math/bezier_curve.h b/src/libjin/math/bezier_curve.h index 6925baf..a84d856 100644 --- a/src/libjin/math/bezier_curve.h +++ b/src/libjin/math/bezier_curve.h @@ -3,15 +3,15 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - class BezierCurve - { + class BezierCurve + { - }; + }; - } // namespace Math + } // namespace Math } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/math/math.h b/src/libjin/math/math.h index 79ed4c8..5197f6d 100644 --- a/src/libjin/math/math.h +++ b/src/libjin/math/math.h @@ -7,109 +7,109 @@ namespace JinEngine { - namespace Math - { - - #ifdef min - #undef min - #endif // min - #ifdef max - #undef max - #endif // max - - template<typename T> - inline T min(T a, T b) - { - return a < b ? a : b; - } - - template<typename T> - inline T max(T a, T b) - { - return a > b ? a : b; - } - - template<typename T> - inline T clamp(T a, T mi, T ma) - { - return min<T>(max<T>(a, mi), ma); - } - - template<typename T> - inline bool within(T a, T mi, T ma) - { - return a >= mi && a <= ma; - } - - template<typename T> - inline bool without(T a, T mi, T ma) - { - return a < mi || a > ma; - } - - template<typename T> - inline T lowerBound(T a, T lower) - { - return a < lower ? lower : a; - } - - template<typename T> - inline T upperBound(T a, T upper) - { - return a > upper ? upper : a; - } - - inline float lerp(float a, float b, float f) - { - f = clamp<float>(f, 0, 1); - return a + f * (b - a); - } - - template<typename T> - inline T abs(T a) - { - return a > 0 ? a : -a; - } - - template<typename T> - inline T reverse(T a) - { - return -a; - } - - template<typename T> - inline T lerp(T a, T b, float t) - { - return a + t * (b - a); - } - - template<typename T> - inline T slerp(T start, T end, float percent) - { - // Dot product - the cosine of the angle between 2 vectors. - float dot = start * end; - // Clamp it to be in the range of Acos() - // This may be unnecessary, but floating point - // precision can be a fickle mistress. - dot = clamp<float>(dot, -1.0f, 1.0f); - // Acos(dot) returns the angle between start and end, - // And multiplying that by percent returns the angle between - // start and the final result. - float theta = Mathf.Acos(dot)*percent; - Vector3 RelativeVec = end - start * dot; - RelativeVec.Normalize(); - // Orthonormal basis - // The final result. - return ((start*Mathf.Cos(theta)) + (RelativeVec*Mathf.Sin(theta))); - } - - template<typename T> - inline T nlerp(T a, T b, float t) - { - - } - - } // namespace Math + namespace Math + { + + #ifdef min + #undef min + #endif // min + #ifdef max + #undef max + #endif // max + + template<typename T> + inline T min(T a, T b) + { + return a < b ? a : b; + } + + template<typename T> + inline T max(T a, T b) + { + return a > b ? a : b; + } + + template<typename T> + inline T clamp(T a, T mi, T ma) + { + return min<T>(max<T>(a, mi), ma); + } + + template<typename T> + inline bool within(T a, T mi, T ma) + { + return a >= mi && a <= ma; + } + + template<typename T> + inline bool without(T a, T mi, T ma) + { + return a < mi || a > ma; + } + + template<typename T> + inline T lowerBound(T a, T lower) + { + return a < lower ? lower : a; + } + + template<typename T> + inline T upperBound(T a, T upper) + { + return a > upper ? upper : a; + } + + inline float lerp(float a, float b, float f) + { + f = clamp<float>(f, 0, 1); + return a + f * (b - a); + } + + template<typename T> + inline T abs(T a) + { + return a > 0 ? a : -a; + } + + template<typename T> + inline T reverse(T a) + { + return -a; + } + + template<typename T> + inline T lerp(T a, T b, float t) + { + return a + t * (b - a); + } + + template<typename T> + inline T slerp(T start, T end, float percent) + { + // Dot product - the cosine of the angle between 2 vectors. + float dot = start * end; + // Clamp it to be in the range of Acos() + // This may be unnecessary, but floating point + // precision can be a fickle mistress. + dot = clamp<float>(dot, -1.0f, 1.0f); + // Acos(dot) returns the angle between start and end, + // And multiplying that by percent returns the angle between + // start and the final result. + float theta = Mathf.Acos(dot)*percent; + Vector3 RelativeVec = end - start * dot; + RelativeVec.Normalize(); + // Orthonormal basis + // The final result. + return ((start*Mathf.Cos(theta)) + (RelativeVec*Mathf.Sin(theta))); + } + + template<typename T> + inline T nlerp(T a, T b, float t) + { + + } + + } // namespace Math } // namespace JinEngine #endif // __JE_UTILS_MATH_H__
\ No newline at end of file diff --git a/src/libjin/math/matrix.cpp b/src/libjin/math/matrix.cpp index 9d1c77b..52d4f74 100644 --- a/src/libjin/math/matrix.cpp +++ b/src/libjin/math/matrix.cpp @@ -7,189 +7,189 @@ namespace JinEngine { - namespace Math - { - - const Matrix Matrix::Identity; - - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - Matrix::Matrix() - { - setIdentity(); - } - - Matrix::~Matrix() - { - } - - void Matrix::setOrtho(float l, float r, float b, float t, float n, float f) - { - setIdentity(); - float w = r - l; - float h = t - b; - float z = f - n; - e[0] = 2 / w; - e[5] = 2 / h; - e[10] = -2 / z; - e[12] = -(r + l) / w; - e[13] = -(t + b) / h; - e[14] = -(f + n) / z; - e[15] = 1; - } - - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - Matrix Matrix::operator * (const Matrix & m) const - { - Matrix t; - - t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]); - t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]); - t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]); - t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]); - - t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]); - t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]); - t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]); - t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]); - - t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]); - t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]); - t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]); - t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]); - - t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]); - t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]); - t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]); - t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]); - - return t; - } - - void Matrix::operator *= (const Matrix & m) - { - Matrix t = (*this) * m; - memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16); - } - - const float * Matrix::getElements() const - { - return e; - } - - void Matrix::setIdentity() - { - memset(e, 0, sizeof(float) * 16); - e[0] = e[5] = e[10] = e[15] = 1; - } - - void Matrix::setTranslation(float x, float y) - { - setIdentity(); - e[12] = x; - e[13] = y; - } - - void Matrix::setRotation(float rad) - { - setIdentity(); - float c = cos(rad), s = sin(rad); - e[0] = c; e[4] = -s; - e[1] = s; e[5] = c; - } - - void Matrix::setScale(float sx, float sy) - { - setIdentity(); - e[0] = sx; - e[5] = sy; - } - - void Matrix::setShear(float kx, float ky) - { - setIdentity(); - e[1] = ky; - e[4] = kx; - } - - void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy) - { - memset(e, 0, sizeof(float) * 16); // zero out matrix - float c = cos(angle), s = sin(angle); - // matrix multiplication carried out on paper: - // |1 x| |c -s | |sx | |1 -ox| - // | 1 y| |s c | | sy | | 1 -oy| - // | 1 | | 1 | | 1 | | 1 | - // | 1| | 1| | 1| | 1 | - // move rotate scale origin - e[10] = e[15] = 1.0f; - e[0] = c * sx ; // = a - e[1] = s * sx ; // = b - e[4] = - s * sy; // = c - e[5] = c * sy; // = d - e[12] = x - ox * e[0] - oy * e[4]; - e[13] = y - ox * e[1] - oy * e[5]; - } - - void Matrix::translate(float x, float y) - { - Matrix t; - t.setTranslation(x, y); - this->operator *=(t); - } - - void Matrix::rotate(float rad) - { - Matrix t; - t.setRotation(rad); - this->operator *=(t); - } - - void Matrix::scale(float sx, float sy) - { - Matrix t; - t.setScale(sx, sy); - this->operator *=(t); - } - - void Matrix::shear(float kx, float ky) - { - Matrix t; - t.setShear(kx, ky); - this->operator *=(t); - } - - // | x | - // | y | - // | 0 | - // | 1 | - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - void Matrix::transform(Graphics::Vertex* dst, const Graphics::Vertex* src, int size) const - { - for (int i = 0; i<size; ++i) - { - // Store in temp variables in case src = dst - float x = (e[0] * src[i].xy.x()) + (e[4] * src[i].xy.y()) + (0) + (e[12]); - float y = (e[1] * src[i].xy.x()) + (e[5] * src[i].xy.y()) + (0) + (e[13]); - - dst[i].xy.set(x, y); - } - } - - } + namespace Math + { + + const Matrix Matrix::Identity; + + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + Matrix::Matrix() + { + setIdentity(); + } + + Matrix::~Matrix() + { + } + + void Matrix::setOrtho(float l, float r, float b, float t, float n, float f) + { + setIdentity(); + float w = r - l; + float h = t - b; + float z = f - n; + e[0] = 2 / w; + e[5] = 2 / h; + e[10] = -2 / z; + e[12] = -(r + l) / w; + e[13] = -(t + b) / h; + e[14] = -(f + n) / z; + e[15] = 1; + } + + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + Matrix Matrix::operator * (const Matrix & m) const + { + Matrix t; + + t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]); + t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]); + t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]); + t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]); + + t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]); + t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]); + t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]); + t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]); + + t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]); + t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]); + t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]); + t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]); + + t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]); + t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]); + t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]); + t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]); + + return t; + } + + void Matrix::operator *= (const Matrix & m) + { + Matrix t = (*this) * m; + memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16); + } + + const float * Matrix::getElements() const + { + return e; + } + + void Matrix::setIdentity() + { + memset(e, 0, sizeof(float) * 16); + e[0] = e[5] = e[10] = e[15] = 1; + } + + void Matrix::setTranslation(float x, float y) + { + setIdentity(); + e[12] = x; + e[13] = y; + } + + void Matrix::setRotation(float rad) + { + setIdentity(); + float c = cos(rad), s = sin(rad); + e[0] = c; e[4] = -s; + e[1] = s; e[5] = c; + } + + void Matrix::setScale(float sx, float sy) + { + setIdentity(); + e[0] = sx; + e[5] = sy; + } + + void Matrix::setShear(float kx, float ky) + { + setIdentity(); + e[1] = ky; + e[4] = kx; + } + + void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy) + { + memset(e, 0, sizeof(float) * 16); // zero out matrix + float c = cos(angle), s = sin(angle); + // matrix multiplication carried out on paper: + // |1 x| |c -s | |sx | |1 -ox| + // | 1 y| |s c | | sy | | 1 -oy| + // | 1 | | 1 | | 1 | | 1 | + // | 1| | 1| | 1| | 1 | + // move rotate scale origin + e[10] = e[15] = 1.0f; + e[0] = c * sx ; // = a + e[1] = s * sx ; // = b + e[4] = - s * sy; // = c + e[5] = c * sy; // = d + e[12] = x - ox * e[0] - oy * e[4]; + e[13] = y - ox * e[1] - oy * e[5]; + } + + void Matrix::translate(float x, float y) + { + Matrix t; + t.setTranslation(x, y); + this->operator *=(t); + } + + void Matrix::rotate(float rad) + { + Matrix t; + t.setRotation(rad); + this->operator *=(t); + } + + void Matrix::scale(float sx, float sy) + { + Matrix t; + t.setScale(sx, sy); + this->operator *=(t); + } + + void Matrix::shear(float kx, float ky) + { + Matrix t; + t.setShear(kx, ky); + this->operator *=(t); + } + + // | x | + // | y | + // | 0 | + // | 1 | + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + void Matrix::transform(Graphics::Vertex* dst, const Graphics::Vertex* src, int size) const + { + for (int i = 0; i<size; ++i) + { + // Store in temp variables in case src = dst + float x = (e[0] * src[i].xy.x()) + (e[4] * src[i].xy.y()) + (0) + (e[12]); + float y = (e[1] * src[i].xy.x()) + (e[5] * src[i].xy.y()) + (0) + (e[13]); + + dst[i].xy.set(x, y); + } + } + + } }
\ No newline at end of file diff --git a/src/libjin/math/matrix.h b/src/libjin/math/matrix.h index 7955de1..c92a293 100644 --- a/src/libjin/math/matrix.h +++ b/src/libjin/math/matrix.h @@ -3,158 +3,158 @@ namespace JinEngine { - - // Forward declarations. - namespace Graphics - { - struct Vertex; - } - - namespace Math - { - - /// - /// This class is the basis for all transformations in LOVE. Althought not - /// really needed for 2D, it contains 4x4 elements to be compatible with - /// OpenGL without conversions. - /// ҪתõOpenGL - /// https://blog.csdn.net/candycat1992/article/details/8830894 - /// - class Matrix - { - private: - - /// - /// | e0 e4 e8 e12 | - /// | e1 e5 e9 e13 | - /// | e2 e6 e10 e14 | - /// | e3 e7 e11 e15 | - /// - float e[16]; - - public: - - static const Matrix Identity; - - /// - /// Creates a new identity matrix. - /// - Matrix(); - - /// - /// Destructor. - /// - ~Matrix(); - - void setOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far); - - /// - /// Multiplies this Matrix with another Matrix, changing neither. - /// @param m The Matrix to multiply with this Matrix. - /// @return The combined matrix. - /// - Matrix operator * (const Matrix & m) const; - - /// - /// Multiplies a Matrix into this Matrix. - /// @param m The Matrix to combine into this Matrix. - /// - void operator *= (const Matrix & m); - - /// - /// Gets a pointer to the 16 array elements. - /// @return The array elements. - /// - const float* getElements() const; - - /// - /// Resets this Matrix to the identity matrix. - /// - void setIdentity(); - - /// - /// Resets this Matrix to a translation. - /// @param x Translation along x-axis. - /// @param y Translation along y-axis. - /// - void setTranslation(float x, float y); - - /// - /// Resets this Matrix to a rotation. - /// @param r The angle in radians. - /// - void setRotation(float r); - - /// - /// Resets this Matrix to a scale transformation. - /// @param sx Scale factor along the x-axis. - /// @param sy Scale factor along the y-axis. - /// - void setScale(float sx, float sy); - - /// - /// Resets this Matrix to a shear transformation. - /// @param kx Shear along x-axis. - /// @param ky Shear along y-axis. - /// - void setShear(float kx, float ky); - - /// - /// Creates a transformation with a certain position, orientation, scale - /// and offset. Perfect for Drawables -- what a coincidence! - /// - /// @param x The translation along the x-axis. - /// @param y The translation along the y-axis. - /// @param angle The rotation (rad) around the center with offset (ox,oy). - /// @param sx Scale along x-axis. - /// @param sy Scale along y-axis. - /// @param ox The offset for rotation along the x-axis. - /// @param oy The offset for rotation along the y-axis. - /// @param kx Shear along x-axis - /// @param ky Shear along y-axis - /// - void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); - - /// - /// Multiplies this Matrix with a translation. - /// @param x Translation along x-axis. - /// @param y Translation along y-axis. - /// - void translate(float x, float y); - - /// - /// Multiplies this Matrix with a rotation. - /// @param r Angle in radians. - /// - void rotate(float r); - - /// - /// Multiplies this Matrix with a scale transformation. - /// @param sx Scale factor along the x-axis. - /// @param sy Scale factor along the y-axis. - /// - void scale(float sx, float sy); - - /// - /// Multiplies this Matrix with a shear transformation. - /// @param kx Shear along the x-axis. - /// @param ky Shear along the y-axis. - /// - void shear(float kx, float ky); - - /// - /// Transforms an array of vertices by this Matrix. The sources and - /// destination arrays may be the same. - /// - /// @param dst Storage for the transformed vertices. - /// @param src The source vertices. - /// @param size The number of vertices. - /// - void transform(Graphics::Vertex* dst, const Graphics::Vertex * src, int size) const; - - }; - - } // namespace Math + + // Forward declarations. + namespace Graphics + { + struct Vertex; + } + + namespace Math + { + + /// + /// This class is the basis for all transformations in LOVE. Althought not + /// really needed for 2D, it contains 4x4 elements to be compatible with + /// OpenGL without conversions. + /// ҪתõOpenGL + /// https://blog.csdn.net/candycat1992/article/details/8830894 + /// + class Matrix + { + private: + + /// + /// | e0 e4 e8 e12 | + /// | e1 e5 e9 e13 | + /// | e2 e6 e10 e14 | + /// | e3 e7 e11 e15 | + /// + float e[16]; + + public: + + static const Matrix Identity; + + /// + /// Creates a new identity matrix. + /// + Matrix(); + + /// + /// Destructor. + /// + ~Matrix(); + + void setOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far); + + /// + /// Multiplies this Matrix with another Matrix, changing neither. + /// @param m The Matrix to multiply with this Matrix. + /// @return The combined matrix. + /// + Matrix operator * (const Matrix & m) const; + + /// + /// Multiplies a Matrix into this Matrix. + /// @param m The Matrix to combine into this Matrix. + /// + void operator *= (const Matrix & m); + + /// + /// Gets a pointer to the 16 array elements. + /// @return The array elements. + /// + const float* getElements() const; + + /// + /// Resets this Matrix to the identity matrix. + /// + void setIdentity(); + + /// + /// Resets this Matrix to a translation. + /// @param x Translation along x-axis. + /// @param y Translation along y-axis. + /// + void setTranslation(float x, float y); + + /// + /// Resets this Matrix to a rotation. + /// @param r The angle in radians. + /// + void setRotation(float r); + + /// + /// Resets this Matrix to a scale transformation. + /// @param sx Scale factor along the x-axis. + /// @param sy Scale factor along the y-axis. + /// + void setScale(float sx, float sy); + + /// + /// Resets this Matrix to a shear transformation. + /// @param kx Shear along x-axis. + /// @param ky Shear along y-axis. + /// + void setShear(float kx, float ky); + + /// + /// Creates a transformation with a certain position, orientation, scale + /// and offset. Perfect for Drawables -- what a coincidence! + /// + /// @param x The translation along the x-axis. + /// @param y The translation along the y-axis. + /// @param angle The rotation (rad) around the center with offset (ox,oy). + /// @param sx Scale along x-axis. + /// @param sy Scale along y-axis. + /// @param ox The offset for rotation along the x-axis. + /// @param oy The offset for rotation along the y-axis. + /// @param kx Shear along x-axis + /// @param ky Shear along y-axis + /// + void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); + + /// + /// Multiplies this Matrix with a translation. + /// @param x Translation along x-axis. + /// @param y Translation along y-axis. + /// + void translate(float x, float y); + + /// + /// Multiplies this Matrix with a rotation. + /// @param r Angle in radians. + /// + void rotate(float r); + + /// + /// Multiplies this Matrix with a scale transformation. + /// @param sx Scale factor along the x-axis. + /// @param sy Scale factor along the y-axis. + /// + void scale(float sx, float sy); + + /// + /// Multiplies this Matrix with a shear transformation. + /// @param kx Shear along the x-axis. + /// @param ky Shear along the y-axis. + /// + void shear(float kx, float ky); + + /// + /// Transforms an array of vertices by this Matrix. The sources and + /// destination arrays may be the same. + /// + /// @param dst Storage for the transformed vertices. + /// @param src The source vertices. + /// @param size The number of vertices. + /// + void transform(Graphics::Vertex* dst, const Graphics::Vertex * src, int size) const; + + }; + + } // namespace Math } // namespace JinEngine #endif // __JE_MATRIX_H__ diff --git a/src/libjin/math/percentage.h b/src/libjin/math/percentage.h index a9fdc4e..41b311a 100644 --- a/src/libjin/math/percentage.h +++ b/src/libjin/math/percentage.h @@ -5,32 +5,32 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - class Percentage - { - public: - Percentage(float v) - { - value = clamp<float>(v, 0, 1); - } + class Percentage + { + public: + Percentage(float v) + { + value = clamp<float>(v, 0, 1); + } - Percentage(const Percentage& p) - { - value = p.value; - } + Percentage(const Percentage& p) + { + value = p.value; + } - void operator = (const Percentage& p) - { - value = p.value; - } + void operator = (const Percentage& p) + { + value = p.value; + } - float value; + float value; - }; + }; - } + } } #endif
\ No newline at end of file diff --git a/src/libjin/math/quad.h b/src/libjin/math/quad.h index 5bda125..4c4246e 100644 --- a/src/libjin/math/quad.h +++ b/src/libjin/math/quad.h @@ -3,29 +3,29 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - /// - /// - /// - struct Quad - { - Quad() - : x(0), y(0), w(0), h(0) - { - } + /// + /// + /// + struct Quad + { + Quad() + : x(0), y(0), w(0), h(0) + { + } - Quad(float _x, float _y, float _w, float _h) - : x(_x), y(_y), w(_w), h(_h) - { - } + Quad(float _x, float _y, float _w, float _h) + : x(_x), y(_y), w(_w), h(_h) + { + } - float x, y, w, h; + float x, y, w, h; - }; + }; - } // namespace Math + } // namespace Math } // namespace JinEngine #endif // __JE_QUAD_H__
\ No newline at end of file diff --git a/src/libjin/math/random.cpp b/src/libjin/math/random.cpp index 5f3b28c..288f6c8 100644 --- a/src/libjin/math/random.cpp +++ b/src/libjin/math/random.cpp @@ -4,51 +4,51 @@ namespace JinEngine { - namespace Math - { - - RandomGenerator::RandomGenerator(uint32 seed) - : mSeed(seed) - { - } - - uint32 RandomGenerator::rand() - { - unsigned int next = mSeed; - uint32 result; - - next *= 1103515245; - next += 12345; - result = (unsigned int)(next / 65536) % 2048; - - next *= 1103515245; - next += 12345; - result <<= 10; - result ^= (unsigned int)(next / 65536) % 1024; - - next *= 1103515245; - next += 12345; - result <<= 10; - result ^= (unsigned int)(next / 65536) % 1024; - - mSeed = next; - - return result; - } - - uint32 RandomGenerator::rand(uint32 min, uint32 max) - { - uint32 n = rand(); - return n % (max - min + 1) + min; - } - - float RandomGenerator::randf(float min, float max, int ac) - { - float floor = 0, ceil = max + reverse<float>(min); - uint32 a = pow(10.f, ac); - uint32 n = rand(floor*a, ceil*a); - return (float)n / a + min; - } - - } + namespace Math + { + + RandomGenerator::RandomGenerator(uint32 seed) + : mSeed(seed) + { + } + + uint32 RandomGenerator::rand() + { + unsigned int next = mSeed; + uint32 result; + + next *= 1103515245; + next += 12345; + result = (unsigned int)(next / 65536) % 2048; + + next *= 1103515245; + next += 12345; + result <<= 10; + result ^= (unsigned int)(next / 65536) % 1024; + + next *= 1103515245; + next += 12345; + result <<= 10; + result ^= (unsigned int)(next / 65536) % 1024; + + mSeed = next; + + return result; + } + + uint32 RandomGenerator::rand(uint32 min, uint32 max) + { + uint32 n = rand(); + return n % (max - min + 1) + min; + } + + float RandomGenerator::randf(float min, float max, int ac) + { + float floor = 0, ceil = max + reverse<float>(min); + uint32 a = pow(10.f, ac); + uint32 n = rand(floor*a, ceil*a); + return (float)n / a + min; + } + + } }
\ No newline at end of file diff --git a/src/libjin/math/random.h b/src/libjin/math/random.h index 1eb22c4..f2fbe22 100644 --- a/src/libjin/math/random.h +++ b/src/libjin/math/random.h @@ -5,29 +5,29 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - /// - /// A random number generator. - /// - class RandomGenerator - { - public: - RandomGenerator(uint32 seed); + /// + /// A random number generator. + /// + class RandomGenerator + { + public: + RandomGenerator(uint32 seed); - uint32 rand(); + uint32 rand(); - uint32 rand(uint32 min, uint32 max); + uint32 rand(uint32 min, uint32 max); - float randf(float min, float max, int ac); + float randf(float min, float max, int ac); - private: - uint32 mSeed; + private: + uint32 mSeed; - }; + }; - } // namespace Math + } // namespace Math } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/math/ranged_value.cpp b/src/libjin/math/ranged_value.cpp index 1a14467..1c8b2ff 100644 --- a/src/libjin/math/ranged_value.cpp +++ b/src/libjin/math/ranged_value.cpp @@ -2,70 +2,70 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - RangedValue::RangedValue() - : mCount(0) - { - } + RangedValue::RangedValue() + : mCount(0) + { + } - RangedValue::RangedValue(float* points, uint n) - : mCount(n) - { - for (uint i = 0; i < n; ++i) - { - float x = points[2*i]; - float y = points[2*i + 1]; - mXAxis.push_back(x); - mYAxis.push_back(y); - } - } + RangedValue::RangedValue(float* points, uint n) + : mCount(n) + { + for (uint i = 0; i < n; ++i) + { + float x = points[2*i]; + float y = points[2*i + 1]; + mXAxis.push_back(x); + mYAxis.push_back(y); + } + } - void RangedValue::addPoint(float x, float y) - { - mXAxis.push_back(x); - mYAxis.push_back(y); - ++mCount; - } + void RangedValue::addPoint(float x, float y) + { + mXAxis.push_back(x); + mYAxis.push_back(y); + ++mCount; + } - void RangedValue::removePoint(uint i) - { - mXAxis.erase(mXAxis.begin() + i); - mYAxis.erase(mYAxis.begin() + i); - --mCount; - } + void RangedValue::removePoint(uint i) + { + mXAxis.erase(mXAxis.begin() + i); + mYAxis.erase(mYAxis.begin() + i); + --mCount; + } - void RangedValue::insertPoint(uint i, float x, float y) - { - mXAxis.insert(mXAxis.begin() + i, x); - mYAxis.insert(mYAxis.begin() + i, y); - ++mCount; - } + void RangedValue::insertPoint(uint i, float x, float y) + { + mXAxis.insert(mXAxis.begin() + i, x); + mYAxis.insert(mYAxis.begin() + i, y); + ++mCount; + } - float RangedValue::getValue(float x) - { - int endIndex = -1; - int n = mCount; - for (int i = 1; i < n; i++) { - float t = mXAxis[i]; - if (t > x) { - endIndex = i; - break; - } - } - if (endIndex == -1) return mYAxis[n - 1]; - int startIndex = endIndex - 1; - float startValue = mYAxis[startIndex]; - float startX = mXAxis[startIndex]; - return startValue + (mYAxis[endIndex] - startValue) * ((x - startX) / (mXAxis[endIndex] - startX)); - } + float RangedValue::getValue(float x) + { + int endIndex = -1; + int n = mCount; + for (int i = 1; i < n; i++) { + float t = mXAxis[i]; + if (t > x) { + endIndex = i; + break; + } + } + if (endIndex == -1) return mYAxis[n - 1]; + int startIndex = endIndex - 1; + float startValue = mYAxis[startIndex]; + float startX = mXAxis[startIndex]; + return startValue + (mYAxis[endIndex] - startValue) * ((x - startX) / (mXAxis[endIndex] - startX)); + } - void RangedValue::clear() - { - mXAxis.clear(); - mYAxis.clear(); - } + void RangedValue::clear() + { + mXAxis.clear(); + mYAxis.clear(); + } - } + } }
\ No newline at end of file diff --git a/src/libjin/math/ranged_value.h b/src/libjin/math/ranged_value.h index 5a4c35d..abcca29 100644 --- a/src/libjin/math/ranged_value.h +++ b/src/libjin/math/ranged_value.h @@ -7,51 +7,51 @@ namespace JinEngine { - namespace Math - { - /* - * y ^ - * |-------- _ - * | \ / \ - * | --- \ - * | \ - * | \ - * +----------------------> x - */ - class RangedValue - { - public: - RangedValue(); + namespace Math + { + /* + * y ^ + * |-------- _ + * | \ / \ + * | --- \ + * | \ + * | \ + * +----------------------> x + */ + class RangedValue + { + public: + RangedValue(); - /// - /// Points of ranged value. - /// - /// @param points Points. - /// @param n Number of points. - /// - RangedValue(float* points, uint n); + /// + /// Points of ranged value. + /// + /// @param points Points. + /// @param n Number of points. + /// + RangedValue(float* points, uint n); - virtual ~RangedValue() {} + virtual ~RangedValue() {} - virtual void addPoint(float x, float y); + virtual void addPoint(float x, float y); - virtual void removePoint(uint i); + virtual void removePoint(uint i); - virtual void insertPoint(uint i, float x, float y); + virtual void insertPoint(uint i, float x, float y); - virtual float getValue(float x); + virtual float getValue(float x); - virtual void clear(); + virtual void clear(); - private: - std::vector<float> mXAxis; - std::vector<float> mYAxis; + private: + std::vector<float> mXAxis; + std::vector<float> mYAxis; - uint mCount; + uint mCount; - }; + }; - } + } } #endif
\ No newline at end of file diff --git a/src/libjin/math/transform.cpp b/src/libjin/math/transform.cpp index 84c8327..71e83e5 100644 --- a/src/libjin/math/transform.cpp +++ b/src/libjin/math/transform.cpp @@ -2,103 +2,103 @@ namespace JinEngine { - namespace Math - { - - Transform::Transform() - : mScale(1, 1) - , mPosition(0, 0) - , mOrigin(0, 0) - , mRotation(0) - { - } - - Transform::Transform(float x, float y, float sx, float sy, float r, float ox, float oy) - { - set(x, y, sx, sy, r, ox, oy); - } - - void Transform::set(float x, float y, float sx, float sy, float r, float ox, float oy) - { - setPosition(x, y); - setScale(sx, sy); - setRotation(r); - setOrigin(ox, oy); - } - - void Transform::setScale(float sx, float sy) - { - mScale.set(sx, sy); - } - - Vector2<float> Transform::getScale() const - { - return mScale; - } - - void Transform::scale(float sx, float sy) - { - mScale.x() *= sx; - mScale.y() *= sy; - } - - void Transform::setPosition(const Vector2<float>& p) - { - setPosition(p.x(), p.y()); - } - - void Transform::setPosition(float x, float y) - { - mPosition.set(x, y); - } - - Vector2<float> Transform::getPosition() const - { - return mPosition; - } - - void Transform::move(float x, float y) - { - mPosition.x() += x; - mPosition.y() += y; - } - - void Transform::move(const Vector2<float>& v) - { - move(v.x(), v.y()); - } - - void Transform::setOrigin(float x, float y) - { - mOrigin.set(x, y); - } - - Vector2<float> Transform::getOrigin() const - { - return mOrigin; - } - - void Transform::setRotation(float r) - { - mRotation = r; - } - - float Transform::getRotation() const - { - return mRotation; - } - - void Transform::rotate(float r) - { - mRotation += r; - } - - Matrix Transform::getMatrix() const - { - Matrix m; - m.setTransformation(mPosition.x(), mPosition.y(), mRotation, mScale.x(), mScale.y(), mOrigin.x(), mOrigin.y()); - return m; - } - - } + namespace Math + { + + Transform::Transform() + : mScale(1, 1) + , mPosition(0, 0) + , mOrigin(0, 0) + , mRotation(0) + { + } + + Transform::Transform(float x, float y, float sx, float sy, float r, float ox, float oy) + { + set(x, y, sx, sy, r, ox, oy); + } + + void Transform::set(float x, float y, float sx, float sy, float r, float ox, float oy) + { + setPosition(x, y); + setScale(sx, sy); + setRotation(r); + setOrigin(ox, oy); + } + + void Transform::setScale(float sx, float sy) + { + mScale.set(sx, sy); + } + + Vector2<float> Transform::getScale() const + { + return mScale; + } + + void Transform::scale(float sx, float sy) + { + mScale.x() *= sx; + mScale.y() *= sy; + } + + void Transform::setPosition(const Vector2<float>& p) + { + setPosition(p.x(), p.y()); + } + + void Transform::setPosition(float x, float y) + { + mPosition.set(x, y); + } + + Vector2<float> Transform::getPosition() const + { + return mPosition; + } + + void Transform::move(float x, float y) + { + mPosition.x() += x; + mPosition.y() += y; + } + + void Transform::move(const Vector2<float>& v) + { + move(v.x(), v.y()); + } + + void Transform::setOrigin(float x, float y) + { + mOrigin.set(x, y); + } + + Vector2<float> Transform::getOrigin() const + { + return mOrigin; + } + + void Transform::setRotation(float r) + { + mRotation = r; + } + + float Transform::getRotation() const + { + return mRotation; + } + + void Transform::rotate(float r) + { + mRotation += r; + } + + Matrix Transform::getMatrix() const + { + Matrix m; + m.setTransformation(mPosition.x(), mPosition.y(), mRotation, mScale.x(), mScale.y(), mOrigin.x(), mOrigin.y()); + return m; + } + + } }
\ No newline at end of file diff --git a/src/libjin/math/transform.h b/src/libjin/math/transform.h index 3f3c199..0a0fa0a 100644 --- a/src/libjin/math/transform.h +++ b/src/libjin/math/transform.h @@ -6,45 +6,45 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - class Transform - { - public: - Transform(); - Transform(float x, float y, float sx, float sy, float r, float ox, float oy); + class Transform + { + public: + Transform(); + Transform(float x, float y, float sx, float sy, float r, float ox, float oy); - void set(float x, float y, float sx, float sy, float r, float ox, float oy); + void set(float x, float y, float sx, float sy, float r, float ox, float oy); - void setScale(float sx, float sy); - Vector2<float> getScale() const; - void scale(float sx, float sy); + void setScale(float sx, float sy); + Vector2<float> getScale() const; + void scale(float sx, float sy); - void setPosition(float x, float y); - void setPosition(const Vector2<float>& p); - Vector2<float> getPosition() const; - void move(float x, float y); - void move(const Vector2<float>& v); + void setPosition(float x, float y); + void setPosition(const Vector2<float>& p); + Vector2<float> getPosition() const; + void move(float x, float y); + void move(const Vector2<float>& v); - void setOrigin(float x, float y); - Vector2<float> getOrigin() const; + void setOrigin(float x, float y); + Vector2<float> getOrigin() const; - void setRotation(float r); - float getRotation() const; - void rotate(float r); + void setRotation(float r); + float getRotation() const; + void rotate(float r); - Matrix getMatrix() const; + Matrix getMatrix() const; - private: - Vector2<float> mPosition; - Vector2<float> mOrigin; - Vector2<float> mScale; - float mRotation; + private: + Vector2<float> mPosition; + Vector2<float> mOrigin; + Vector2<float> mScale; + float mRotation; - }; + }; - } + } } #endif
\ No newline at end of file diff --git a/src/libjin/math/vector2.hpp b/src/libjin/math/vector2.hpp index 6115a63..b61205b 100644 --- a/src/libjin/math/vector2.hpp +++ b/src/libjin/math/vector2.hpp @@ -3,80 +3,80 @@ namespace JinEngine { - namespace Math - { + namespace Math + { - template<typename T> - class Vector2 - { - public: - Vector2() - { - data[0] = data[1] = 0; - } - Vector2(T _x, T _y) - { - data[0] = _x; - data[1] = _y; - } - Vector2(const Vector2<T>& v) - { - data[0] = v.data[0]; - data[1] = v.data[1]; - } + template<typename T> + class Vector2 + { + public: + Vector2() + { + data[0] = data[1] = 0; + } + Vector2(T _x, T _y) + { + data[0] = _x; + data[1] = _y; + } + Vector2(const Vector2<T>& v) + { + data[0] = v.data[0]; + data[1] = v.data[1]; + } - void operator = (const Vector2<T>& v) - { - data[0] = v.data[0]; - data[1] = v.data[1]; - } + void operator = (const Vector2<T>& v) + { + data[0] = v.data[0]; + data[1] = v.data[1]; + } - Vector2<T> operator * (float n) - { - return Vector2<T>(data[0]*n, data[1]*n); - } + Vector2<T> operator * (float n) + { + return Vector2<T>(data[0]*n, data[1]*n); + } - void operator +=(const Vector2<T> v) - { - data[0] += v.data[0]; - data[1] += v.data[1]; - } + void operator +=(const Vector2<T> v) + { + data[0] += v.data[0]; + data[1] += v.data[1]; + } - Vector2<T> operator +(const Vector2<T>& v) - { - return Vector2<T>(data[0] + v.data[0], data[1] + v.data[1]); - } + Vector2<T> operator +(const Vector2<T>& v) + { + return Vector2<T>(data[0] + v.data[0], data[1] + v.data[1]); + } - void set(T _x, T _y) - { - data[0] = _x; - data[1] = _y; - } + void set(T _x, T _y) + { + data[0] = _x; + data[1] = _y; + } - bool isZero() - { - return data[0] == 0 && data[1] == 0; - } + bool isZero() + { + return data[0] == 0 && data[1] == 0; + } - #define _aliases(A, B) \ - inline T& A() { return data[0]; }\ - inline T& B() { return data[1]; }\ - inline T A() const { return data[0]; }\ - inline T B() const { return data[1]; } + #define _aliases(A, B) \ + inline T& A() { return data[0]; }\ + inline T& B() { return data[1]; }\ + inline T A() const { return data[0]; }\ + inline T B() const { return data[1]; } - _aliases(x, y); - _aliases(w, h); - _aliases(u, v); - _aliases(colum, row); + _aliases(x, y); + _aliases(w, h); + _aliases(u, v); + _aliases(colum, row); - #undef _aliases + #undef _aliases - private: - T data[2]; + private: + T data[2]; - }; + }; - } // namespace Math + } // namespace Math } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/math/vector3.hpp b/src/libjin/math/vector3.hpp index 3c800b6..85babf5 100644 --- a/src/libjin/math/vector3.hpp +++ b/src/libjin/math/vector3.hpp @@ -3,49 +3,49 @@ namespace JinEngine { - namespace Math - { - - template<typename T> - class Vector3 - { - public: - Vector3() - { - data[0] = data[1] = data[2] = 0; - } - Vector3(T _x, T _y, T _z) - { - data[0] = _x; - data[1] = _y; - data[2] = _z; - } - Vector3(const Vector3<T>& v) - { - data[0] = v.data[0]; - data[1] = v.data[1]; - data[2] = v.data[2]; - } - - #define _aliases(A, B, C) \ - inline T& A() { return data[0]; }\ - inline T& B() { return data[1]; }\ - inline T& C() { return data[2]; }\ - inline T A() const { return data[0]; }\ - inline T B() const { return data[1]; }\ - inline T C() const { return data[2]; } - - _aliases(x, y, z); - _aliases(r, g, b); - - #undef _aliases - - private: - T data[3]; - - }; - - } // namespace Math + namespace Math + { + + template<typename T> + class Vector3 + { + public: + Vector3() + { + data[0] = data[1] = data[2] = 0; + } + Vector3(T _x, T _y, T _z) + { + data[0] = _x; + data[1] = _y; + data[2] = _z; + } + Vector3(const Vector3<T>& v) + { + data[0] = v.data[0]; + data[1] = v.data[1]; + data[2] = v.data[2]; + } + + #define _aliases(A, B, C) \ + inline T& A() { return data[0]; }\ + inline T& B() { return data[1]; }\ + inline T& C() { return data[2]; }\ + inline T A() const { return data[0]; }\ + inline T B() const { return data[1]; }\ + inline T C() const { return data[2]; } + + _aliases(x, y, z); + _aliases(r, g, b); + + #undef _aliases + + private: + T data[3]; + + }; + + } // namespace Math } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/math/vector4.hpp b/src/libjin/math/vector4.hpp index b544126..01a2309 100644 --- a/src/libjin/math/vector4.hpp +++ b/src/libjin/math/vector4.hpp @@ -3,55 +3,55 @@ namespace JinEngine { - namespace Math - { - - template<typename T> - class Vector4 - { - public: - Vector4() - { - data[0] = data[1] = data[2] = data[3] = 0; - } - Vector4(T _x, T _y, T _z, T _t) - { - data[0] = _x; - data[1] = _y; - data[2] = _z; - data[3] = _t; - } - Vector4(const Vector4<T>& v) - { - data[0] = v.data[0]; - data[1] = v.data[1]; - data[2] = v.data[2]; - data[3] = v.data[3]; - } - - #define _aliases(A, B, C, D) \ - inline T& A() { return data[0]; } \ - inline T& B() { return data[1]; } \ - inline T& C() { return data[2]; } \ - inline T& D() { return data[3]; } \ - inline T A() const { return data[0]; } \ - inline T B() const { return data[1]; } \ - inline T C() const { return data[2]; } \ - inline T D() const { return data[3]; } - - _aliases(x, y, z, t); - _aliases(x1, y1, w, h); - _aliases(r, g, b, a); - _aliases(left, right, top, bottom); - - #undef _aliases - - private: - T data[4]; - - }; - - } // namespace Math + namespace Math + { + + template<typename T> + class Vector4 + { + public: + Vector4() + { + data[0] = data[1] = data[2] = data[3] = 0; + } + Vector4(T _x, T _y, T _z, T _t) + { + data[0] = _x; + data[1] = _y; + data[2] = _z; + data[3] = _t; + } + Vector4(const Vector4<T>& v) + { + data[0] = v.data[0]; + data[1] = v.data[1]; + data[2] = v.data[2]; + data[3] = v.data[3]; + } + + #define _aliases(A, B, C, D) \ + inline T& A() { return data[0]; } \ + inline T& B() { return data[1]; } \ + inline T& C() { return data[2]; } \ + inline T& D() { return data[3]; } \ + inline T A() const { return data[0]; } \ + inline T B() const { return data[1]; } \ + inline T C() const { return data[2]; } \ + inline T D() const { return data[3]; } + + _aliases(x, y, z, t); + _aliases(x1, y1, w, h); + _aliases(r, g, b, a); + _aliases(left, right, top, bottom); + + #undef _aliases + + private: + T data[4]; + + }; + + } // namespace Math } // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/net/net_manager.cpp b/src/libjin/net/net_manager.cpp index 632219c..53ddfbc 100644 --- a/src/libjin/net/net_manager.cpp +++ b/src/libjin/net/net_manager.cpp @@ -2,23 +2,23 @@ namespace JinEngine { - namespace Net - { + namespace Net + { - bool NetManager::startSystem(const SettingBase* setting) - { - #ifdef _WIN32 - #if jin_net == jin_net_tekcos - tk_init(); - #endif - #endif - return true; - } + bool NetManager::startSystem(const SettingBase* setting) + { + #ifdef _WIN32 + #if jin_net == jin_net_tekcos + tk_init(); + #endif + #endif + return true; + } - void NetManager::quitSystem() - { + void NetManager::quitSystem() + { - } + } - } // namespace Net + } // namespace Net } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/net/net_manager.h b/src/libjin/net/net_manager.h index 36238f8..19c0192 100644 --- a/src/libjin/net/net_manager.h +++ b/src/libjin/net/net_manager.h @@ -9,38 +9,38 @@ namespace JinEngine { - namespace Net - { - - /// - /// - /// - class NetManager : public Subsystem<NetManager> - { - public: - /// - /// - /// - NetManager() {}; - - /// - /// - /// - ~NetManager() {}; - - /// - /// - /// - bool startSystem(const SettingBase* setting) override; - - /// - /// - /// - void quitSystem() override; - - }; - - } // namespace Net + namespace Net + { + + /// + /// + /// + class NetManager : public Subsystem<NetManager> + { + public: + /// + /// + /// + NetManager() {}; + + /// + /// + /// + ~NetManager() {}; + + /// + /// + /// + bool startSystem(const SettingBase* setting) override; + + /// + /// + /// + void quitSystem() override; + + }; + + } // namespace Net } // namespace JinEngine #endif // defined(jin_net) diff --git a/src/libjin/net/socket.cpp b/src/libjin/net/socket.cpp index 3d59a57..cbea27f 100644 --- a/src/libjin/net/socket.cpp +++ b/src/libjin/net/socket.cpp @@ -2,189 +2,189 @@ namespace JinEngine { - namespace Net - { - Socket::Socket(const Socket& socket) - : mHandle(socket.mHandle) - , mType(socket.mType) - { - } - - Socket::Socket(const SocketInformation& info) - : mType(info.type) - { - if (mType == SocketType::TCP) - { - tk_IPaddress ip; - ip.host = info.address; - ip.port = info.port; - mHandle.tcpHandle = tk_tcp_open(ip); - } - else if (mType == SocketType::UDP) - { - mHandle.udpHandle = tk_udp_open(info.port); - } - } - - Socket::Socket(SocketType type, const char* address, unsigned short port) - { - mType = type; - if (mType == SocketType::TCP) - { - tk_IPaddress ip; - #if jin_net == jin_net_tekcos - ip.host = tk_strtohl(address); - ip.port = port; - mHandle.tcpHandle = tk_tcp_open(ip); - #endif - } - else if (mType == SocketType::UDP) - { - mHandle.udpHandle = tk_udp_open(port); - } - } - - Socket::Socket(SocketType type, unsigned int address, unsigned short port) - { - mType = type; - if (mType == SocketType::TCP) - { - tk_IPaddress ip; - ip.host = address; - ip.port = port; - mHandle.tcpHandle = tk_tcp_open(ip); - } - else if (mType == SocketType::UDP) - { - mHandle.udpHandle = tk_udp_open(port); - } - } - - Socket::Socket(SocketType type, unsigned short port) - { - mType = type; - if (mType == SocketType::TCP) - { - tk_IPaddress ip; - ip.host = 0; - ip.port = port; - mHandle.tcpHandle = tk_tcp_open(ip); - } - else if (mType == SocketType::UDP) - { - mHandle.udpHandle = tk_udp_open(port); - } - } - - #if jin_net == jin_net_tekcos - - Socket::Socket(const tk_TCPsocket& tcphandle) - { - mHandle.tcpHandle = tcphandle; - } - - Socket::Socket(const tk_UDPsocket& udphandle) - { - mHandle.udpHandle = udphandle; - } - - #endif // jin_net == jin_net_tekcos - - Socket::~Socket() - { - } - - void Socket::configureBlocking(bool blocking) - { - if (mType != SocketType::TCP) - return; - #if jin_net == jin_net_tekcos - if (blocking) - tk_tcp_blocking(&mHandle.tcpHandle); - else - tk_tcp_nonblocking(&mHandle.tcpHandle); - #endif - } - - Socket* Socket::accept() - { - if (mType != SocketType::TCP) - return nullptr; - Socket* client; - #if jin_net == jin_net_tekcos - tk_TCPsocket socket = tk_tcp_accept(&mHandle.tcpHandle); - client = new Socket(socket); - #endif - return client; - } - - int Socket::receive(char* buffer, int size) - { - if (mType != SocketType::TCP) - return 0; - #if jin_net == jin_net_tekcos - int len; - tk_tcp_recv(&mHandle.tcpHandle, buffer, size, &len); - return len; - #endif - } - - int Socket::send(char* buffer, int size) - { - if (mType != SocketType::TCP) - return 0; - #if jin_net == jin_net_tekcos - int len; - tk_tcp_send(&mHandle.tcpHandle, buffer, size, &len); - return len; - #endif - } - - void Socket::sendTo(char* buffer, int size, unsigned int address, unsigned int port) - { - if (mType != SocketType::UDP) - return; - #if jin_net == jin_net_tekcos - tk_UDPpack pack; - pack.data = buffer; - pack.len = size; - pack.ip.host = address; - pack.ip.port = port; - tk_udp_sendto(&mHandle.udpHandle, &pack); - #endif - } - - int Socket::receiveFrom(char* buffer, int size, unsigned int address, unsigned int port) - { - if (mType != SocketType::UDP) - return 0; - int len; - #if jin_net == jin_net_tekcos - tk_UDPpack pack; - pack.data = buffer; - pack.len = size; - pack.ip.host = address; - pack.ip.port = port; - tk_udp_recvfrom(&mHandle.udpHandle, &pack); - return pack.len; - #endif - } - - void Socket::close() - { - if (mType == SocketType::TCP) - { - #if jin_net == jin_net_tekcos - tk_tcp_close(&mHandle.tcpHandle); - #endif - } - else if (mType == SocketType::UDP) - { - #if jin_net == jin_net_tekcos - tk_udp_close(&mHandle.udpHandle); - #endif - } - } - - } // namespace Net + namespace Net + { + Socket::Socket(const Socket& socket) + : mHandle(socket.mHandle) + , mType(socket.mType) + { + } + + Socket::Socket(const SocketInformation& info) + : mType(info.type) + { + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = info.address; + ip.port = info.port; + mHandle.tcpHandle = tk_tcp_open(ip); + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(info.port); + } + } + + Socket::Socket(SocketType type, const char* address, unsigned short port) + { + mType = type; + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + #if jin_net == jin_net_tekcos + ip.host = tk_strtohl(address); + ip.port = port; + mHandle.tcpHandle = tk_tcp_open(ip); + #endif + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(port); + } + } + + Socket::Socket(SocketType type, unsigned int address, unsigned short port) + { + mType = type; + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = address; + ip.port = port; + mHandle.tcpHandle = tk_tcp_open(ip); + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(port); + } + } + + Socket::Socket(SocketType type, unsigned short port) + { + mType = type; + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = 0; + ip.port = port; + mHandle.tcpHandle = tk_tcp_open(ip); + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(port); + } + } + + #if jin_net == jin_net_tekcos + + Socket::Socket(const tk_TCPsocket& tcphandle) + { + mHandle.tcpHandle = tcphandle; + } + + Socket::Socket(const tk_UDPsocket& udphandle) + { + mHandle.udpHandle = udphandle; + } + + #endif // jin_net == jin_net_tekcos + + Socket::~Socket() + { + } + + void Socket::configureBlocking(bool blocking) + { + if (mType != SocketType::TCP) + return; + #if jin_net == jin_net_tekcos + if (blocking) + tk_tcp_blocking(&mHandle.tcpHandle); + else + tk_tcp_nonblocking(&mHandle.tcpHandle); + #endif + } + + Socket* Socket::accept() + { + if (mType != SocketType::TCP) + return nullptr; + Socket* client; + #if jin_net == jin_net_tekcos + tk_TCPsocket socket = tk_tcp_accept(&mHandle.tcpHandle); + client = new Socket(socket); + #endif + return client; + } + + int Socket::receive(char* buffer, int size) + { + if (mType != SocketType::TCP) + return 0; + #if jin_net == jin_net_tekcos + int len; + tk_tcp_recv(&mHandle.tcpHandle, buffer, size, &len); + return len; + #endif + } + + int Socket::send(char* buffer, int size) + { + if (mType != SocketType::TCP) + return 0; + #if jin_net == jin_net_tekcos + int len; + tk_tcp_send(&mHandle.tcpHandle, buffer, size, &len); + return len; + #endif + } + + void Socket::sendTo(char* buffer, int size, unsigned int address, unsigned int port) + { + if (mType != SocketType::UDP) + return; + #if jin_net == jin_net_tekcos + tk_UDPpack pack; + pack.data = buffer; + pack.len = size; + pack.ip.host = address; + pack.ip.port = port; + tk_udp_sendto(&mHandle.udpHandle, &pack); + #endif + } + + int Socket::receiveFrom(char* buffer, int size, unsigned int address, unsigned int port) + { + if (mType != SocketType::UDP) + return 0; + int len; + #if jin_net == jin_net_tekcos + tk_UDPpack pack; + pack.data = buffer; + pack.len = size; + pack.ip.host = address; + pack.ip.port = port; + tk_udp_recvfrom(&mHandle.udpHandle, &pack); + return pack.len; + #endif + } + + void Socket::close() + { + if (mType == SocketType::TCP) + { + #if jin_net == jin_net_tekcos + tk_tcp_close(&mHandle.tcpHandle); + #endif + } + else if (mType == SocketType::UDP) + { + #if jin_net == jin_net_tekcos + tk_udp_close(&mHandle.udpHandle); + #endif + } + } + + } // namespace Net } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/net/socket.h b/src/libjin/net/socket.h index 1562272..4a65245 100644 --- a/src/libjin/net/socket.h +++ b/src/libjin/net/socket.h @@ -9,136 +9,136 @@ namespace JinEngine { - namespace Net - { - - /// - /// - /// - enum SocketType - { - TCP, - UDP - }; - - /// - /// - /// - struct SocketInformation - { - unsigned int address; - unsigned short port; - SocketType type; - }; - - /// - /// - /// - class Socket : public Object - { - public: - - /// - /// - /// - Socket() {}; - - /// - /// - /// - Socket(const Socket& socket); - - /// - /// - /// - Socket(const SocketInformation& socketInformation); - - /// - /// - /// - Socket(SocketType type, unsigned short port); - - /// - /// - /// - Socket(SocketType type, unsigned int address, unsigned short port); - - /// - /// - /// - Socket(SocketType type, const char* address, unsigned short port); - - /// - /// - /// - ~Socket(); - - /// - /// - /// - void configureBlocking(bool bocking); - - /// - /// - /// - Socket* accept(); - - /// - /// - /// - int receive(char* buffer, int size); - - /// - /// - /// - int send(char* buffer, int size); - - /// - /// - /// - void sendTo(char* buffer, int size, unsigned int address, unsigned int port); - - /// - /// - /// - int receiveFrom(char* buffer, int size, unsigned int address, unsigned int port); - - /// - /// - /// - void close(); - - protected: - #if jin_net == jin_net_tekcos - - /// - /// - /// - Socket(const tk_TCPsocket& tcpHandle); - - /// - /// - /// - Socket(const tk_UDPsocket& udpHandle); - - /// - /// - /// - union - { - tk_TCPsocket tcpHandle; - tk_UDPsocket udpHandle; - } mHandle; - #endif - - /// - /// - /// - SocketType mType; - - }; - - } // namespace Net + namespace Net + { + + /// + /// + /// + enum SocketType + { + TCP, + UDP + }; + + /// + /// + /// + struct SocketInformation + { + unsigned int address; + unsigned short port; + SocketType type; + }; + + /// + /// + /// + class Socket : public Object + { + public: + + /// + /// + /// + Socket() {}; + + /// + /// + /// + Socket(const Socket& socket); + + /// + /// + /// + Socket(const SocketInformation& socketInformation); + + /// + /// + /// + Socket(SocketType type, unsigned short port); + + /// + /// + /// + Socket(SocketType type, unsigned int address, unsigned short port); + + /// + /// + /// + Socket(SocketType type, const char* address, unsigned short port); + + /// + /// + /// + ~Socket(); + + /// + /// + /// + void configureBlocking(bool bocking); + + /// + /// + /// + Socket* accept(); + + /// + /// + /// + int receive(char* buffer, int size); + + /// + /// + /// + int send(char* buffer, int size); + + /// + /// + /// + void sendTo(char* buffer, int size, unsigned int address, unsigned int port); + + /// + /// + /// + int receiveFrom(char* buffer, int size, unsigned int address, unsigned int port); + + /// + /// + /// + void close(); + + protected: + #if jin_net == jin_net_tekcos + + /// + /// + /// + Socket(const tk_TCPsocket& tcpHandle); + + /// + /// + /// + Socket(const tk_UDPsocket& udpHandle); + + /// + /// + /// + union + { + tk_TCPsocket tcpHandle; + tk_UDPsocket udpHandle; + } mHandle; + #endif + + /// + /// + /// + SocketType mType; + + }; + + } // namespace Net } // namespace JinEngine #endif // defined(jin_net) diff --git a/src/libjin/threads/thread.cpp b/src/libjin/threads/thread.cpp index 1c35efb..0dfa53b 100644 --- a/src/libjin/threads/thread.cpp +++ b/src/libjin/threads/thread.cpp @@ -5,297 +5,297 @@ namespace JinEngine { - namespace Threads - { - - class Mutex - { - public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - private: - #if jin_thread == jin_thread_sdl - SDL_mutex* mutex; - #endif - friend class Conditional; - }; - - // ̼߳signal wait - class Conditional - { - public: - Conditional(); - ~Conditional(); - void signal(); - void broadcast(); - bool wait(Mutex* mutex, int timeout = -1); - private: - #if jin_thread == jin_thread_sdl - SDL_cond* cond; - #endif - }; - - class Lock - { - public: - Lock(Mutex* m) : mutex(m) { - mutex->lock(); - } - - Lock(Mutex& m) : mutex(&m) { - mutex->lock(); - } - - ~Lock() { - mutex->unlock(); - } - private: - Mutex* mutex; - - Lock(Lock&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - Mutex::Mutex() - { - #if jin_thread == jin_thread_sdl - mutex = SDL_CreateMutex(); - #endif - } - - Mutex::~Mutex() - { - #if jin_thread == jin_thread_sdl - SDL_DestroyMutex(mutex); - #endif - } - - void Mutex::lock() - { - #if jin_thread == jin_thread_sdl - SDL_LockMutex(mutex); - #endif - } - - void Mutex::unlock() - { - #if jin_thread == jin_thread_sdl - SDL_UnlockMutex(mutex); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Conditional::Conditional() - { - #if jin_thread == jin_thread_sdl - cond = SDL_CreateCond(); - #endif - } - - Conditional::~Conditional() - { - #if jin_thread == jin_thread_sdl - SDL_DestroyCond(cond); - #endif - } - - void Conditional::signal() - { - #if jin_thread == jin_thread_sdl - SDL_CondSignal(cond); - #endif - } - - void Conditional::broadcast() - { - #if jin_thread == jin_thread_sdl - SDL_CondBroadcast(cond); - #endif - } - - bool Conditional::wait(Mutex* mutex, int timeout) - { - #if jin_thread == jin_thread_sdl - if (timeout < 0) - return !SDL_CondWait(cond, mutex->mutex); - else - return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Thread::ThreadData::ThreadData(Mutex* m, Conditional* c) - : mutex(m) - , condition(c) - , share() - { - } - - Thread::ThreadData::~ThreadData() - { - } - - void Thread::ThreadData::set(int slot, Variant value) - { - Lock l(mutex); - share[slot] = value; - } - - Thread::Variant Thread::ThreadData::get(int slot) - { - Lock l(mutex); - return share[slot]; - } - - bool Thread::ThreadData::exist(int slot) - { - Lock l(mutex); - return share.count(slot) == 1; - } - - void Thread::ThreadData::remove(int slot) - { - Lock l(mutex); - if (exist(slot)) - { - share.erase(slot); - } - } - - ////////////////////////////////////////////////////////////////////// - - Thread::Thread(const std::string tname, ThreadRunner runner) - : name(tname) - , running(false) - , threadRunner(runner) - { - mutex = new Mutex(); - condition = new Conditional(); - common = new Thread::ThreadData(mutex, condition); - } - - Thread::~Thread() - { - #if jin_thread == jin_thread_sdl - #endif - } - - const char* Thread::getName() - { - Lock l(mutex); - return name.c_str(); - }; - - bool Thread::isRunning() - { - Lock l(mutex); - return running; - }; - - bool Thread::start(void* p) - { - Lock l(mutex); - if (running) - return false; - if (handle) - { - #if jin_thread == jin_thread_sdl - SDL_WaitThread(handle, nullptr); - #endif - } - #if jin_thread == jin_thread_sdl - handle = SDL_CreateThread(threadRunner, name.c_str(), p); - #elif jin_thread == jin_thread_cpp - handle = new std::thread(); - #endif - return (running = (handle != nullptr)); - } - - void Thread::wait() - { - { - Lock l(mutex); - if (!handle) - return; - } - #if jin_thread == jin_thread_sdl - SDL_WaitThread(handle, nullptr); - #endif - Lock l(mutex); - running = false; - handle = nullptr; - } - - void Thread::lock() - { - if (mutex != nullptr) - mutex->lock(); - } - - void Thread::unlock() - { - if (mutex != nullptr) - mutex->unlock(); - } - - void Thread::send(int slot, const Variant& value) - { - lock(); - common->set(slot, value); - unlock(); - condition->broadcast(); - } - - bool Thread::receive(int slot) - { - return common->exist(slot); - } - - Thread::Variant Thread::fetch(int slot) - { - Thread::Variant v = common->get(slot); - return v; - } - - Thread::Variant Thread::demand(int slot) - { - /** - * pthread_mutex_lock(mtx); - * while(pass == 0) - * { - * pthread_mutex_unlock(mtx); - * pthread_cond_just_wait(cv); - * pthread_mutex_lock(mtx); - * } - * pthread_mutex_unlock(mtx); - */ - lock(); - while (!common->exist(slot)) - { - if (common->exist(ThreadData::SLOT_ERROR)) - return 0; - condition->wait(mutex); - } - Thread::Variant v = common->get(slot); - unlock(); - return v; - } - - void Thread::remove(int slot) - { - lock(); - common->remove(slot); - unlock(); - } - - } // namespace Threads + namespace Threads + { + + class Mutex + { + public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + private: + #if jin_thread == jin_thread_sdl + SDL_mutex* mutex; + #endif + friend class Conditional; + }; + + // ̼߳signal wait + class Conditional + { + public: + Conditional(); + ~Conditional(); + void signal(); + void broadcast(); + bool wait(Mutex* mutex, int timeout = -1); + private: + #if jin_thread == jin_thread_sdl + SDL_cond* cond; + #endif + }; + + class Lock + { + public: + Lock(Mutex* m) : mutex(m) { + mutex->lock(); + } + + Lock(Mutex& m) : mutex(&m) { + mutex->lock(); + } + + ~Lock() { + mutex->unlock(); + } + private: + Mutex* mutex; + + Lock(Lock&) {} + + }; + + ////////////////////////////////////////////////////////////////////// + + Mutex::Mutex() + { + #if jin_thread == jin_thread_sdl + mutex = SDL_CreateMutex(); + #endif + } + + Mutex::~Mutex() + { + #if jin_thread == jin_thread_sdl + SDL_DestroyMutex(mutex); + #endif + } + + void Mutex::lock() + { + #if jin_thread == jin_thread_sdl + SDL_LockMutex(mutex); + #endif + } + + void Mutex::unlock() + { + #if jin_thread == jin_thread_sdl + SDL_UnlockMutex(mutex); + #endif + } + + ////////////////////////////////////////////////////////////////////// + + Conditional::Conditional() + { + #if jin_thread == jin_thread_sdl + cond = SDL_CreateCond(); + #endif + } + + Conditional::~Conditional() + { + #if jin_thread == jin_thread_sdl + SDL_DestroyCond(cond); + #endif + } + + void Conditional::signal() + { + #if jin_thread == jin_thread_sdl + SDL_CondSignal(cond); + #endif + } + + void Conditional::broadcast() + { + #if jin_thread == jin_thread_sdl + SDL_CondBroadcast(cond); + #endif + } + + bool Conditional::wait(Mutex* mutex, int timeout) + { + #if jin_thread == jin_thread_sdl + if (timeout < 0) + return !SDL_CondWait(cond, mutex->mutex); + else + return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); + #endif + } + + ////////////////////////////////////////////////////////////////////// + + Thread::ThreadData::ThreadData(Mutex* m, Conditional* c) + : mutex(m) + , condition(c) + , share() + { + } + + Thread::ThreadData::~ThreadData() + { + } + + void Thread::ThreadData::set(int slot, Variant value) + { + Lock l(mutex); + share[slot] = value; + } + + Thread::Variant Thread::ThreadData::get(int slot) + { + Lock l(mutex); + return share[slot]; + } + + bool Thread::ThreadData::exist(int slot) + { + Lock l(mutex); + return share.count(slot) == 1; + } + + void Thread::ThreadData::remove(int slot) + { + Lock l(mutex); + if (exist(slot)) + { + share.erase(slot); + } + } + + ////////////////////////////////////////////////////////////////////// + + Thread::Thread(const std::string tname, ThreadRunner runner) + : name(tname) + , running(false) + , threadRunner(runner) + { + mutex = new Mutex(); + condition = new Conditional(); + common = new Thread::ThreadData(mutex, condition); + } + + Thread::~Thread() + { + #if jin_thread == jin_thread_sdl + #endif + } + + const char* Thread::getName() + { + Lock l(mutex); + return name.c_str(); + }; + + bool Thread::isRunning() + { + Lock l(mutex); + return running; + }; + + bool Thread::start(void* p) + { + Lock l(mutex); + if (running) + return false; + if (handle) + { + #if jin_thread == jin_thread_sdl + SDL_WaitThread(handle, nullptr); + #endif + } + #if jin_thread == jin_thread_sdl + handle = SDL_CreateThread(threadRunner, name.c_str(), p); + #elif jin_thread == jin_thread_cpp + handle = new std::thread(); + #endif + return (running = (handle != nullptr)); + } + + void Thread::wait() + { + { + Lock l(mutex); + if (!handle) + return; + } + #if jin_thread == jin_thread_sdl + SDL_WaitThread(handle, nullptr); + #endif + Lock l(mutex); + running = false; + handle = nullptr; + } + + void Thread::lock() + { + if (mutex != nullptr) + mutex->lock(); + } + + void Thread::unlock() + { + if (mutex != nullptr) + mutex->unlock(); + } + + void Thread::send(int slot, const Variant& value) + { + lock(); + common->set(slot, value); + unlock(); + condition->broadcast(); + } + + bool Thread::receive(int slot) + { + return common->exist(slot); + } + + Thread::Variant Thread::fetch(int slot) + { + Thread::Variant v = common->get(slot); + return v; + } + + Thread::Variant Thread::demand(int slot) + { + /** + * pthread_mutex_lock(mtx); + * while(pass == 0) + * { + * pthread_mutex_unlock(mtx); + * pthread_cond_just_wait(cv); + * pthread_mutex_lock(mtx); + * } + * pthread_mutex_unlock(mtx); + */ + lock(); + while (!common->exist(slot)) + { + if (common->exist(ThreadData::SLOT_ERROR)) + return 0; + condition->wait(mutex); + } + Thread::Variant v = common->get(slot); + unlock(); + return v; + } + + void Thread::remove(int slot) + { + lock(); + common->remove(slot); + unlock(); + } + + } // namespace Threads } // namespace JinEngine #endif // defined(jin_thread)
\ No newline at end of file diff --git a/src/libjin/threads/thread.h b/src/libjin/threads/thread.h index 2b7ee35..6319e38 100644 --- a/src/libjin/threads/thread.h +++ b/src/libjin/threads/thread.h @@ -6,160 +6,160 @@ #include <string> #include <map> #if jin_thread == jin_thread_sdl - #include "SDL2/SDL_thread.h" + #include "SDL2/SDL_thread.h" #elif jin_thread == jin_thread_cpp - #include <thread> - #include <mutex> - #include <condition_variable> + #include <thread> + #include <mutex> + #include <condition_variable> #endif namespace JinEngine { - namespace Threads - { - /** - * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ - * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ - * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz - * һӦûҪ˻ƵԴУꡢСжϴڶеĴ - * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ - * ߣָѣ - */ - class Mutex; - class Conditional; + namespace Threads + { + /** + * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ + * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ + * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz + * һӦûҪ˻ƵԴУꡢСжϴڶеĴ + * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ + * ߣָѣ + */ + class Mutex; + class Conditional; - // - // Thread::demand Receive a message from a thread. Wait for the message to exist before returning. - // Thread::getName Get the name of a thread. - // Thread::kill Forcefully terminate the thread. - // Thread::peek Receive a message from a thread, but leave it in the message box. - // Thread::receive Receive a message from a thread. - // Thread::send Send a message. - // Thread::set Set a value. - // Thread::start Starts the thread. - // Thread::wait Wait for a thread to finish. - // - class Thread - { - public: - struct Variant - { - enum Type - { - NONE = 0, - INTERGER, - BOOLEAN, - CHARACTER, - CSTRING, - POINTER, - REAL, - }; - Type type; - union - { - int integer; - bool boolean; - char character; - const char* cstring; - void* pointer; - float real; - }; - Variant() :type(NONE) {}; - Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); } - Variant(int i) : integer(i), type(INTERGER) {}; - Variant(float f) : real(f), type(REAL) {}; - Variant(bool b) : boolean(b), type(BOOLEAN) {}; - Variant(char c) : character(c), type(CHARACTER) {}; - Variant(const char* s) : cstring(s), type(CSTRING) {}; - Variant(void* p) : pointer(p), type(POINTER) {}; - }; + // + // Thread::demand Receive a message from a thread. Wait for the message to exist before returning. + // Thread::getName Get the name of a thread. + // Thread::kill Forcefully terminate the thread. + // Thread::peek Receive a message from a thread, but leave it in the message box. + // Thread::receive Receive a message from a thread. + // Thread::send Send a message. + // Thread::set Set a value. + // Thread::start Starts the thread. + // Thread::wait Wait for a thread to finish. + // + class Thread + { + public: + struct Variant + { + enum Type + { + NONE = 0, + INTERGER, + BOOLEAN, + CHARACTER, + CSTRING, + POINTER, + REAL, + }; + Type type; + union + { + int integer; + bool boolean; + char character; + const char* cstring; + void* pointer; + float real; + }; + Variant() :type(NONE) {}; + Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); } + Variant(int i) : integer(i), type(INTERGER) {}; + Variant(float f) : real(f), type(REAL) {}; + Variant(bool b) : boolean(b), type(BOOLEAN) {}; + Variant(char c) : character(c), type(CHARACTER) {}; + Variant(const char* s) : cstring(s), type(CSTRING) {}; + Variant(void* p) : pointer(p), type(POINTER) {}; + }; - private: - class ThreadData - { - public: - static const int SLOT_ERROR = -1; - static const int SLOT_WARN = -2; - static const int SLOT_INFO = -3; - static const int SLOT_DEBUG = -4; + private: + class ThreadData + { + public: + static const int SLOT_ERROR = -1; + static const int SLOT_WARN = -2; + static const int SLOT_INFO = -3; + static const int SLOT_DEBUG = -4; - ThreadData(Mutex*, Conditional*); - ~ThreadData(); - bool exist(int slot); - void set(int slot, Variant value); - Variant get(int slot); - void remove(int slot); + ThreadData(Mutex*, Conditional*); + ~ThreadData(); + bool exist(int slot); + void set(int slot, Variant value); + Variant get(int slot); + void remove(int slot); - Conditional* condition; - Mutex* mutex; + Conditional* condition; + Mutex* mutex; - private: - std::map<int, Variant> share; // threads shared value + private: + std::map<int, Variant> share; // threads shared value - }; + }; - public: - typedef int(*ThreadRunner)(void* obj); + public: + typedef int(*ThreadRunner)(void* obj); - Thread(const std::string name, ThreadRunner threadfuncs); - ~Thread(); - bool start(void* p); - void wait(); - void send(int slot, const Variant& value); - bool receive(int slot); - Variant fetch(int slot); - Variant demand(int slot); - void remove(int slot); - const char* getName(); - bool isRunning(); - void lock(); - void unlock(); + Thread(const std::string name, ThreadRunner threadfuncs); + ~Thread(); + bool start(void* p); + void wait(); + void send(int slot, const Variant& value); + bool receive(int slot); + Variant fetch(int slot); + Variant demand(int slot); + void remove(int slot); + const char* getName(); + bool isRunning(); + void lock(); + void unlock(); - protected: - #if jin_thread == jin_thread_sdl - SDL_Thread* handle; // SDL thread - #elif jin_thread == jin_thread_cpp - std::thread* handle; // cpp thread - #endif - Mutex* mutex; // mutex variable - Conditional* condition; // condition variable - ThreadRunner threadRunner; // thread function - ThreadData* common; // threads common data - const std::string name; // thread name, for debugging purposes - /** - * https://stackoverflow.com/questions/149932/naming-conventions-for-threads - * - * Use short names because they don't make the lines in a log file too long. - * - * Create names where the important part is at the beginning. Log viewers in a - * graphical user interface tend to have tables with columns, and the thread - * column is usually small or will be made small by you to read everything else. - * - * Do not use the word "thread" in the thread name because it is obvious. - * - * Make the thread names easily grep-able. Avoid similar sounding thread names - * - * If you have several threads of the same nature, enumerate them with IDs that - * are unique to one execution of the application or one log file, whichever fits - * your logging habits. - * - * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker - * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or - * "Calculation" (what does it calculate?). - * - * If you have a test group that uses thread names to grep your application's log - * files, do not rename your threads after some time. Your testers will hate you for - * doing so. Thread names in well-tested applications should be there to stay. - * - * When you have threads that service a network connection, try to include the target - * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about - * enumeration though if there are multiple connections to the same host. - */ - bool running; // running + protected: + #if jin_thread == jin_thread_sdl + SDL_Thread* handle; // SDL thread + #elif jin_thread == jin_thread_cpp + std::thread* handle; // cpp thread + #endif + Mutex* mutex; // mutex variable + Conditional* condition; // condition variable + ThreadRunner threadRunner; // thread function + ThreadData* common; // threads common data + const std::string name; // thread name, for debugging purposes + /** + * https://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * Use short names because they don't make the lines in a log file too long. + * + * Create names where the important part is at the beginning. Log viewers in a + * graphical user interface tend to have tables with columns, and the thread + * column is usually small or will be made small by you to read everything else. + * + * Do not use the word "thread" in the thread name because it is obvious. + * + * Make the thread names easily grep-able. Avoid similar sounding thread names + * + * If you have several threads of the same nature, enumerate them with IDs that + * are unique to one execution of the application or one log file, whichever fits + * your logging habits. + * + * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker + * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or + * "Calculation" (what does it calculate?). + * + * If you have a test group that uses thread names to grep your application's log + * files, do not rename your threads after some time. Your testers will hate you for + * doing so. Thread names in well-tested applications should be there to stay. + * + * When you have threads that service a network connection, try to include the target + * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about + * enumeration though if there are multiple connections to the same host. + */ + bool running; // running - }; + }; - } // namespace Threads + } // namespace Threads } // namespace JinEngine #endif // defined(jin_thread) diff --git a/src/libjin/time/timer.cpp b/src/libjin/time/timer.cpp index 32b2f57..a20e46b 100644 --- a/src/libjin/time/timer.cpp +++ b/src/libjin/time/timer.cpp @@ -5,120 +5,120 @@ namespace JinEngine { - namespace Time - { - - - Timer::Timer() - : mHandlers() - { - } - - Timer::~Timer() - { - for (int i = 0; i < mHandlers.size(); ++i) - delete mHandlers[i]; - } - - void Timer::update(float dt) - { - // Process handler. - std::vector<Handler*>::iterator it = mHandlers.begin(); - for (; it != mHandlers.end(); ++it) - (*it)->process(dt); - // Erase canceled handler. - for (it = mHandlers.begin(); it != mHandlers.end();) - { - if ((*it)->canceled) - { - Handler* h = *it; - it = mHandlers.erase(it); - delete h; - } - else - ++it; - } - } - - void Timer::cancel(Handler* handler) - { - if(handler != nullptr) - handler->canceled = true; - } - - void Timer::cancelAll() - { - for (auto h : mHandlers) - cancel(h); - } - - Timer::Handler* Timer::every(float dt, TimerCallback callback, void* p, FinishCallback finish) - { - Handler* t = new Handler(Handler::EVERY, dt, 0, callback, p, finish); - mHandlers.push_back(t); - return t; - } - - Timer::Handler* Timer::after(float dt, TimerCallback callback, void* p, FinishCallback finish) - { - Handler* t = new Handler(Handler::AFTER, dt, 0, callback, p, finish); - mHandlers.push_back(t); - return t; - } - - Timer::Handler* Timer::repeat(float dt, int count, TimerCallback callback, void* p, FinishCallback finish) - { - Handler* t = new Handler(Handler::REPEAT, dt, count, callback, p, finish); - mHandlers.push_back(t); - return t; - } - - Timer::Handler::Handler(Type t, float d, int c, TimerCallback f, void* p, FinishCallback finishcallback) - : type(t) - , duration(d) - , count(c) - , tickdown(d) - , countdown(c) - , callback(f) - , paramters(p) - , canceled(false) - , finishCallback(finishcallback) - { - } - - Timer::Handler::~Handler() - { - if (finishCallback != nullptr) - finishCallback(paramters); - } - - void Timer::Handler::process(float dt) - { - tickdown -= dt; - if (tickdown <= 0) - { - tickdown += duration; - if (!canceled && callback != nullptr) - callback(paramters); - if (type == EVERY) - { - } - else if (type == AFTER) - { - canceled = true; - } - else if (type == REPEAT) - { - --countdown; - if (countdown <= 0) - canceled = true; - } - } - } - - float deltaTime = 0; - - } // namespace Time + namespace Time + { + + + Timer::Timer() + : mHandlers() + { + } + + Timer::~Timer() + { + for (int i = 0; i < mHandlers.size(); ++i) + delete mHandlers[i]; + } + + void Timer::update(float dt) + { + // Process handler. + std::vector<Handler*>::iterator it = mHandlers.begin(); + for (; it != mHandlers.end(); ++it) + (*it)->process(dt); + // Erase canceled handler. + for (it = mHandlers.begin(); it != mHandlers.end();) + { + if ((*it)->canceled) + { + Handler* h = *it; + it = mHandlers.erase(it); + delete h; + } + else + ++it; + } + } + + void Timer::cancel(Handler* handler) + { + if(handler != nullptr) + handler->canceled = true; + } + + void Timer::cancelAll() + { + for (auto h : mHandlers) + cancel(h); + } + + Timer::Handler* Timer::every(float dt, TimerCallback callback, void* p, FinishCallback finish) + { + Handler* t = new Handler(Handler::EVERY, dt, 0, callback, p, finish); + mHandlers.push_back(t); + return t; + } + + Timer::Handler* Timer::after(float dt, TimerCallback callback, void* p, FinishCallback finish) + { + Handler* t = new Handler(Handler::AFTER, dt, 0, callback, p, finish); + mHandlers.push_back(t); + return t; + } + + Timer::Handler* Timer::repeat(float dt, int count, TimerCallback callback, void* p, FinishCallback finish) + { + Handler* t = new Handler(Handler::REPEAT, dt, count, callback, p, finish); + mHandlers.push_back(t); + return t; + } + + Timer::Handler::Handler(Type t, float d, int c, TimerCallback f, void* p, FinishCallback finishcallback) + : type(t) + , duration(d) + , count(c) + , tickdown(d) + , countdown(c) + , callback(f) + , paramters(p) + , canceled(false) + , finishCallback(finishcallback) + { + } + + Timer::Handler::~Handler() + { + if (finishCallback != nullptr) + finishCallback(paramters); + } + + void Timer::Handler::process(float dt) + { + tickdown -= dt; + if (tickdown <= 0) + { + tickdown += duration; + if (!canceled && callback != nullptr) + callback(paramters); + if (type == EVERY) + { + } + else if (type == AFTER) + { + canceled = true; + } + else if (type == REPEAT) + { + --countdown; + if (countdown <= 0) + canceled = true; + } + } + } + + float deltaTime = 0; + + } // namespace Time } // namespace JinEngine #endif // defined(jin_time)
\ No newline at end of file diff --git a/src/libjin/time/timer.h b/src/libjin/time/timer.h index 48e51ba..e742112 100644 --- a/src/libjin/time/timer.h +++ b/src/libjin/time/timer.h @@ -12,145 +12,145 @@ namespace JinEngine { - namespace Time - { - - /// - /// - /// - class Timer : public Object - { - public: - - typedef std::function<void(void*)> TimerCallback; - - typedef std::function<void(void*)> FinishCallback; - - /// - /// - /// - class Handler : public Object - { - public: - friend class Timer; - enum Type - { - EVERY, - AFTER, - REPEAT, - }; - Handler(Type type, float duration, int count = 0, TimerCallback callback = nullptr, void* paramters = nullptr, FinishCallback finishcallback = nullptr); - virtual ~Handler(); - void process(float dt); - - protected: - int count; - int countdown; - float duration; - float tickdown; - Type type; - TimerCallback callback; - FinishCallback finishCallback; - void* paramters; - bool canceled; - }; - - /// - /// - /// - Timer(); - - /// - /// - /// - ~Timer(); - - /// - /// - /// - void update(float dt); - - /// - /// - /// - Handler* every(float dt, TimerCallback callback, void* paramters = nullptr, FinishCallback finish = nullptr); - - /// - /// - /// - Handler* after(float dt, TimerCallback callback, void* paramters, FinishCallback finish); - - /// - /// - /// - Handler* repeat(float dt, int count, TimerCallback callback, void* paramters, FinishCallback finish); - - /// - /// - /// - void cancel(Handler* handler); - - /// - /// - /// - void cancelAll(); - - private: - - std::vector<Handler*> mHandlers; - - }; - - /// - /// - /// - inline void sleep(int ms) - { - #if jin_time == jin_time_sdl - SDL_Delay(ms); - #endif - } - - /// - /// - /// - inline double getSecond() - { - #if jin_time == jin_time_sdl - return SDL_GetTicks() / 1000.f; - #endif - } - - /// - /// - /// - inline double getMilliSecond() - { - #if jin_time == jin_time_sdl - return SDL_GetTicks(); - #endif - } - - /// - /// Delta time between frames. - /// - extern float deltaTime; - - inline void step() - { - static float previous = 0; - static float current = getSecond(); - previous = current; - current = getSecond(); - deltaTime = current - previous; - } - - inline float getDeltaTime() - { - return deltaTime; - } - - } // namespace Time + namespace Time + { + + /// + /// + /// + class Timer : public Object + { + public: + + typedef std::function<void(void*)> TimerCallback; + + typedef std::function<void(void*)> FinishCallback; + + /// + /// + /// + class Handler : public Object + { + public: + friend class Timer; + enum Type + { + EVERY, + AFTER, + REPEAT, + }; + Handler(Type type, float duration, int count = 0, TimerCallback callback = nullptr, void* paramters = nullptr, FinishCallback finishcallback = nullptr); + virtual ~Handler(); + void process(float dt); + + protected: + int count; + int countdown; + float duration; + float tickdown; + Type type; + TimerCallback callback; + FinishCallback finishCallback; + void* paramters; + bool canceled; + }; + + /// + /// + /// + Timer(); + + /// + /// + /// + ~Timer(); + + /// + /// + /// + void update(float dt); + + /// + /// + /// + Handler* every(float dt, TimerCallback callback, void* paramters = nullptr, FinishCallback finish = nullptr); + + /// + /// + /// + Handler* after(float dt, TimerCallback callback, void* paramters, FinishCallback finish); + + /// + /// + /// + Handler* repeat(float dt, int count, TimerCallback callback, void* paramters, FinishCallback finish); + + /// + /// + /// + void cancel(Handler* handler); + + /// + /// + /// + void cancelAll(); + + private: + + std::vector<Handler*> mHandlers; + + }; + + /// + /// + /// + inline void sleep(int ms) + { + #if jin_time == jin_time_sdl + SDL_Delay(ms); + #endif + } + + /// + /// + /// + inline double getSecond() + { + #if jin_time == jin_time_sdl + return SDL_GetTicks() / 1000.f; + #endif + } + + /// + /// + /// + inline double getMilliSecond() + { + #if jin_time == jin_time_sdl + return SDL_GetTicks(); + #endif + } + + /// + /// Delta time between frames. + /// + extern float deltaTime; + + inline void step() + { + static float previous = 0; + static float current = getSecond(); + previous = current; + current = getSecond(); + deltaTime = current - previous; + } + + inline float getDeltaTime() + { + return deltaTime; + } + + } // namespace Time } // namespace JinEngine #endif // defined(jin_time) diff --git a/src/libjin/utils/endian.h b/src/libjin/utils/endian.h index db8c8fd..ee22775 100644 --- a/src/libjin/utils/endian.h +++ b/src/libjin/utils/endian.h @@ -11,10 +11,10 @@ #define jin_byte_order __BYTE_ORDER #else /* __linux__ */ #if defined(__hppa__) || \ - defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ - (defined(__MIPS__) && defined(__MISPEB__)) || \ - defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ - defined(__sparc__) + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MISPEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__sparc__) #define jin_byte_order jin_endian_big #else #define jin_byte_order jin_endian_lil diff --git a/src/libjin/utils/log.cpp b/src/libjin/utils/log.cpp index 560afa8..ad9d793 100644 --- a/src/libjin/utils/log.cpp +++ b/src/libjin/utils/log.cpp @@ -9,73 +9,73 @@ std::ofstream Loghelper::fs; void Loghelper::log(Level _level, const char* _fmt, ...) { - if (!hasbit(levels, _level)) - return; + if (!hasbit(levels, _level)) + return; #define FORMAT_MSG_BUFFER_SIZE (204800) - const char* levelStr = nullptr; - switch (_level) - { - case LV_ERROR: - levelStr = "[Jin Error]: "; - break; - case LV_WARNING: - levelStr = "[Jin Warning]: "; - break; - case LV_INFO: - levelStr = "[Jin Info]: "; - break; - case LV_DEBUG: - levelStr = "[Jin Debug]: "; - break; - default: - levelStr = "[Jin Unknow]: "; - break; - } - char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; - strcpy(buffer, levelStr); - va_list args; - va_start(args, _fmt); - vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); - va_end(args); - if (hasbit(dir, DIR_CERR)) - { - std::cerr << buffer << std::endl; - } - if (hasbit(dir, DIR_FILE)) - { - fs << buffer << std::endl; - } + const char* levelStr = nullptr; + switch (_level) + { + case LV_ERROR: + levelStr = "[Jin Error]: "; + break; + case LV_WARNING: + levelStr = "[Jin Warning]: "; + break; + case LV_INFO: + levelStr = "[Jin Info]: "; + break; + case LV_DEBUG: + levelStr = "[Jin Debug]: "; + break; + default: + levelStr = "[Jin Unknow]: "; + break; + } + char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; + strcpy(buffer, levelStr); + va_list args; + va_start(args, _fmt); + vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); + va_end(args); + if (hasbit(dir, DIR_CERR)) + { + std::cerr << buffer << std::endl; + } + if (hasbit(dir, DIR_FILE)) + { + fs << buffer << std::endl; + } #undef FORMAT_MSG_BUFFER_SIZE } // ض void Loghelper::redirect(unsigned int _dir, char* _path) { - dir = _dir; - if (hasbit(dir, DIR_FILE)) - { - try - { - fs.open(_path, std::ios_base::app); - } - catch (std::ios_base::failure& e) { - dir = DIR_CERR; - log(Level::LV_WARNING, "ضlog· %s ʧ", _path); - } - } + dir = _dir; + if (hasbit(dir, DIR_FILE)) + { + try + { + fs.open(_path, std::ios_base::app); + } + catch (std::ios_base::failure& e) { + dir = DIR_CERR; + log(Level::LV_WARNING, "ضlog· %s ʧ", _path); + } + } } // ɸѡȼ void Loghelper::restrict(unsigned int _levels) { - levels = _levels; + levels = _levels; } void Loghelper::close() { - if (!fs.fail()) - fs.close(); - fs.clear(); + if (!fs.fail()) + fs.close(); + fs.clear(); } #undef hasbit diff --git a/src/libjin/utils/log.h b/src/libjin/utils/log.h index 11b4897..961df7a 100644 --- a/src/libjin/utils/log.h +++ b/src/libjin/utils/log.h @@ -11,52 +11,52 @@ class Loghelper { public: - // logĿ - enum Direction - { - DIR_CERR = 1 << 1, // - DIR_FILE = 1 << 2, // logļ - }; - - // ȼ - enum Level - { - LV_NONE = 0, // none - LV_ERROR = 1 << 1, // error - LV_WARNING = 1 << 2, // warn - LV_INFO = 1 << 3, // info - LV_DEBUG = 1 << 4, // debug - LV_ALL = 0xffffffff - }; - - static void log(Level _level, const char* _fmt, ...); - - // ض - static void redirect(unsigned int _dir, char* _path = nullptr); - - // ɸѡȼ - static void restrict(unsigned int levels); - - static void close(); + // logĿ + enum Direction + { + DIR_CERR = 1 << 1, // + DIR_FILE = 1 << 2, // logļ + }; + + // ȼ + enum Level + { + LV_NONE = 0, // none + LV_ERROR = 1 << 1, // error + LV_WARNING = 1 << 2, // warn + LV_INFO = 1 << 3, // info + LV_DEBUG = 1 << 4, // debug + LV_ALL = 0xffffffff + }; + + static void log(Level _level, const char* _fmt, ...); + + // ض + static void redirect(unsigned int _dir, char* _path = nullptr); + + // ɸѡȼ + static void restrict(unsigned int levels); + + static void close(); private: - static unsigned int dir; // Ŀ - static unsigned int levels; // ȼ - static std::ofstream fs; // ļ + static unsigned int dir; // Ŀ + static unsigned int levels; // ȼ + static std::ofstream fs; // ļ }; typedef Loghelper::Level Loglevel; #if defined(jin_debug) - #define jin_log_error(f, ...) Loghelper::log(Loghelper::LV_ERROR, f, __VA_ARGS__) - #define jin_log_info(f, ...) Loghelper::log(Loghelper::LV_INFO, f, __VA_ARGS__) - #define jin_log_warning(f, ...) Loghelper::log(Loghelper::LV_WARNING, f, __VA_ARGS__) - #define jin_log_debug(f, ...) Loghelper::log(Loghelper::LV_DEBUG, f, __VA_ARGS__) + #define jin_log_error(f, ...) Loghelper::log(Loghelper::LV_ERROR, f, __VA_ARGS__) + #define jin_log_info(f, ...) Loghelper::log(Loghelper::LV_INFO, f, __VA_ARGS__) + #define jin_log_warning(f, ...) Loghelper::log(Loghelper::LV_WARNING, f, __VA_ARGS__) + #define jin_log_debug(f, ...) Loghelper::log(Loghelper::LV_DEBUG, f, __VA_ARGS__) #else - #define jin_log_error(f, ...) - #define jin_log_info(f, ...) - #define jin_log_warning(f, ...) - #define jin_log_debug(f, ...) + #define jin_log_error(f, ...) + #define jin_log_info(f, ...) + #define jin_log_warning(f, ...) + #define jin_log_debug(f, ...) #endif #endif // __LOG_H__ELPER_H__
\ No newline at end of file diff --git a/src/libjin/utils/macros.h b/src/libjin/utils/macros.h index 6e4e7a9..d807a91 100644 --- a/src/libjin/utils/macros.h +++ b/src/libjin/utils/macros.h @@ -8,7 +8,7 @@ // //#define MASK // enum // -//#define onlyonce // ֻһ +//#define onlyonce // ֻһ //#define CALLONCE(call) static char __dummy__=(call, 1) // ֻһ //#define SAFECALL(func, params) if(func) func(params) // diff --git a/src/libjin/utils/unittest.cpp b/src/libjin/utils/unittest.cpp index 83af6ce..4ab598a 100644 --- a/src/libjin/utils/unittest.cpp +++ b/src/libjin/utils/unittest.cpp @@ -12,21 +12,21 @@ using namespace std; int main(int argc, char* argv[]) { - SDLAudio* audio = SDLAudio::get(); - audio->init(0); - SDLSource* source = SDLSource::createSource("a.ogg"); - SDLSource* source2 = SDLSource::createSource("a.wav"); - //source->play(); - source2->play(); - source->setLoop(true); - source2->setLoop(true); - int i = 0; - while (true) - { - SDL_Delay(1000); - } - audio->quit(); - return 0; + SDLAudio* audio = SDLAudio::get(); + audio->init(0); + SDLSource* source = SDLSource::createSource("a.ogg"); + SDLSource* source2 = SDLSource::createSource("a.wav"); + //source->play(); + source2->play(); + source->setLoop(true); + source2->setLoop(true); + int i = 0; + while (true) + { + SDL_Delay(1000); + } + audio->quit(); + return 0; } /* @@ -40,68 +40,68 @@ int main(int argc, char* argv[]) static SDL_mutex* audio_mutex; static void lock_handler(cm_Event *e) { - if (e->type == CM_EVENT_LOCK) { - SDL_LockMutex(audio_mutex); - } - if (e->type == CM_EVENT_UNLOCK) { - SDL_UnlockMutex(audio_mutex); - } + if (e->type == CM_EVENT_LOCK) { + SDL_LockMutex(audio_mutex); + } + if (e->type == CM_EVENT_UNLOCK) { + SDL_UnlockMutex(audio_mutex); + } } static void audio_callback(void *udata, Uint8 *stream, int size) { - cm_process((cm_Int16*)stream, size / 2); + cm_process((cm_Int16*)stream, size / 2); } int main(int argc, char **argv) { - SDL_AudioDeviceID dev; - SDL_AudioSpec fmt, got; - cm_Source *src; - cm_Source* src2; + SDL_AudioDeviceID dev; + SDL_AudioSpec fmt, got; + cm_Source *src; + cm_Source* src2; - SDL_Init(SDL_INIT_AUDIO); - audio_mutex = SDL_CreateMutex(); + SDL_Init(SDL_INIT_AUDIO); + audio_mutex = SDL_CreateMutex(); - memset(&fmt, 0, sizeof(fmt)); - fmt.freq = 44100; - fmt.format = AUDIO_S16; - fmt.channels = 2; - fmt.samples = 1024; - fmt.callback = audio_callback; + memset(&fmt, 0, sizeof(fmt)); + fmt.freq = 44100; + fmt.format = AUDIO_S16; + fmt.channels = 2; + fmt.samples = 1024; + fmt.callback = audio_callback; - dev = SDL_OpenAudioDevice(NULL, 0, &fmt, &got, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); - if (dev == 0) { - fprintf(stderr, "Error: failed to open audio device '%s'\n", SDL_GetError()); - exit(EXIT_FAILURE); - } + dev = SDL_OpenAudioDevice(NULL, 0, &fmt, &got, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); + if (dev == 0) { + fprintf(stderr, "Error: failed to open audio device '%s'\n", SDL_GetError()); + exit(EXIT_FAILURE); + } - cm_init(got.freq); - cm_set_lock(lock_handler); - cm_set_master_gain(0.5); + cm_init(got.freq); + cm_set_lock(lock_handler); + cm_set_master_gain(0.5); - SDL_PauseAudioDevice(dev, 0); + SDL_PauseAudioDevice(dev, 0); - src = cm_new_source_from_file("a.ogg"); - src2 = cm_new_source_from_file("loop.wav"); - if (!src) { - fprintf(stderr, "Error: failed to create source '%s'\n", cm_get_error()); - exit(EXIT_FAILURE); - } - cm_set_loop(src2, 1); + src = cm_new_source_from_file("a.ogg"); + src2 = cm_new_source_from_file("loop.wav"); + if (!src) { + fprintf(stderr, "Error: failed to create source '%s'\n", cm_get_error()); + exit(EXIT_FAILURE); + } + cm_set_loop(src2, 1); - cm_play(src); - cm_play(src2); + cm_play(src); + cm_play(src2); - printf("Press [return] to exit\n"); - getchar(); + printf("Press [return] to exit\n"); + getchar(); - cm_destroy_source(src); - SDL_CloseAudioDevice(dev); - SDL_Quit(); + cm_destroy_source(src); + SDL_CloseAudioDevice(dev); + SDL_Quit(); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } */ |