From 18e44dc835570753395d2737e51143fbf93f2417 Mon Sep 17 00:00:00 2001 From: kearwood Date: Sat, 13 Jul 2013 13:18:25 -0700 Subject: [PATCH 01/43] start nfb branch --HG-- branch : nfb From 14b6a2f56ce494ec4a119e7ab5ba3e529774f8d5 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 27 Jul 2013 14:57:50 -0700 Subject: [PATCH 02/43] Fixed an issue that caused some textures to be unloaded permanently when streaming a world. This manifested itself in cases where a texture unit would hold only a single texture for many frames, such as in scenes where only one object had a normal map in view. --HG-- branch : nfb --- KREngine/kraken/KRTextureManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index e6fb8f5..c81d104 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -63,6 +63,7 @@ void KRTextureManager::_clearGLState() m_wrapModeS[i] = 0; m_wrapModeT[i] = 0; m_maxAnisotropy[i] = -1.0f; + selectTexture(i, NULL); } m_iActiveTexture = -1; From 0300dcdd7e3e1a1d15eee0287e276844d7a2f67c Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 24 Aug 2013 16:37:07 -0700 Subject: [PATCH 03/43] Implemented animation splitting --HG-- branch : nfb --- KREngine/kraken/KRAnimation.cpp | 82 ++++++++++++++++++++- KREngine/kraken/KRAnimation.h | 7 ++ KREngine/kraken/KRAnimationAttribute.cpp | 10 +++ KREngine/kraken/KRAnimationAttribute.h | 2 + KREngine/kraken/KRAnimationCurve.cpp | 43 ++++++++++- KREngine/kraken/KRAnimationCurve.h | 5 ++ KREngine/kraken/KRAnimationCurveManager.cpp | 5 ++ KREngine/kraken/KRAnimationCurveManager.h | 2 + KREngine/kraken/KRAnimationManager.cpp | 9 +++ KREngine/kraken/KRAnimationManager.h | 1 + 10 files changed, 162 insertions(+), 4 deletions(-) diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index 47ea76b..1be1203 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -28,7 +28,8 @@ // authors and should not be interpreted as representing official policies, either expressed // or implied, of Kearwood Gilbert. // - +#include +#include #include "KRAnimation.h" #include "KRAnimationManager.h" #include "KRContext.h" @@ -44,6 +45,7 @@ KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(cont m_playing = false; m_local_time = 0.0f; m_duration = 0.0f; + m_start_time = 0.0f; } KRAnimation::~KRAnimation() { @@ -68,6 +70,7 @@ bool KRAnimation::save(KRDataBlock &data) { animation_node->SetAttribute("loop", m_loop ? "true" : "false"); animation_node->SetAttribute("auto_play", m_auto_play ? "true" : "false"); animation_node->SetAttribute("duration", m_duration); + animation_node->SetAttribute("start_time", m_start_time); for(unordered_map::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){ (*itr).second->saveXML(animation_node); @@ -93,6 +96,10 @@ KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDa new_animation->m_duration = 0.0f; // Default value } + if(animation_node->QueryFloatAttribute("start_time", &new_animation->m_start_time) != tinyxml2::XML_SUCCESS) { + new_animation->m_start_time = 0.0f; // Default value + } + if(animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) { new_animation->m_loop = false; // Default value } @@ -157,9 +164,9 @@ void KRAnimation::update(float deltaTime) KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute(); if(curve != NULL && target != NULL) { - int frame_number = (int)(m_local_time * curve->getFrameRate()); + int frame_number = (int)((m_local_time + m_start_time) * curve->getFrameRate()); if(frame_number < curve->getFrameStart()) { - target->SetAttribute(attribute_type, curve->getValue(0)); + target->SetAttribute(attribute_type, curve->getValue(m_start_time)); } else if(frame_number - curve->getFrameStart() >= curve->getFrameCount()) { target->SetAttribute(attribute_type, curve->getValue(curve->getFrameCount() - 1)); } else { @@ -203,6 +210,16 @@ void KRAnimation::setDuration(float duration) m_duration = duration; } +float KRAnimation::getStartTime() +{ + return m_start_time; +} + +void KRAnimation::setStartTime(float start_time) +{ + m_start_time = start_time; +} + bool KRAnimation::isPlaying() { return m_playing; @@ -227,3 +244,62 @@ void KRAnimation::setLooping(bool looping) { m_loop = looping; } + +KRAnimation *KRAnimation::split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes, bool clone_curves) +{ + KRAnimation *new_animation = new KRAnimation(getContext(), name); + new_animation->setStartTime(start_time); + new_animation->setDuration(duration); + new_animation->m_loop = m_loop; + new_animation->m_auto_play = m_auto_play; + int new_curve_count = 0; + for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer *layer = (*layer_itr).second; + KRAnimationLayer *new_layer = new KRAnimationLayer(getContext()); + new_layer->setName(layer->getName()); + new_layer->setRotationAccumulationMode(layer->getRotationAccumulationMode()); + new_layer->setScaleAccumulationMode(layer->getScaleAccumulationMode()); + new_layer->setWeight(layer->getWeight()); + new_animation->m_layers[new_layer->getName()] = new_layer; + for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute *attribute = *attribute_itr; + KRAnimationCurve *curve = attribute->getCurve(); + if(curve != NULL) { + bool include_attribute = true; + if(strip_unchanging_attributes) { + if(!curve->valueChanges(start_time, duration)) { + include_attribute = false; + } + } + + if(include_attribute) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(getContext()); + KRAnimationCurve *new_curve = curve; + if(clone_curves) { + std::string new_curve_name = name + "_curve" + boost::lexical_cast(++new_curve_count); + new_curve = curve->split(new_curve_name, start_time, duration); + } + + new_attribute->setCurveName(new_curve->getName()); + new_attribute->setTargetName(attribute->getTargetName()); + new_layer->addAttribute(new_attribute); + } + } + } + } + + getContext().getAnimationManager()->addAnimation(new_animation); + return new_animation; +} + +void KRAnimation::deleteCurves() +{ + for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer *layer = (*layer_itr).second; + for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute *attribute = *attribute_itr; + attribute->deleteCurve(); + } + } +} + diff --git a/KREngine/kraken/KRAnimation.h b/KREngine/kraken/KRAnimation.h index 38166a6..a052177 100644 --- a/KREngine/kraken/KRAnimation.h +++ b/KREngine/kraken/KRAnimation.h @@ -64,7 +64,13 @@ public: void setTime(float time); float getDuration(); void setDuration(float duration); + float getStartTime(); + void setStartTime(float start_time); bool isPlaying(); + + KRAnimation *split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes = true, bool clone_curves = true); + void deleteCurves(); + private: unordered_map m_layers; bool m_auto_play; @@ -72,6 +78,7 @@ private: bool m_playing; float m_local_time; float m_duration; + float m_start_time; }; diff --git a/KREngine/kraken/KRAnimationAttribute.cpp b/KREngine/kraken/KRAnimationAttribute.cpp index 48d3943..9133f6a 100644 --- a/KREngine/kraken/KRAnimationAttribute.cpp +++ b/KREngine/kraken/KRAnimationAttribute.cpp @@ -152,6 +152,8 @@ void KRAnimationAttribute::loadXML(tinyxml2::XMLElement *e) m_curve = NULL; m_curve_name = e->Attribute("curve"); m_target_name = e->Attribute("target"); + + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; const char *szAttribute = e->Attribute("attribute"); @@ -267,4 +269,12 @@ KRAnimationCurve *KRAnimationAttribute::getCurve() return m_curve; } +void KRAnimationAttribute::deleteCurve() +{ + KRAnimationCurve *curve = getCurve(); + if(curve) { + getContext().getAnimationCurveManager()->deleteAnimationCurve(curve); + m_curve = NULL; + } +} diff --git a/KREngine/kraken/KRAnimationAttribute.h b/KREngine/kraken/KRAnimationAttribute.h index 7ddcfb8..6a4f695 100644 --- a/KREngine/kraken/KRAnimationAttribute.h +++ b/KREngine/kraken/KRAnimationAttribute.h @@ -58,6 +58,8 @@ public: KRNode *getTarget(); KRAnimationCurve *getCurve(); + void deleteCurve(); + private: std::string m_target_name; std::string m_curve_name; diff --git a/KREngine/kraken/KRAnimationCurve.cpp b/KREngine/kraken/KRAnimationCurve.cpp index a1abbd7..b85ad15 100644 --- a/KREngine/kraken/KRAnimationCurve.cpp +++ b/KREngine/kraken/KRAnimationCurve.cpp @@ -29,6 +29,7 @@ // or implied, of Kearwood Gilbert. // +#include "KRContext.h" #include "KRAnimationCurve.h" #include "KRDataBlock.h" @@ -48,7 +49,6 @@ KRAnimationCurve::~KRAnimationCurve() m_pData->unload(); delete m_pData; } - bool KRAnimationCurve::load(KRDataBlock *data) { m_pData->unload(); @@ -152,3 +152,44 @@ float KRAnimationCurve::getValue(float local_time) return getValue((int)(local_time * getFrameRate())); } +bool KRAnimationCurve::valueChanges(float start_time, float duration) +{ + return valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); +} + +bool KRAnimationCurve::valueChanges(int start_frame, int frame_count) +{ + + float first_value = getValue(start_frame); + + // Range of frames is not inclusive of last frame + for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count; frame_number++) { + if(getValue(frame_number) != first_value) { + return true; + } + } + + return false; +} + +KRAnimationCurve *KRAnimationCurve::split(const std::string &name, float start_time, float duration) +{ + return split(name, (int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); +} + +KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_frame, int frame_count) +{ + KRAnimationCurve *new_curve = new KRAnimationCurve(getContext(), name); + + new_curve->setFrameRate(getFrameRate()); + new_curve->setFrameStart(start_frame); + new_curve->setFrameCount(frame_count); + + // Range of frames is not inclusive of last frame + for(int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) { + new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here? + } + + getContext().getAnimationCurveManager()->addAnimationCurve(new_curve); + return new_curve; +} diff --git a/KREngine/kraken/KRAnimationCurve.h b/KREngine/kraken/KRAnimationCurve.h index 3b4f334..ff5309c 100644 --- a/KREngine/kraken/KRAnimationCurve.h +++ b/KREngine/kraken/KRAnimationCurve.h @@ -61,6 +61,11 @@ public: static KRAnimationCurve *Load(KRContext &context, const std::string &name, KRDataBlock *data); + bool valueChanges(float start_time, float duration); + bool valueChanges(int start_frame, int frame_count); + + KRAnimationCurve *split(const std::string &name, float start_time, float duration); + KRAnimationCurve *split(const std::string &name, int start_frame, int frame_count); private: KRDataBlock *m_pData; diff --git a/KREngine/kraken/KRAnimationCurveManager.cpp b/KREngine/kraken/KRAnimationCurveManager.cpp index 017b13a..548d378 100644 --- a/KREngine/kraken/KRAnimationCurveManager.cpp +++ b/KREngine/kraken/KRAnimationCurveManager.cpp @@ -43,6 +43,11 @@ KRAnimationCurveManager::~KRAnimationCurveManager() { } } +void KRAnimationCurveManager::deleteAnimationCurve(KRAnimationCurve *curve) { + m_animationCurves.erase(curve->getName()); + delete curve; +} + KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const std::string &name, KRDataBlock *data) { KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data); m_animationCurves[name] = pAnimationCurve; diff --git a/KREngine/kraken/KRAnimationCurveManager.h b/KREngine/kraken/KRAnimationCurveManager.h index b2a007c..4d59be2 100644 --- a/KREngine/kraken/KRAnimationCurveManager.h +++ b/KREngine/kraken/KRAnimationCurveManager.h @@ -50,6 +50,8 @@ public: void addAnimationCurve(KRAnimationCurve *new_animation_curve); unordered_map &getAnimationCurves(); + void deleteAnimationCurve(KRAnimationCurve *curve); + private: unordered_map m_animationCurves; }; diff --git a/KREngine/kraken/KRAnimationManager.cpp b/KREngine/kraken/KRAnimationManager.cpp index e55c166..76224e7 100644 --- a/KREngine/kraken/KRAnimationManager.cpp +++ b/KREngine/kraken/KRAnimationManager.cpp @@ -100,3 +100,12 @@ void KRAnimationManager::updateActiveAnimations(KRAnimation *animation) m_animationsToUpdate.insert(animation); } +void KRAnimationManager::deleteAnimation(KRAnimation *animation, bool delete_curves) +{ + if(delete_curves) + { + animation->deleteCurves(); + } + m_animations.erase(animation->getName()); + delete animation; +} diff --git a/KREngine/kraken/KRAnimationManager.h b/KREngine/kraken/KRAnimationManager.h index 6456d65..34a06f0 100644 --- a/KREngine/kraken/KRAnimationManager.h +++ b/KREngine/kraken/KRAnimationManager.h @@ -49,6 +49,7 @@ public: KRAnimation *getAnimation(const char *szName); void addAnimation(KRAnimation *new_animation); unordered_map &getAnimations(); + void deleteAnimation(KRAnimation *animation, bool delete_curves); void startFrame(float deltaTime); void endFrame(float deltaTime); From 0cb3db427dada83d5bc42e2f8cd347001df0eda6 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 24 Aug 2013 17:04:20 -0700 Subject: [PATCH 04/43] Fixed bug in animation import that caused the attributes to be un-assigned to nodes. --HG-- branch : nfb --- KREngine/kraken/KRAnimation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index 1be1203..093ef13 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -281,6 +281,7 @@ KRAnimation *KRAnimation::split(const std::string &name, float start_time, float } new_attribute->setCurveName(new_curve->getName()); + new_attribute->setTargetAttribute(attribute->getTargetAttribute()); new_attribute->setTargetName(attribute->getTargetName()); new_layer->addAttribute(new_attribute); } From b67ae221cdd1ce944eed3717703fa2be24fc9af7 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 31 Aug 2013 15:31:17 -0700 Subject: [PATCH 05/43] Fixed bug in animation splitting that would cause curves that don't start at frame 0 to be offset incorrectly --HG-- branch : nfb --- KREngine/kraken/KRAnimationCurve.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/KREngine/kraken/KRAnimationCurve.cpp b/KREngine/kraken/KRAnimationCurve.cpp index b85ad15..8c6d8eb 100644 --- a/KREngine/kraken/KRAnimationCurve.cpp +++ b/KREngine/kraken/KRAnimationCurve.cpp @@ -127,7 +127,7 @@ void KRAnimationCurve::setFrameStart(int frame_number) float KRAnimationCurve::getValue(int frame_number) { //printf("frame_number: %i\n", frame_number); - int clamped_frame = frame_number; + int clamped_frame = frame_number - getFrameStart(); if(frame_number < 0) { clamped_frame = 0; } else if(frame_number >= getFrameCount()) { @@ -139,9 +139,10 @@ float KRAnimationCurve::getValue(int frame_number) void KRAnimationCurve::setValue(int frame_number, float value) { - if(frame_number >= 0 && frame_number < getFrameCount()) { + int clamped_frame = frame_number - getFrameStart(); + if(clamped_frame >= 0 && clamped_frame < getFrameCount()) { float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); - frame_data[frame_number] = value; + frame_data[clamped_frame] = value; } } From 0b90046aaae29dc11a2175e92065c6af87795d22 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 31 Aug 2013 17:38:20 -0700 Subject: [PATCH 06/43] Animation fixes for curves that do not start on frame 0 --HG-- branch : nfb --- KREngine/kraken/KRAnimation.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index 093ef13..02b99a8 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -164,16 +164,8 @@ void KRAnimation::update(float deltaTime) KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute(); if(curve != NULL && target != NULL) { - int frame_number = (int)((m_local_time + m_start_time) * curve->getFrameRate()); - if(frame_number < curve->getFrameStart()) { - target->SetAttribute(attribute_type, curve->getValue(m_start_time)); - } else if(frame_number - curve->getFrameStart() >= curve->getFrameCount()) { - target->SetAttribute(attribute_type, curve->getValue(curve->getFrameCount() - 1)); - } else { - target->SetAttribute(attribute_type, curve->getValue(frame_number - curve->getFrameStart())); - } + target->SetAttribute(attribute_type, curve->getValue(m_local_time + m_start_time)); } - } } } From 7b3ce4d3bfb48e6eef136b2afa7b9008c7921d16 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 31 Aug 2013 19:22:37 -0700 Subject: [PATCH 07/43] More animation fixes for curves that don't start on frame 0. --HG-- branch : nfb --- KREngine/kraken/KRAnimationCurve.cpp | 4 ++-- KREngine/kraken/KRResource+fbx.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/KREngine/kraken/KRAnimationCurve.cpp b/KREngine/kraken/KRAnimationCurve.cpp index 8c6d8eb..48077e9 100644 --- a/KREngine/kraken/KRAnimationCurve.cpp +++ b/KREngine/kraken/KRAnimationCurve.cpp @@ -128,9 +128,9 @@ float KRAnimationCurve::getValue(int frame_number) { //printf("frame_number: %i\n", frame_number); int clamped_frame = frame_number - getFrameStart(); - if(frame_number < 0) { + if(clamped_frame < 0) { clamped_frame = 0; - } else if(frame_number >= getFrameCount()) { + } else if(clamped_frame >= getFrameCount()) { clamped_frame = getFrameCount()-1; } float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 37c7dda..360f002 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -359,19 +359,19 @@ KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurv return NULL; } - float frame_rate = 30.0f; // FINDME, TODO - This needs to be dynamic - int frame_start = time_span.GetStart().GetSecondDouble() * frame_rate; - int frame_count = (time_span.GetStop().GetSecondDouble() * frame_rate) - frame_start; + float dest_frame_rate = 30.0f; // FINDME, TODO - This needs to be dynamic + int frame_start = time_span.GetStart().GetSecondDouble() * dest_frame_rate; + int frame_count = (time_span.GetStop().GetSecondDouble() * dest_frame_rate) - frame_start; KRAnimationCurve *new_curve = new KRAnimationCurve(context, name); - new_curve->setFrameRate(frame_rate); + new_curve->setFrameRate(dest_frame_rate); new_curve->setFrameStart(frame_start); new_curve->setFrameCount(frame_count); // Resample animation curve int last_frame = 0; // Used by FBX sdk for faster keyframe searches for(int frame_number=0; frame_number < frame_count; frame_number++) { - float frame_seconds = (frame_start + frame_number) / frame_rate; + float frame_seconds = (frame_start + frame_number) / dest_frame_rate; FbxTime frame_time; frame_time.SetSecondDouble(frame_seconds); float frame_value = pAnimCurve->Evaluate(frame_time, &last_frame); From eb6ee6c6767b516ae483acb5c0e318a1b13fa672 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 7 Sep 2013 16:57:18 -0700 Subject: [PATCH 08/43] Fixed shader compile error that occurred when using Reflection Map scale or offset attributes in a material. Fixed bug that caused the Reflection Map scale to be swapped with the Normal Map scale material parameter. Fixed bug that caused the Reflection Map offset to be swapped with the Normal Map offset material parameter. --HG-- branch : nfb --- KREngine/kraken/KRMaterial.cpp | 2 +- KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh | 4 ++-- .../kraken_standard_assets_osx/Shaders/ObjectShader_osx.vsh | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/KREngine/kraken/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index 95e836e..3a29612 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -252,7 +252,7 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_ligh bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, point_lights, directional_lights, spot_lights, bones.size(), bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_reflectionMapScale != default_scale && bReflectionMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_reflectionMapOffset != default_offset && bReflectionMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass); + KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, point_lights, directional_lights, spot_lights, bones.size(), bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_normalMapScale != default_scale && bNormalMap, m_reflectionMapScale != default_scale && bReflectionMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_normalMapOffset != default_offset && bNormalMap, m_reflectionMapOffset != default_offset && bReflectionMap, bAlphaTest, bAlphaBlend, renderPass); if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, 0, renderPass)) { return false; diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh index 353f5b2..6d2b3fe 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh @@ -111,11 +111,11 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t #endif #if HAS_REFLECTION_MAP_SCALE == 1 - uniform highp vec2 reflection_Scale; + uniform highp vec2 reflectionTexture_Scale; #endif #if HAS_REFLECTION_MAP_OFFSET == 1 - uniform highp vec2 reflection_Offset; + uniform highp vec2 reflectionTexture_Offset; #endif #if SHADOW_QUALITY >= 1 diff --git a/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.vsh index fd08cb2..4aaad3b 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.vsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.vsh @@ -107,11 +107,11 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t #endif #if HAS_REFLECTION_MAP_SCALE == 1 - uniform highp vec2 reflection_Scale; + uniform highp vec2 reflectionTexture_Scale; #endif #if HAS_REFLECTION_MAP_OFFSET == 1 - uniform highp vec2 reflection_Offset; + uniform highp vec2 reflectionTexture_Offset; #endif #if SHADOW_QUALITY >= 1 From de324ff2790ba615689359301a10bdbf01f950cd Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 7 Sep 2013 17:34:06 -0700 Subject: [PATCH 09/43] Fixed bug in KROctreeNode::lineCast that would cause it to always return false --HG-- branch : nfb --- KREngine/kraken/KROctreeNode.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/KREngine/kraken/KROctreeNode.cpp b/KREngine/kraken/KROctreeNode.cpp index 490b7f7..7332275 100644 --- a/KREngine/kraken/KROctreeNode.cpp +++ b/KREngine/kraken/KROctreeNode.cpp @@ -203,7 +203,6 @@ bool KROctreeNode::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo // Optimization: If we already have a hit, only search for hits that are closer hit_found = lineCast(v0, hitinfo.getPosition(), hitinfo, layer_mask); } else { - bool hit_found = false; if(getBounds().intersectsLine(v0, v1)) { for(std::set::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { KRCollider *collider = dynamic_cast(*nodes_itr); From 4dddec7f8509c850a1bcd5df4ddc2137ffd558ee Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 6 Oct 2013 18:56:23 -0700 Subject: [PATCH 10/43] Asynchronous streaming and memory management improvements in progress. Note: This branch is unstable --HG-- branch : async_streaming --- KREngine/Kraken.xcodeproj/project.pbxproj | 12 ++ KREngine/kraken/KRAnimation.cpp | 5 +- KREngine/kraken/KRAnimationCurve.cpp | 54 +++++-- KREngine/kraken/KRAudioManager.cpp | 8 +- KREngine/kraken/KRAudioSample.cpp | 7 +- KREngine/kraken/KRBundle.cpp | 45 +++--- KREngine/kraken/KRDataBlock.cpp | 149 ++++++++++++++--- KREngine/kraken/KRDataBlock.h | 30 +++- KREngine/kraken/KREngine-common.h | 2 + KREngine/kraken/KRLocator.cpp | 35 ++++ KREngine/kraken/KRLocator.h | 27 ++++ KREngine/kraken/KRMaterialManager.cpp | 4 +- KREngine/kraken/KRMesh.cpp | 186 ++++++++++++---------- KREngine/kraken/KRNode.cpp | 3 + KREngine/kraken/KRResource+fbx.cpp | 103 +++++++----- KREngine/kraken/KRScene.cpp | 2 + KREngine/kraken/KRShaderManager.cpp | 4 +- KREngine/kraken/KRTexture2D.cpp | 2 + KREngine/kraken/KRTexturePVR.cpp | 5 +- KREngine/kraken/KRTextureTGA.cpp | 4 +- 20 files changed, 488 insertions(+), 199 deletions(-) create mode 100644 KREngine/kraken/KRLocator.cpp create mode 100644 KREngine/kraken/KRLocator.h diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index d44fbbe..a306cac 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -109,6 +109,10 @@ E461A176152E5C5600F2044A /* KRPointLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A157152E555400F2044A /* KRPointLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; E461A177152E5C6600F2044A /* KRMat4.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017613C99BDC0098455B /* KRMat4.h */; settings = {ATTRIBUTES = (Public, ); }; }; E461A17A152E5C9100F2044A /* KRMat4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E491017713C99BDC0098455B /* KRMat4.cpp */; }; + E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; }; + E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; }; + E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; }; + E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; }; E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */; }; E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */ = {isa = PBXBuildFile; fileRef = E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; }; @@ -438,6 +442,8 @@ E461A15E152E565700F2044A /* KRDirectionalLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRDirectionalLight.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E461A164152E56C000F2044A /* KRSpotLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSpotLight.cpp; sourceTree = ""; }; E461A167152E570500F2044A /* KRSpotLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRSpotLight.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + E468447D17FFDF51001F1FA1 /* KRLocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLocator.cpp; sourceTree = ""; }; + E468447E17FFDF51001F1FA1 /* KRLocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLocator.h; sourceTree = ""; }; E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "KRResource+blend.cpp"; sourceTree = ""; }; E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KRResource+blend.h"; sourceTree = ""; }; E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = ""; }; @@ -971,6 +977,8 @@ E480BE6B1671C653004EC8AD /* KRBone.cpp */, E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */, E4AE635C1704FB0A00B460CD /* KRLODGroup.h */, + E468447D17FFDF51001F1FA1 /* KRLocator.cpp */, + E468447E17FFDF51001F1FA1 /* KRLocator.h */, ); name = "Scene Graph Nodes"; sourceTree = ""; @@ -1198,6 +1206,7 @@ E461A152152E54B500F2044A /* KRLight.h in Headers */, E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */, E461A168152E570700F2044A /* KRSpotLight.h in Headers */, + E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */, E4F975321536220900FD60B2 /* KRNode.h in Headers */, E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */, E48C696F15374F5B00232E28 /* KRContext.h in Headers */, @@ -1257,6 +1266,7 @@ E497B948151BB89D00D3DC67 /* KRVector2.h in Headers */, E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */, E461A177152E5C6600F2044A /* KRMat4.h in Headers */, + E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */, E4F975461536327C00FD60B2 /* KRMeshManager.h in Headers */, E497B94B151BCEE900D3DC67 /* KRResource.h in Headers */, E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */, @@ -1544,6 +1554,7 @@ E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */, E461A156152E54F800F2044A /* KRLight.cpp in Sources */, E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */, + E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */, E461A15F152E565700F2044A /* KRDirectionalLight.cpp in Sources */, E461A165152E56C000F2044A /* KRSpotLight.cpp in Sources */, E4F975361536221C00FD60B2 /* KRNode.cpp in Sources */, @@ -1607,6 +1618,7 @@ E4BBBBA71512A6DC00F43B5B /* KRVector3.cpp in Sources */, E4B2A43B1523B02E004CB0EC /* KRMaterial.cpp in Sources */, E4BBBB8E1512A40300F43B5B /* krengine_osx.mm in Sources */, + E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */, E497B947151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B94E151BCF2500D3DC67 /* KRResource.cpp in Sources */, E497B951151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */, diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index 02b99a8..f5db97b 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -85,9 +85,10 @@ bool KRAnimation::save(KRDataBlock &data) { KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDataBlock *data) { - data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely + std::string xml_string = data->getString(); + tinyxml2::XMLDocument doc; - doc.Parse((char *)data->getStart()); + doc.Parse(xml_string.c_str()); KRAnimation *new_animation = new KRAnimation(context, name); tinyxml2::XMLElement *animation_node = doc.RootElement(); diff --git a/KREngine/kraken/KRAnimationCurve.cpp b/KREngine/kraken/KRAnimationCurve.cpp index 48077e9..a99138e 100644 --- a/KREngine/kraken/KRAnimationCurve.cpp +++ b/KREngine/kraken/KRAnimationCurve.cpp @@ -37,11 +37,13 @@ KRAnimationCurve::KRAnimationCurve(KRContext &context, const std::string &name) { m_pData = new KRDataBlock(); m_pData->expand(sizeof(animation_curve_header)); + m_pData->lock(); animation_curve_header *header = (animation_curve_header *)m_pData->getStart(); strcpy(header->szTag, "KRCURVE1.0 "); header->frame_rate = 30.0f; header->frame_start = 0; header->frame_count = 0; + m_pData->unlock(); } KRAnimationCurve::~KRAnimationCurve() @@ -84,11 +86,16 @@ KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string & int KRAnimationCurve::getFrameCount() { - return ((animation_curve_header *)m_pData->getStart())->frame_count; + m_pData->lock(); + int frame_count = ((animation_curve_header *)m_pData->getStart())->frame_count; + m_pData->unlock(); + + return frame_count; } void KRAnimationCurve::setFrameCount(int frame_count) { + m_pData->lock(); int prev_frame_count = getFrameCount(); if(frame_count != prev_frame_count) { float fill_value = 0.0f; @@ -102,30 +109,42 @@ void KRAnimationCurve::setFrameCount(int frame_count) } ((animation_curve_header *)m_pData->getStart())->frame_count = frame_count; } + m_pData->unlock(); } float KRAnimationCurve::getFrameRate() { - return ((animation_curve_header *)m_pData->getStart())->frame_rate; + m_pData->lock(); + float frame_rate =((animation_curve_header *)m_pData->getStart())->frame_rate; + m_pData->unlock(); + return frame_rate; } void KRAnimationCurve::setFrameRate(float frame_rate) { + m_pData->lock(); ((animation_curve_header *)m_pData->getStart())->frame_rate = frame_rate; + m_pData->unlock(); } int KRAnimationCurve::getFrameStart() { - return ((animation_curve_header *)m_pData->getStart())->frame_start; + m_pData->lock(); + int frame_start = ((animation_curve_header *)m_pData->getStart())->frame_start; + m_pData->unlock(); + return frame_start; } void KRAnimationCurve::setFrameStart(int frame_number) { + m_pData->lock(); ((animation_curve_header *)m_pData->getStart())->frame_start = frame_number; + m_pData->unlock(); } float KRAnimationCurve::getValue(int frame_number) { + m_pData->lock(); //printf("frame_number: %i\n", frame_number); int clamped_frame = frame_number - getFrameStart(); if(clamped_frame < 0) { @@ -134,43 +153,56 @@ float KRAnimationCurve::getValue(int frame_number) clamped_frame = getFrameCount()-1; } float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); - return frame_data[clamped_frame]; + float v = frame_data[clamped_frame]; + m_pData->unlock(); + return v; } void KRAnimationCurve::setValue(int frame_number, float value) { + m_pData->lock(); int clamped_frame = frame_number - getFrameStart(); if(clamped_frame >= 0 && clamped_frame < getFrameCount()) { float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); frame_data[clamped_frame] = value; } + m_pData->unlock(); } float KRAnimationCurve::getValue(float local_time) { // TODO - Need to add interpolation for time values between frames. // Must consider looping animations when determining which two frames to interpolate between. - return getValue((int)(local_time * getFrameRate())); + m_pData->lock(); + float v = getValue((int)(local_time * getFrameRate())); + m_pData->unlock(); + return v; } bool KRAnimationCurve::valueChanges(float start_time, float duration) { - return valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); + m_pData->lock(); + bool c = valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); + m_pData->unlock(); + return c; } bool KRAnimationCurve::valueChanges(int start_frame, int frame_count) { - + m_pData->lock(); float first_value = getValue(start_frame); + bool change_found = false; + // Range of frames is not inclusive of last frame - for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count; frame_number++) { + for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count && !change_found; frame_number++) { if(getValue(frame_number) != first_value) { - return true; + change_found = true; } } - return false; + m_pData->unlock(); + return change_found; } KRAnimationCurve *KRAnimationCurve::split(const std::string &name, float start_time, float duration) @@ -185,11 +217,13 @@ KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_fra new_curve->setFrameRate(getFrameRate()); new_curve->setFrameStart(start_frame); new_curve->setFrameCount(frame_count); + new_curve->m_pData->lock(); // Range of frames is not inclusive of last frame for(int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) { new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here? } + new_curve->m_pData->unlock(); getContext().getAnimationCurveManager()->addAnimationCurve(new_curve); return new_curve; diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index 428cb2b..4d8158f 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -214,8 +214,8 @@ void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData) uint64_t end_time = mach_absolute_time(); - uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds - uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100; +// uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds +// uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100; // fprintf(stderr, "audio load: %5.1f%% hrtf channels: %li\n", (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); } @@ -1364,14 +1364,14 @@ KRDataBlock *KRAudioManager::getBufferData(int size) data = new KRDataBlock(); data->expand(size); } - + data->lock(); return data; - } void KRAudioManager::recycleBufferData(KRDataBlock *data) { if(data != NULL) { + data->unlock(); if(data->getSize() == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() < KRENGINE_AUDIO_MAX_POOL_SIZE) { m_bufferPoolIdle.push_back(data); } else { diff --git a/KREngine/kraken/KRAudioSample.cpp b/KREngine/kraken/KRAudioSample.cpp index 793729f..b9bd250 100644 --- a/KREngine/kraken/KRAudioSample.cpp +++ b/KREngine/kraken/KRAudioSample.cpp @@ -40,6 +40,7 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension) : KRResource(context, name) { m_pData = new KRDataBlock(); + m_pData->lock(); m_extension = extension; m_audio_file_id = 0; @@ -55,6 +56,7 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name) { m_pData = data; + m_pData->lock(); m_extension = extension; m_audio_file_id = 0; @@ -71,6 +73,7 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e KRAudioSample::~KRAudioSample() { closeFile(); + m_pData->unlock(); delete m_pData; } @@ -198,7 +201,8 @@ OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc KRAudioSample *sound = (KRAudioSample *)inClientData; UInt32 max_count = sound->m_pData->getSize() - inPosition; *actualCount = requestCount < max_count ? requestCount : max_count; - memcpy(buffer, (unsigned char *)sound->m_pData->getStart() + inPosition, *actualCount); + sound->m_pData->copy(buffer, inPosition, *actualCount); + //memcpy(buffer, (unsigned char *)sound->m_pData->getStart() + inPosition, *actualCount); return noErr; } @@ -231,6 +235,7 @@ void KRAudioSample::openFile() { // AudioFileInitializeWithCallbacks if(m_fileRef == NULL) { + // Temp variables UInt32 propertySize; diff --git a/KREngine/kraken/KRBundle.cpp b/KREngine/kraken/KRBundle.cpp index 5173695..d152d77 100644 --- a/KREngine/kraken/KRBundle.cpp +++ b/KREngine/kraken/KRBundle.cpp @@ -53,35 +53,18 @@ KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : K { m_pData = pData; - unsigned char *pFile = (unsigned char *)m_pData->getStart(); - while(pFile < m_pData->getEnd() ) { - tar_header_type *file_header = (tar_header_type *)pFile; - size_t file_size = strtol(file_header->file_size, NULL, 8); - pFile += 512; // Skip past the header to the file contents - - if(file_header->file_name[0] != '\0' && file_header->file_name[0] != '.') { + __int64_t file_pos = 0; + while(file_pos < m_pData->getSize()) { + tar_header_type file_header; + m_pData->copy(&file_header, file_pos, sizeof(file_header)); + size_t file_size = strtol(file_header.file_size, NULL, 8); + file_pos += 512; // Skip past the header to the file contents + if(file_header.file_name[0] != '\0' && file_header.file_name[0] != '.') { // We ignore the last two records in the tar file, which are zero'ed out tar_header structures - KRDataBlock *pFileData = new KRDataBlock(); - if(pFileData->load(pFile, file_size)) { - context.loadResource(file_header->file_name, pFileData); - } else { - delete pFileData; - assert(false); - } + KRDataBlock *pFileData = pData->getSubBlock(file_pos, file_size); + context.loadResource(file_header.file_name, pFileData); } - - // Advance past the end of the file - /* - if((file_size & 0x01ff) == 0) { - // file size is a multiple of 512 bytes, we can just add it - pFile += file_size; - } else { - // We would not be on a 512 byte boundary, round up to the next one - pFile += (file_size + 0x0200) - (file_size & 0x1ff); - } - */ - pFile += RoundUpSize(file_size); - + file_pos += RoundUpSize(file_size); } } @@ -90,7 +73,9 @@ KRBundle::KRBundle(KRContext &context, std::string name) : KRResource(context, n // Create an empty krbundle (tar) file, initialized with two zero-ed out file headers, which terminate it. m_pData = new KRDataBlock(); m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE * 2); + m_pData->lock(); memset(m_pData->getStart(), 0, m_pData->getSize()); + m_pData->unlock(); } size_t KRBundle::RoundUpSize(size_t s) @@ -142,6 +127,8 @@ void KRBundle::append(KRResource &resource) m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE + resource_data.getSize() + padding_size - KRENGINE_KRBUNDLE_HEADER_SIZE * 2); // We will overwrite the existing zero-ed out file headers that marked the end of the archive, so we don't have to include their size here + m_pData->lock(); + // Get location of file header tar_header_type *file_header = (tar_header_type *)((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize() - KRENGINE_KRBUNDLE_HEADER_SIZE); @@ -149,7 +136,9 @@ void KRBundle::append(KRResource &resource) memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE); // Copy resource data + resource_data.lock(); memcpy((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize(), resource_data.getStart(), resource_data.getSize()); + resource_data.unlock(); // Zero out alignment padding and terminating set of file header blocks memset((unsigned char *)m_pData->getEnd() - padding_size, 0, padding_size); @@ -172,4 +161,6 @@ void KRBundle::append(KRResource &resource) check_sum += byte_ptr[i]; } sprintf(file_header->checksum, "%07o", check_sum); + + m_pData->unlock(); } diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index b60ad37..05a9e94 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -30,12 +30,18 @@ // #include "KRDataBlock.h" +#include "KREngine-common.h" KRDataBlock::KRDataBlock() { m_data = NULL; m_data_size = 0; + m_data_offset = 0; m_fdPackFile = 0; + m_mmapData = NULL; + m_fileOwnerDataBlock = NULL; m_bMalloced = false; + m_lockCount = 0; + m_bReadOnly = false; } KRDataBlock::~KRDataBlock() { @@ -45,10 +51,13 @@ KRDataBlock::~KRDataBlock() { // Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use void KRDataBlock::unload() { + assert(m_lockCount == 0); + if(m_fdPackFile) { // Memory mapped file - munmap(m_data, m_data_size); - close(m_fdPackFile); + if(m_fileOwnerDataBlock == this) { + close(m_fdPackFile); + } } else if(m_data != NULL && m_bMalloced) { // Malloc'ed data free(m_data); @@ -57,7 +66,11 @@ void KRDataBlock::unload() m_bMalloced = false; m_data = NULL; m_data_size = 0; + m_data_offset = 0; m_fdPackFile = 0; + m_mmapData = NULL; + m_fileOwnerDataBlock = NULL; + m_bReadOnly = false; } // Encapsulate a pointer. Note - The pointer will not be free'ed @@ -66,6 +79,8 @@ bool KRDataBlock::load(void *data, size_t size) unload(); m_data = data; m_data_size = size; + m_data_offset = 0; + m_bReadOnly = false; return true; } @@ -76,14 +91,14 @@ bool KRDataBlock::load(const std::string &path) unload(); struct stat statbuf; + m_bReadOnly = true; m_fdPackFile = open(path.c_str(), O_RDONLY); if(m_fdPackFile >= 0) { + m_fileOwnerDataBlock = this; if(fstat(m_fdPackFile, &statbuf) >= 0) { - if ((m_data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, m_fdPackFile, 0)) == (caddr_t) -1) { - } else { - m_data_size = statbuf.st_size; - success = true; - } + m_data_size = statbuf.st_size; + m_data_offset = 0; + success = true; } } if(!success) { @@ -93,13 +108,32 @@ bool KRDataBlock::load(const std::string &path) return success; } +// Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object. +KRDataBlock *KRDataBlock::getSubBlock(int start, int length) +{ + KRDataBlock *new_block = new KRDataBlock(); + + new_block->m_data_size = length; + if(m_fdPackFile) { + new_block->m_fdPackFile = m_fdPackFile; + new_block->m_fileOwnerDataBlock = m_fileOwnerDataBlock; + new_block->m_data_offset = start; + } else if(m_bMalloced) { + new_block->m_data = (unsigned char *)m_data + start; + } + new_block->m_bReadOnly = true; + return new_block; +} + // Return a pointer to the start of the data block void *KRDataBlock::getStart() { + assertLocked(); return m_data; } // Return a pointer to the byte after the end of the data block void *KRDataBlock::getEnd() { + assertLocked(); return (unsigned char *)m_data + m_data_size; } @@ -111,28 +145,33 @@ size_t KRDataBlock::getSize() const { // Expand the data block, and switch it to read-write mode. Note - this may result in a mmap'ed file being copied to malloc'ed ram and then closed void KRDataBlock::expand(size_t size) { - if(m_data == NULL) { + if(m_data == NULL && m_fdPackFile == 0) { // Starting with an empty data block; allocate memory on the heap m_data = malloc(size); assert(m_data != NULL); m_data_size = size; + m_data_offset = 0; m_bMalloced = true; } else if(m_bMalloced) { // Starting with a malloc'ed data block; realloc it expand m_data = realloc(m_data, m_data_size + size); m_data_size += size; } else { - // Starting with a mmap'ed data block; copy it to ram before expanding to avoid updating the original file until save() is called + // Starting with a mmap'ed data block, an encapsulated pointer, or a sub-block; copy it to ram before expanding to avoid updating the original file until save() is called // ... Or starting with a pointer reference, we must make our own copy and must not free the pointer void *pNewData = malloc(m_data_size + size); assert(pNewData != NULL); - memcpy((unsigned char *)pNewData, m_data, m_data_size); // Copy exising data + + // Copy exising data + copy(pNewData); + // Unload existing data allocation, which is now redundant size_t new_size = m_data_size + size; // We need to store this before unload() as unload() will reset it unload(); m_bMalloced = true; m_data = pNewData; m_data_size = new_size; + m_data_offset = 0; } } @@ -142,12 +181,31 @@ void KRDataBlock::append(void *data, size_t size) { expand(size); // Fill the new space with the data to append + lock(); memcpy((unsigned char *)m_data + m_data_size - size, data, size); + unlock(); +} + + +// Copy the entire data block to the destination pointer +void KRDataBlock::copy(void *dest) { + lock(); + memcpy((unsigned char *)dest, m_data, m_data_size); + unlock(); +} + +// Copy a range of data to the destination pointer +void KRDataBlock::copy(void *dest, int start, int count) { + lock(); + memcpy((unsigned char *)dest, (unsigned char *)m_data + start, count); + unlock(); } // Append data to the end of the block, increasing the size of the block and making it read-write. void KRDataBlock::append(KRDataBlock &data) { + data.lock(); append(data.getStart(), data.getSize()); + data.unlock(); } // Append string to the end of the block, increasing the size of the block and making it read-write. The null terminating character is included @@ -157,7 +215,7 @@ void KRDataBlock::append(const std::string &s) append((void *)szText, strlen(szText)+1); } -// Save the data to a file, and switch to read-only mode. The data pointer will be replaced with a mmap'ed address of the file; the malloc'ed data will be freed +// Save the data to a file. bool KRDataBlock::save(const std::string& path) { int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); if(fdNewFile == -1) { @@ -173,20 +231,16 @@ bool KRDataBlock::save(const std::string& path) { close(fdNewFile); return false; } else if(m_data != NULL) { + + // Copy data to new file - memcpy(pNewData, m_data, m_data_size); + copy(pNewData); - // Unload existing data allocation, which is now redundant - size_t new_size = m_data_size; // We need to store this, as unload() will reset it - unload(); - - // Protect new mmap'ed memory - mprotect(pNewData, m_data_size, PROT_READ); + // Unmap the new file + munmap(pNewData, m_data_size); - // Switch pointer to use new mmap'ed memory - m_data_size = new_size; - m_fdPackFile = fdNewFile; - m_data = pNewData; + // Close the new file + close(fdNewFile); } return true; } @@ -195,8 +249,57 @@ bool KRDataBlock::save(const std::string& path) { // Get contents as a string std::string KRDataBlock::getString() { + lock(); KRDataBlock b; b.append(*this); b.append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely - return std::string((char *)b.getStart()); + b.lock(); + std::string ret = std::string((char *)b.getStart()); + b.unlock(); + unlock(); + return ret; +} + +// Lock the memory, forcing it to be loaded into a contiguous block of address space +void KRDataBlock::lock() +{ + m_lockCount++; + if(m_lockCount == 1) { + + // Memory mapped file; ensure data is mapped to ram + if(m_fdPackFile) { + // Round m_data_offset down to the next memory page, as required by mmap + size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); + if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) { + assert(false); // mmap() failed. + } + m_data = (unsigned char *)m_mmapData + alignment_offset; + } + + } +} + +// Unlock the memory, releasing the address space for use by other allocations +void KRDataBlock::unlock() +{ + // We expect that the data block was previously locked + assertLocked(); + + m_lockCount--; + if(m_lockCount == 0) { + + // Memory mapped file; ensure data is unmapped from ram + if(m_fdPackFile) { + munmap(m_mmapData, m_data_size); + m_data = NULL; + m_mmapData = NULL; + } + + } +} + +// Assert if not locked +void KRDataBlock::assertLocked() +{ + assert(m_lockCount > 0); } diff --git a/KREngine/kraken/KRDataBlock.h b/KREngine/kraken/KRDataBlock.h index b67dba8..13caed0 100644 --- a/KREngine/kraken/KRDataBlock.h +++ b/KREngine/kraken/KRDataBlock.h @@ -45,9 +45,12 @@ public: // Load a file into memory using mmap. The data pointer will be protected as read-only until append() or expand() is called bool load(const std::string &path); - // Save the data to a file, and switch to read-only mode. The data pointer will be replaced with a mmap'ed address of the file; the malloc'ed data will be freed + // Save the data to a file. bool save(const std::string& path); + // Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object. + KRDataBlock *getSubBlock(int start, int length); + // Append data to the end of the block, increasing the size of the block and making it read-write. void append(void *data, size_t size); @@ -74,15 +77,40 @@ public: // Get the contents as a string std::string getString(); + + // Copy the entire data block to the destination pointer + void copy(void *dest); + + // Copy a range of data to the destination pointer + void copy(void *dest, int start, int count); + + // Lock the memory, forcing it to be loaded into a contiguous block of address space + void lock(); + + // Unlock the memory, releasing the address space for use by other allocations + void unlock(); + private: void *m_data; size_t m_data_size; + size_t m_data_offset; // For memory mapped objects: int m_fdPackFile; + KRDataBlock *m_fileOwnerDataBlock; + void *m_mmapData; // For malloc'ed objects: bool m_bMalloced; + + // Lock refcount + int m_lockCount; + + // Read-only allocation + bool m_bReadOnly; + + // Assert if not locked + void assertLocked(); }; #endif diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index d80a414..700adba 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -11,6 +11,8 @@ #ifndef KRENGINE_COMMON_H #define KRENGINE_COMMON_H +#define KRAKEN_MEM_PAGE_SIZE 4096 +#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) (x & ~(KRAKEN_MEM_PAGE_SIZE - 1)) #define KRENGINE_MAX_TEXTURE_UNITS 8 float const PI = 3.141592653589793f; diff --git a/KREngine/kraken/KRLocator.cpp b/KREngine/kraken/KRLocator.cpp new file mode 100644 index 0000000..13d8878 --- /dev/null +++ b/KREngine/kraken/KRLocator.cpp @@ -0,0 +1,35 @@ +// +// KRLocator.cpp +// KREngine +// +// Created by Kearwood Gilbert on 2012-12-06. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#include "KRLocator.h" +#include "KRContext.h" + +KRLocator::KRLocator(KRScene &scene, std::string name) : KRNode(scene, name) +{ + setScaleCompensation(true); +} + +KRLocator::~KRLocator() +{ +} + +std::string KRLocator::getElementName() { + return "locator"; +} + +tinyxml2::XMLElement *KRLocator::saveXML( tinyxml2::XMLNode *parent) +{ + tinyxml2::XMLElement *e = KRNode::saveXML(parent); + + return e; +} + +void KRLocator::loadXML(tinyxml2::XMLElement *e) +{ + KRNode::loadXML(e); +} diff --git a/KREngine/kraken/KRLocator.h b/KREngine/kraken/KRLocator.h new file mode 100644 index 0000000..19e6f22 --- /dev/null +++ b/KREngine/kraken/KRLocator.h @@ -0,0 +1,27 @@ +// +// KRLocator +// KREngine +// +// Created by Kearwood Gilbert on 2012-12-06. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#ifndef KRLOCATOR_H +#define KRLOCATOR_H + +#include "KRResource.h" +#include "KRNode.h" +#include "KRTexture.h" + +class KRLocator : public KRNode { +public: + KRLocator(KRScene &scene, std::string name); + virtual ~KRLocator(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); + virtual void loadXML(tinyxml2::XMLElement *e); + +}; + + +#endif diff --git a/KREngine/kraken/KRMaterialManager.cpp b/KREngine/kraken/KRMaterialManager.cpp index 5f9d568..8b7deaa 100644 --- a/KREngine/kraken/KRMaterialManager.cpp +++ b/KREngine/kraken/KRMaterialManager.cpp @@ -100,7 +100,7 @@ void KRMaterialManager::add(KRMaterial *new_material) { bool KRMaterialManager::load(const char *szName, KRDataBlock *data) { KRMaterial *pMaterial = NULL; char szSymbol[16][256]; - + data->lock(); char *pScan = (char *)data->getStart(); char *pEnd = (char *)data->getEnd(); @@ -282,7 +282,7 @@ bool KRMaterialManager::load(const char *szName, KRDataBlock *data) { } } - + data->unlock(); delete data; return true; } diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index 1afe334..a044244 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -46,6 +46,7 @@ KRMesh::KRMesh(KRContext &context, std::string name) : KRResource(context, name) m_materials.clear(); m_uniqueMaterials.clear(); m_pData = new KRDataBlock(); + m_pData->lock(); setName(name); } @@ -54,6 +55,7 @@ KRMesh::KRMesh(KRContext &context, std::string name, KRDataBlock *data) : KRReso m_materials.clear(); m_uniqueMaterials.clear(); m_pData = new KRDataBlock(); + m_pData->lock(); setName(name); loadPack(data); @@ -104,6 +106,7 @@ int KRMesh::GetLODCoverage(const std::string &name) KRMesh::~KRMesh() { clearData(); + m_pData->unlock(); if(m_pData) delete m_pData; } @@ -124,8 +127,10 @@ bool KRMesh::save(KRDataBlock &data) { void KRMesh::loadPack(KRDataBlock *data) { clearData(); + m_pData->unlock(); delete m_pData; m_pData = data; + m_pData->lock(); updateAttributeOffsets(); pack_header *pHeader = getHeader(); m_minPoint = KRVector3(pHeader->minx, pHeader->miny, pHeader->minz); @@ -134,6 +139,8 @@ void KRMesh::loadPack(KRDataBlock *data) { void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones) { + m_pData->lock(); + //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { getSubmeshes(); @@ -214,6 +221,8 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect } } } + + m_pData->unlock(); } GLfloat KRMesh::getMaxDimension() { @@ -429,8 +438,9 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vectorunlock(); m_pData->expand(new_file_size); + m_pData->lock(); pack_header *pHeader = getHeader(); memset(pHeader, 0, sizeof(pack_header)); @@ -586,7 +596,9 @@ KRVector3 KRMesh::getMaxPoint() const { } void KRMesh::clearData() { + m_pData->unlock(); m_pData->unload(); + m_pData->lock(); } void KRMesh::clearBuffers() { @@ -892,8 +904,11 @@ size_t KRMesh::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_ int KRMesh::getBoneCount() { + m_pData->lock(); pack_header *header = getHeader(); - return header->bone_count; + int bone_count = header->bone_count; + m_pData->unlock(); + return bone_count; } char *KRMesh::getBoneName(int bone_index) @@ -908,7 +923,10 @@ KRMat4 KRMesh::getBoneBindPose(int bone_index) KRMesh::model_format_t KRMesh::getModelFormat() const { - return (model_format_t)getHeader()->model_format; + m_pData->lock(); + model_format_t f = (model_format_t)getHeader()->model_format; + m_pData->unlock(); + return f; } bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, const KRVector3 &tri_v0, const KRVector3 &tri_v1, const KRVector3 &tri_v2, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo) @@ -1055,7 +1073,7 @@ bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitin void KRMesh::convertToIndexed() { - + m_pData->lock(); char *szKey = new char[m_vertex_size * 2 + 1]; // Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU @@ -1230,6 +1248,8 @@ void KRMesh::convertToIndexed() mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES; + + m_pData->unlock(); LoadData(mi, false, false); } @@ -1284,85 +1304,89 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const void KRMesh::optimizeIndexes() { - if(getModelFormat() != KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) return; - - __uint16_t *new_indices = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); - __uint16_t *vertex_mapping = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); - unsigned char *new_vertex_data = (unsigned char *)malloc(m_vertex_size * 0x10000); - - // FINDME, TODO, HACK - This will segfault if the KRData object is still mmap'ed to a read-only file. Need to detach from the file before calling this function. Currently, this function is only being used during the import process, so it isn't going to cause any problems for now. - - pack_header *header = getHeader(); - - __uint16_t *index_data = getIndexData(); - unsigned char *vertex_data = getVertexData(); - - for(int submesh_index=0; submesh_index < header->submesh_count; submesh_index++) { - pack_material *submesh = getSubmesh(submesh_index); - int vertexes_remaining = submesh->vertex_count; - int index_group = getSubmesh(submesh_index)->index_group; - int index_group_offset = getSubmesh(submesh_index)->index_group_offset; - while(vertexes_remaining > 0) { - int start_index_offset, start_vertex_offset, index_count, vertex_count; - getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - - int vertexes_to_process = vertexes_remaining; - if(vertexes_to_process + index_group_offset > 0xffff) { - vertexes_to_process = 0xffff - index_group_offset; - } - - __uint16_t *index_data_start = index_data + start_index_offset + index_group_offset; - - - // ----====---- Step 1: Optimize triangle drawing order to maximize use of the GPU's post-transform vertex cache ----====---- - Forsyth::OptimizeFaces(index_data_start, vertexes_to_process, vertex_count, new_indices, 16); // FINDME, TODO - GPU post-transform vertex cache size of 16 should be configureable - memcpy(index_data_start, new_indices, vertexes_to_process * sizeof(__uint16_t)); - vertexes_remaining -= vertexes_to_process; - - /* - - unsigned char * vertex_data_start = vertex_data + start_vertex_offset; - - // ----====---- Step 2: Re-order the vertex data to maintain cache coherency ----====---- - for(int i=0; i < vertex_count; i++) { - vertex_mapping[i] = i; - } - int new_vertex_index=0; - for(int index_number=0; index_number new_vertex_index) { - // Swap prev_vertex_index and new_vertex_index - - for(int i=0; i < index_count; i++) { - if(index_data_start[i] == prev_vertex_index) { - index_data_start[i] = new_vertex_index; - } else if(index_data_start[i] == new_vertex_index) { - index_data_start[i] = prev_vertex_index; - } - } - - int tmp = vertex_mapping[prev_vertex_index]; - vertex_mapping[prev_vertex_index] = vertex_mapping[new_vertex_index]; - vertex_mapping[new_vertex_index] = tmp; - - - new_vertex_index++; + m_pData->lock(); + if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { + + __uint16_t *new_indices = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); + __uint16_t *vertex_mapping = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); + unsigned char *new_vertex_data = (unsigned char *)malloc(m_vertex_size * 0x10000); + + // FINDME, TODO, HACK - This will segfault if the KRData object is still mmap'ed to a read-only file. Need to detach from the file before calling this function. Currently, this function is only being used during the import process, so it isn't going to cause any problems for now. + + pack_header *header = getHeader(); + + __uint16_t *index_data = getIndexData(); + unsigned char *vertex_data = getVertexData(); + + for(int submesh_index=0; submesh_index < header->submesh_count; submesh_index++) { + pack_material *submesh = getSubmesh(submesh_index); + int vertexes_remaining = submesh->vertex_count; + int index_group = getSubmesh(submesh_index)->index_group; + int index_group_offset = getSubmesh(submesh_index)->index_group_offset; + while(vertexes_remaining > 0) { + int start_index_offset, start_vertex_offset, index_count, vertex_count; + getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); + + int vertexes_to_process = vertexes_remaining; + if(vertexes_to_process + index_group_offset > 0xffff) { + vertexes_to_process = 0xffff - index_group_offset; } + + __uint16_t *index_data_start = index_data + start_index_offset + index_group_offset; + + + // ----====---- Step 1: Optimize triangle drawing order to maximize use of the GPU's post-transform vertex cache ----====---- + Forsyth::OptimizeFaces(index_data_start, vertexes_to_process, vertex_count, new_indices, 16); // FINDME, TODO - GPU post-transform vertex cache size of 16 should be configureable + memcpy(index_data_start, new_indices, vertexes_to_process * sizeof(__uint16_t)); + vertexes_remaining -= vertexes_to_process; + + /* + + unsigned char * vertex_data_start = vertex_data + start_vertex_offset; + + // ----====---- Step 2: Re-order the vertex data to maintain cache coherency ----====---- + for(int i=0; i < vertex_count; i++) { + vertex_mapping[i] = i; + } + int new_vertex_index=0; + for(int index_number=0; index_number new_vertex_index) { + // Swap prev_vertex_index and new_vertex_index + + for(int i=0; i < index_count; i++) { + if(index_data_start[i] == prev_vertex_index) { + index_data_start[i] = new_vertex_index; + } else if(index_data_start[i] == new_vertex_index) { + index_data_start[i] = prev_vertex_index; + } + } + + int tmp = vertex_mapping[prev_vertex_index]; + vertex_mapping[prev_vertex_index] = vertex_mapping[new_vertex_index]; + vertex_mapping[new_vertex_index] = tmp; + + + new_vertex_index++; + } + } + + for(int i=0; i < vertex_count; i++) { + memcpy(new_vertex_data + vertex_mapping[i] * m_vertex_size, vertex_data_start + i * m_vertex_size, m_vertex_size); + } + memcpy(vertex_data_start, new_vertex_data, vertex_count * m_vertex_size); + */ + + + + index_group_offset = 0; } - - for(int i=0; i < vertex_count; i++) { - memcpy(new_vertex_data + vertex_mapping[i] * m_vertex_size, vertex_data_start + i * m_vertex_size, m_vertex_size); - } - memcpy(vertex_data_start, new_vertex_data, vertex_count * m_vertex_size); - */ - - - - index_group_offset = 0; } - } + + free(new_indices); + free(vertex_mapping); + free(new_vertex_data); + } // if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) - free(new_indices); - free(vertex_mapping); - free(new_vertex_data); + m_pData->unlock(); } diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index 56d8093..70e5ae1 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -20,6 +20,7 @@ #include "KRAABB.h" #include "KRQuaternion.h" #include "KRBone.h" +#include "KRLocator.h" #include "KRAudioSource.h" #include "KRAmbientZone.h" #include "KRReverbZone.h" @@ -421,6 +422,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { new_node = new KRCollider(scene, szName, e->Attribute("mesh"), 65535, 1.0f); } else if(strcmp(szElementName, "bone") == 0) { new_node = new KRBone(scene, szName); + } else if(strcmp(szElementName, "locator") == 0) { + new_node = new KRLocator(scene, szName); } else if(strcmp(szElementName, "audio_source") == 0) { new_node = new KRAudioSource(scene, szName); } else if(strcmp(szElementName, "ambient_zone") == 0) { diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 360f002..c5ee30d 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -23,6 +23,7 @@ #include "KRScene.h" #include "KRQuaternion.h" #include "KRBone.h" +#include "KRLocator.h" #include "KRBundle.h" #include "KRModel.h" #include "KRLODGroup.h" @@ -46,6 +47,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode); KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); +KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode); std::string GetFbxObjectName(FbxObject *obj); @@ -54,9 +56,25 @@ const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be c std::string GetFbxObjectName(FbxObject *obj) { + bool is_locator = false; + KFbxNode *node = FbxCast(obj); + if(node) { + KFbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType()); + if(attribute_type == KFbxNodeAttribute::eNull) { + KFbxNull* pSourceNull = (KFbxNull*) node->GetNodeAttribute(); + if(pSourceNull->Look.Get() == KFbxNull::eCross ) { + is_locator = true; + } + } + } + + // Object names from FBX files are now concatenated with the FBX numerical ID to ensure that they are unique // TODO - This should be updated to only add a prefix or suffix if needed to make the name unique - if(strcmp(obj->GetName(), "default_camera") == 0) { + if(is_locator) { + // We do not rename locators + return std::string(obj->GetName()); + } else if(strcmp(obj->GetName(), "default_camera") == 0) { // There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera return "default_camera"; } else { @@ -955,54 +973,40 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p case KFbxNodeAttribute::eSkeleton: new_node = LoadSkeleton(parent_node, pFbxScene, pNode); break; + case KFbxNodeAttribute::eCamera: new_node = LoadCamera(parent_node, pNode); break; default: { - if(pNode->GetChildCount() > 0) { - // Create an empty node, for inheritence of transforms - std::string name = GetFbxObjectName(pNode); - - float min_distance = 0.0f; - float max_distance = 0.0f; - - typedef boost::tokenizer > char_tokenizer; - - int step = 0; - - char_tokenizer name_components(name, boost::char_separator("_")); - for(char_tokenizer::iterator itr=name_components.begin(); itr != name_components.end(); itr++) { - std::string component = *itr; - std::transform(component.begin(), component.end(), - component.begin(), ::tolower); - if(component.compare("lod") == 0) { - step = 1; - } else if(step == 1) { - min_distance = boost::lexical_cast(component); - step++; - } else if(step == 2) { - max_distance = boost::lexical_cast(component); - step++; - } + bool is_locator = false; + if(attribute_type == KFbxNodeAttribute::eNull) { + KFbxNull* pSourceNull = (KFbxNull*) pNode->GetNodeAttribute(); + if(pSourceNull->Look.Get() == KFbxNull::eCross ) { + is_locator = true; } - - /* - if(min_distance == 0.0f && max_distance == 0.0f) { - // Regular node for grouping children together under one transform - new_node = new KRNode(parent_node->getScene(), name); - } else { - */ - // LOD Enabled group node - KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name); - lod_group->setMinDistance(min_distance); - lod_group->setMaxDistance(max_distance); - new_node = lod_group; - /* + } + + if(is_locator) { + new_node = LoadLocator(parent_node, pFbxScene, pNode); + } else { + if(pNode->GetChildCount() > 0) { + // Create an empty node, for inheritence of transforms + std::string name = GetFbxObjectName(pNode); + + + /* + if(min_distance == 0.0f && max_distance == 0.0f) { + // Regular node for grouping children together under one transform + new_node = new KRNode(parent_node->getScene(), name); + } else { + */ + // LOD Enabled group node + KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name); + lod_group->setMinDistance(0.0f); + lod_group->setMaxDistance(0.0f); + new_node = lod_group; } - */ - - } } break; @@ -1526,6 +1530,21 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) return new_bone; } +KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { + std::string name = GetFbxObjectName(pNode); + + KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str()); + + //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); + // PoseList pose_list; + // FbxArray pose_indices; + // if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) { + // fprintf(stderr, "Found bind pose(s)!\n"); + // } + + return new_locator; +} + KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) { FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute(); const char *szName = pNode->GetName(); diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 2a1f2f5..2e9c36c 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -406,7 +406,9 @@ KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock { data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely tinyxml2::XMLDocument doc; + data->lock(); doc.Parse((char *)data->getStart()); + data->unlock(); KRScene *new_scene = new KRScene(context, name); tinyxml2::XMLElement *scene_element = doc.RootElement(); diff --git a/KREngine/kraken/KRShaderManager.cpp b/KREngine/kraken/KRShaderManager.cpp index a591ea8..570f5ed 100644 --- a/KREngine/kraken/KRShaderManager.cpp +++ b/KREngine/kraken/KRShaderManager.cpp @@ -254,12 +254,12 @@ bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KR } void KRShaderManager::loadFragmentShader(const std::string &name, KRDataBlock *data) { - m_fragShaderSource[name] = string((char *)data->getStart(), data->getSize()); + m_fragShaderSource[name] = data->getString(); delete data; } void KRShaderManager::loadVertexShader(const std::string &name, KRDataBlock *data) { - m_vertShaderSource[name] = string((char *)data->getStart(), data->getSize()); + m_vertShaderSource[name] = data->getString(); delete data; } diff --git a/KREngine/kraken/KRTexture2D.cpp b/KREngine/kraken/KRTexture2D.cpp index da79d62..ea2a922 100644 --- a/KREngine/kraken/KRTexture2D.cpp +++ b/KREngine/kraken/KRTexture2D.cpp @@ -36,9 +36,11 @@ KRTexture2D::KRTexture2D(KRContext &context, KRDataBlock *data, std::string name) : KRTexture(context, name) { m_current_lod_max_dim = 0; m_pData = data; + m_pData->lock(); } KRTexture2D::~KRTexture2D() { + m_pData->unlock(); delete m_pData; } diff --git a/KREngine/kraken/KRTexturePVR.cpp b/KREngine/kraken/KRTexturePVR.cpp index 97addbf..63d6f4f 100644 --- a/KREngine/kraken/KRTexturePVR.cpp +++ b/KREngine/kraken/KRTexturePVR.cpp @@ -64,6 +64,7 @@ typedef struct _PVRTexHeader KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) { #if TARGET_OS_IPHONE + m_pData->lock(); PVRTexHeader *header = (PVRTexHeader *)m_pData->getStart(); uint32_t formatFlags = header->flags & PVR_TEXTURE_FLAG_TYPE_MASK; if (formatFlags == kPVRTextureFlagTypePVRTC_4) { @@ -134,7 +135,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight; m_min_lod_max_dim = width > height ? width : height; - + m_pData->unlock(); #endif } @@ -176,8 +177,6 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo int target_dim = lod_max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - GLenum err; - if(m_blocks.size() == 0) { return false; } diff --git a/KREngine/kraken/KRTextureTGA.cpp b/KREngine/kraken/KRTextureTGA.cpp index 5c6bb71..294c17b 100644 --- a/KREngine/kraken/KRTextureTGA.cpp +++ b/KREngine/kraken/KRTextureTGA.cpp @@ -28,10 +28,12 @@ typedef struct { KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) { + data->lock(); TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart(); m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height; m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images + data->unlock(); } KRTextureTGA::~KRTextureTGA() @@ -73,7 +75,7 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo } //#endif glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image); - delete converted_image; + free(converted_image); err = glGetError(); if (err != GL_NO_ERROR) { return false; From e849f55b34dbbcd85ab70e903481223402189585 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Tue, 8 Oct 2013 20:44:31 -0700 Subject: [PATCH 11/43] Experimental optimizations, not yet ready for stable branch --HG-- branch : async_streaming --- KREngine/Kraken.xcodeproj/project.pbxproj | 5 +++++ KREngine/kraken/KRMat4.cpp | 2 +- KREngine/kraken/KRMat4.h | 2 +- KREngine/kraken/KRMeshManager.cpp | 18 +++++++++++++++++ KREngine/kraken/KRModel.cpp | 24 ++++++++++++++++++++++- KREngine/kraken/KRModel.h | 4 ++++ 6 files changed, 52 insertions(+), 3 deletions(-) diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index a306cac..8304be3 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -1720,6 +1720,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_UNROLL_LOOPS = YES; GCC_VERSION = com.apple.compilers.llvmgcc42; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -1728,6 +1729,7 @@ "$(SRCROOT)/3rdparty/**", ); IPHONEOS_DEPLOYMENT_TARGET = 5.1; + LLVM_VECTORIZE_LOOPS = YES; MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -1741,6 +1743,8 @@ CLANG_CXX_LIBRARY = "libc++"; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = fast; + GCC_UNROLL_LOOPS = YES; GCC_VERSION = com.apple.compilers.llvmgcc42; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -1749,6 +1753,7 @@ "$(SRCROOT)/3rdparty/**", ); IPHONEOS_DEPLOYMENT_TARGET = 5.1; + LLVM_VECTORIZE_LOOPS = YES; MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = iphoneos; SKIP_INSTALL = YES; diff --git a/KREngine/kraken/KRMat4.cpp b/KREngine/kraken/KRMat4.cpp index 1441e55..6e686c0 100644 --- a/KREngine/kraken/KRMat4.cpp +++ b/KREngine/kraken/KRMat4.cpp @@ -87,7 +87,7 @@ float KRMat4::operator[](unsigned i) const { } // Overload comparison operator -bool KRMat4::operator==(const KRMat4 &m) { +bool KRMat4::operator==(const KRMat4 &m) const { return memcmp(c, m.c, sizeof(float) * 16) == 0; } diff --git a/KREngine/kraken/KRMat4.h b/KREngine/kraken/KRMat4.h index c8ac508..8e7340e 100644 --- a/KREngine/kraken/KRMat4.h +++ b/KREngine/kraken/KRMat4.h @@ -83,7 +83,7 @@ class KRMat4 { KRMat4& operator=(const KRMat4 &m); // Overload comparison operator - bool operator==(const KRMat4 &m); + bool operator==(const KRMat4 &m) const; // Overload compound multiply operator KRMat4& operator*=(const KRMat4 &m); diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 7f9b607..110416d 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -214,7 +214,15 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G #endif GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); +#if GL_OES_mapbuffer + + GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(void *map_ptr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); + memcpy(map_ptr, data, size); + GLDEBUG(glUnmapBufferOES(GL_ARRAY_BUFFER)); +#else GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); +#endif m_memoryTransferredThisFrame += size; m_vboMemUsed += size; configureAttribs(vertex_attrib_flags); @@ -226,7 +234,17 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); + +#if GL_OES_mapbuffer + + GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(void *map_ptr = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); + memcpy(map_ptr, index_data, index_data_size); + GLDEBUG(glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER)); +#else GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, index_data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); +#endif + m_memoryTransferredThisFrame += index_data_size; m_vboMemUsed += index_data_size; m_currentVBO.size += index_data_size; diff --git a/KREngine/kraken/KRModel.cpp b/KREngine/kraken/KRModel.cpp index 1f1be11..2c13800 100644 --- a/KREngine/kraken/KRModel.cpp +++ b/KREngine/kraken/KRModel.cpp @@ -43,6 +43,23 @@ KRModel::KRModel(KRScene &scene, std::string instance_name, std::string model_na m_min_lod_coverage = lod_min_coverage; m_receivesShadow = receives_shadow; m_faces_camera = faces_camera; + + m_boundsCachedMat.c[0] = -1.0f; + m_boundsCachedMat.c[1] = -1.0f; + m_boundsCachedMat.c[2] = -1.0f; + m_boundsCachedMat.c[3] = -1.0f; + m_boundsCachedMat.c[4] = -1.0f; + m_boundsCachedMat.c[5] = -1.0f; + m_boundsCachedMat.c[6] = -1.0f; + m_boundsCachedMat.c[7] = -1.0f; + m_boundsCachedMat.c[8] = -1.0f; + m_boundsCachedMat.c[9] = -1.0f; + m_boundsCachedMat.c[10] = -1.0f; + m_boundsCachedMat.c[11] = -1.0f; + m_boundsCachedMat.c[12] = -1.0f; + m_boundsCachedMat.c[13] = -1.0f; + m_boundsCachedMat.c[14] = -1.0f; + m_boundsCachedMat.c[15] = -1.0f; } KRModel::~KRModel() { @@ -155,7 +172,12 @@ KRAABB KRModel::getBounds() { float max_dimension = normal_bounds.longest_radius(); return KRAABB(normal_bounds.center()-KRVector3(max_dimension), normal_bounds.center() + KRVector3(max_dimension)); } else { - return KRAABB(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix()); + + if(!(m_boundsCachedMat == getModelMatrix())) { + m_boundsCachedMat = getModelMatrix(); + m_boundsCached = KRAABB(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix()); + } + return m_boundsCached; } } else { return KRAABB::Infinite(); diff --git a/KREngine/kraken/KRModel.h b/KREngine/kraken/KRModel.h index 80e145c..c5fff37 100644 --- a/KREngine/kraken/KRModel.h +++ b/KREngine/kraken/KRModel.h @@ -74,6 +74,10 @@ private: bool m_receivesShadow; bool m_faces_camera; + + + KRMat4 m_boundsCachedMat; + KRAABB m_boundsCached; }; From 63503393a43713b5487a08879218ae28e6f54cc5 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Fri, 18 Oct 2013 17:26:07 -0700 Subject: [PATCH 12/43] Now targeting iOS 7 and enabling 64-bit ARM --HG-- branch : async_streaming --- KREngine/Kraken.xcodeproj/project.pbxproj | 4 ++++ KREngine/kraken/KREngine-common.h | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index 8304be3..a4fc02e 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -1764,6 +1764,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; DSTROOT = /tmp/KREngine.dst; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1772,6 +1773,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch"; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", @@ -1788,6 +1790,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; DSTROOT = /tmp/KREngine.dst; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1796,6 +1799,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch"; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 700adba..5ad60fc 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -11,10 +11,6 @@ #ifndef KRENGINE_COMMON_H #define KRENGINE_COMMON_H -#define KRAKEN_MEM_PAGE_SIZE 4096 -#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) (x & ~(KRAKEN_MEM_PAGE_SIZE - 1)) -#define KRENGINE_MAX_TEXTURE_UNITS 8 - float const PI = 3.141592653589793f; float const D2R = PI * 2 / 360; @@ -71,6 +67,11 @@ using std::queue; #define KRAKEN_HAVE_BLAS 1 #endif +int KRAKEN_MEM_PAGE_SIZE = getpagesize(); + +#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) (x & ~(KRAKEN_MEM_PAGE_SIZE - 1)) +#define KRENGINE_MAX_TEXTURE_UNITS 8 + #if !defined(__i386__) && defined(__arm__) #define KRAKEN_USE_ARM_NEON From dc574ce2743341ffd61ec706560e4b6c72a3561b Mon Sep 17 00:00:00 2001 From: Manjit Bedi Date: Fri, 1 Nov 2013 17:34:51 -0700 Subject: [PATCH 13/43] changed settings to support iOS 7 & 64 bit architecture --HG-- branch : nfb --- KREngine/Kraken.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index d44fbbe..85b9e5e 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -1701,7 +1701,7 @@ E491016913C99B9E0098455B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; CLANG_CXX_LIBRARY = "libc++"; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1715,7 +1715,7 @@ /usr/local/include, "$(SRCROOT)/3rdparty/**", ); - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -1725,7 +1725,7 @@ E491016A13C99B9E0098455B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; CLANG_CXX_LIBRARY = "libc++"; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1736,7 +1736,7 @@ /usr/local/include, "$(SRCROOT)/3rdparty/**", ); - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = iphoneos; SKIP_INSTALL = YES; From ab808fc3e1b539cfcfcf287e1c5aa3d383d150cc Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Fri, 1 Nov 2013 23:17:04 -0700 Subject: [PATCH 14/43] Asynchronous streaming and memory management improvements in progress. --HG-- branch : async_streaming --- KREngine/Kraken.xcodeproj/project.pbxproj | 30 +++++++++++-------- KREngine/kraken/KRDataBlock.cpp | 30 ++++++++++++------- KREngine/kraken/KRDataBlock.h | 2 ++ KREngine/kraken/KREngine.mm | 18 ++++++------ KREngine/kraken/KRLODGroup.h | 1 - KREngine/kraken/KRLODSet.cpp | 35 +++++++++++++++++++++++ KREngine/kraken/KRLODSet.h | 26 +++++++++++++++++ KREngine/kraken/KRLocator.cpp | 2 +- KREngine/kraken/KRScene.cpp | 9 +++--- KREngine/kraken/KRTexture2D.cpp | 2 -- KREngine/kraken/KRTexturePVR.cpp | 14 +++++---- KREngine/kraken/KRTexturePVR.h | 2 +- KREngine/kraken/KRTextureTGA.cpp | 9 +++++- 13 files changed, 133 insertions(+), 47 deletions(-) create mode 100644 KREngine/kraken/KRLODSet.cpp create mode 100644 KREngine/kraken/KRLODSet.h diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index a4fc02e..471adaa 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -73,6 +73,10 @@ E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; }; E43B0AD815DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (); }; }; E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; + E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; + E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; + E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; }; E44F38241683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (); }; }; E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -423,6 +427,8 @@ E437849716C488360037FD43 /* hrtf_kemar.krbundle */ = {isa = PBXFileReference; lastKnownFileType = file; path = hrtf_kemar.krbundle; sourceTree = ""; }; E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRContextObject.cpp; sourceTree = ""; }; E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = ""; }; + E43F70DA181B20E300136169 /* KRLODSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODSet.cpp; sourceTree = ""; }; + E43F70DB181B20E400136169 /* KRLODSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODSet.h; sourceTree = ""; }; E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = ""; }; E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = ""; }; E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -979,6 +985,8 @@ E4AE635C1704FB0A00B460CD /* KRLODGroup.h */, E468447D17FFDF51001F1FA1 /* KRLocator.cpp */, E468447E17FFDF51001F1FA1 /* KRLocator.h */, + E43F70DA181B20E300136169 /* KRLODSet.cpp */, + E43F70DB181B20E400136169 /* KRLODSet.h */, ); name = "Scene Graph Nodes"; sourceTree = ""; @@ -1188,6 +1196,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + E43F70DE181B20E400136169 /* KRLODSet.h in Headers */, E491019513C99BDC0098455B /* KRMaterial.h in Headers */, E491019C13C99BDC0098455B /* KRMaterialManager.h in Headers */, E491019D13C99BDC0098455B /* KRTextureManager.h in Headers */, @@ -1299,6 +1308,7 @@ E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */, E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */, + E43F70DF181B20E400136169 /* KRLODSet.h in Headers */, E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */, E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */, E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */, @@ -1546,6 +1556,7 @@ E491019A13C99BDC0098455B /* KRMeshManager.cpp in Sources */, E47C25A713F4F6AB00FF4370 /* KRShaderManager.cpp in Sources */, E47C25A913F4F6DD00FF4370 /* KRShader.cpp in Sources */, + E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */, E414BAE51435558900A668C4 /* KRModel.cpp in Sources */, E414BAE91435585A00A668C4 /* KRScene.cpp in Sources */, E48B3CC014393E30000C50E2 /* KRCamera.cpp in Sources */, @@ -1648,6 +1659,7 @@ E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */, E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */, E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */, + E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */, E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, @@ -1713,22 +1725,21 @@ E491016913C99B9E0098455B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = c11; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_UNROLL_LOOPS = YES; - GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_VERSION = ""; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( /usr/local/include, "$(SRCROOT)/3rdparty/**", ); - IPHONEOS_DEPLOYMENT_TARGET = 5.1; LLVM_VECTORIZE_LOOPS = YES; MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = iphoneos; @@ -1739,20 +1750,19 @@ E491016A13C99B9E0098455B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = c11; GCC_OPTIMIZATION_LEVEL = fast; GCC_UNROLL_LOOPS = YES; - GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_VERSION = ""; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( /usr/local/include, "$(SRCROOT)/3rdparty/**", ); - IPHONEOS_DEPLOYMENT_TARGET = 5.1; LLVM_VECTORIZE_LOOPS = YES; MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = iphoneos; @@ -1772,7 +1782,6 @@ ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch"; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -1781,7 +1790,6 @@ OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = kraken; SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; - SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -1798,7 +1806,6 @@ ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch"; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -1807,7 +1814,6 @@ OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = kraken; SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; - SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index 05a9e94..c92a1e6 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -37,6 +37,7 @@ KRDataBlock::KRDataBlock() { m_data_size = 0; m_data_offset = 0; m_fdPackFile = 0; + m_fileName = ""; m_mmapData = NULL; m_fileOwnerDataBlock = NULL; m_bMalloced = false; @@ -68,6 +69,7 @@ void KRDataBlock::unload() m_data_size = 0; m_data_offset = 0; m_fdPackFile = 0; + m_fileName = ""; m_mmapData = NULL; m_fileOwnerDataBlock = NULL; m_bReadOnly = false; @@ -95,6 +97,7 @@ bool KRDataBlock::load(const std::string &path) m_fdPackFile = open(path.c_str(), O_RDONLY); if(m_fdPackFile >= 0) { m_fileOwnerDataBlock = this; + m_fileName = path; if(fstat(m_fdPackFile, &statbuf) >= 0) { m_data_size = statbuf.st_size; m_data_offset = 0; @@ -117,9 +120,9 @@ KRDataBlock *KRDataBlock::getSubBlock(int start, int length) if(m_fdPackFile) { new_block->m_fdPackFile = m_fdPackFile; new_block->m_fileOwnerDataBlock = m_fileOwnerDataBlock; - new_block->m_data_offset = start; + new_block->m_data_offset = start + m_data_offset; } else if(m_bMalloced) { - new_block->m_data = (unsigned char *)m_data + start; + new_block->m_data = (unsigned char *)m_data + start + m_data_offset; } new_block->m_bReadOnly = true; return new_block; @@ -189,16 +192,20 @@ void KRDataBlock::append(void *data, size_t size) { // Copy the entire data block to the destination pointer void KRDataBlock::copy(void *dest) { - lock(); - memcpy((unsigned char *)dest, m_data, m_data_size); - unlock(); + copy(dest, 0, m_data_size); } // Copy a range of data to the destination pointer void KRDataBlock::copy(void *dest, int start, int count) { - lock(); - memcpy((unsigned char *)dest, (unsigned char *)m_data + start, count); - unlock(); + if(m_lockCount == 0 && m_fdPackFile != 0) { + // Optimization: If we haven't mmap'ed or malloced the data already, pread() it directly from the file into the buffer + ssize_t r = pread(m_fdPackFile, dest, count, start + m_data_offset); + assert(r != -1); + } else { + lock(); + memcpy((unsigned char *)dest, (unsigned char *)m_data + start, count); + unlock(); + } } // Append data to the end of the block, increasing the size of the block and making it read-write. @@ -249,25 +256,26 @@ bool KRDataBlock::save(const std::string& path) { // Get contents as a string std::string KRDataBlock::getString() { - lock(); KRDataBlock b; b.append(*this); b.append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely b.lock(); std::string ret = std::string((char *)b.getStart()); b.unlock(); - unlock(); return ret; } // Lock the memory, forcing it to be loaded into a contiguous block of address space void KRDataBlock::lock() { + m_lockCount++; if(m_lockCount == 1) { // Memory mapped file; ensure data is mapped to ram if(m_fdPackFile) { + fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + // Round m_data_offset down to the next memory page, as required by mmap size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) { @@ -290,6 +298,8 @@ void KRDataBlock::unlock() // Memory mapped file; ensure data is unmapped from ram if(m_fdPackFile) { + fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + munmap(m_mmapData, m_data_size); m_data = NULL; m_mmapData = NULL; diff --git a/KREngine/kraken/KRDataBlock.h b/KREngine/kraken/KRDataBlock.h index 13caed0..80aeb0c 100644 --- a/KREngine/kraken/KRDataBlock.h +++ b/KREngine/kraken/KRDataBlock.h @@ -97,6 +97,7 @@ private: // For memory mapped objects: int m_fdPackFile; + std::string m_fileName; KRDataBlock *m_fileOwnerDataBlock; void *m_mmapData; @@ -111,6 +112,7 @@ private: // Assert if not locked void assertLocked(); + }; #endif diff --git a/KREngine/kraken/KREngine.mm b/KREngine/kraken/KREngine.mm index cb64a3f..b5fbb11 100644 --- a/KREngine/kraken/KREngine.mm +++ b/KREngine/kraken/KREngine.mm @@ -425,7 +425,7 @@ void kraken::set_debug_text(const std::string &print_text) [self getAmbientIntensity], [self getSunTemperature], [self getSunIntensity], - _settings.dof_quality, + static_cast(_settings.dof_quality), _settings.dof_depth, _settings.dof_falloff, _settings.bEnableFlash ? 1.0f : 0.0f, @@ -445,26 +445,26 @@ void kraken::set_debug_text(const std::string &print_text) _settings.bEnableDeferredLighting ? 1.0f : 0.0f, _settings.getPerspectiveNearZ(), _settings.getPerspectiveFarZ(), - _settings.volumetric_environment_enable, - 5 - _settings.volumetric_environment_downsample, + static_cast(_settings.volumetric_environment_enable), + static_cast(5 - _settings.volumetric_environment_downsample), _settings.volumetric_environment_max_distance, _settings.volumetric_environment_quality, _settings.volumetric_environment_intensity, - _settings.fog_type, + static_cast(_settings.fog_type), _settings.fog_near, _settings.fog_far, _settings.fog_density, _settings.fog_color.x, _settings.fog_color.y, _settings.fog_color.z, - _settings.dust_particle_enable, + static_cast(_settings.dust_particle_enable), _settings.dust_particle_intensity, _settings.getLODBias(), - _settings.getEnableRealtimeOcclusion(), + static_cast(_settings.getEnableRealtimeOcclusion()), _settings.debug_display, - _settings.siren_enable, - _settings.siren_enable_reverb, - _settings.siren_enable_hrtf, + static_cast(_settings.siren_enable), + static_cast(_settings.siren_enable_reverb), + static_cast(_settings.siren_enable_hrtf), _settings.siren_reverb_max_length, _settings.max_anisotropy }; diff --git a/KREngine/kraken/KRLODGroup.h b/KREngine/kraken/KRLODGroup.h index a35daea..c394fb4 100644 --- a/KREngine/kraken/KRLODGroup.h +++ b/KREngine/kraken/KRLODGroup.h @@ -11,7 +11,6 @@ #include "KRResource.h" #include "KRNode.h" -#include "KRTexture.h" class KRLODGroup : public KRNode { public: diff --git a/KREngine/kraken/KRLODSet.cpp b/KREngine/kraken/KRLODSet.cpp new file mode 100644 index 0000000..93fe90d --- /dev/null +++ b/KREngine/kraken/KRLODSet.cpp @@ -0,0 +1,35 @@ +// +// KRLODSet.cpp +// KREngine +// +// Created by Kearwood Gilbert on 2012-12-06. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#include "KRLODSet.h" +#include "KRContext.h" + +KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name) +{ + +} + +KRLODSet::~KRLODSet() +{ +} + +std::string KRLODSet::getElementName() { + return "lod_set"; +} + +tinyxml2::XMLElement *KRLODSet::saveXML( tinyxml2::XMLNode *parent) +{ + tinyxml2::XMLElement *e = KRNode::saveXML(parent); + + return e; +} + +void KRLODSet::loadXML(tinyxml2::XMLElement *e) +{ + KRNode::loadXML(e); +} diff --git a/KREngine/kraken/KRLODSet.h b/KREngine/kraken/KRLODSet.h new file mode 100644 index 0000000..cbb5337 --- /dev/null +++ b/KREngine/kraken/KRLODSet.h @@ -0,0 +1,26 @@ +// +// KRLODSet +// KREngine +// +// Created by Kearwood Gilbert on 2012-12-06. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#ifndef KRLODSET_H +#define KRLODSET_H + +#include "KRResource.h" +#include "KRNode.h" + +class KRLODSet : public KRNode { +public: + KRLODSet(KRScene &scene, std::string name); + virtual ~KRLODSet(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); + virtual void loadXML(tinyxml2::XMLElement *e); + +}; + + +#endif diff --git a/KREngine/kraken/KRLocator.cpp b/KREngine/kraken/KRLocator.cpp index 13d8878..1794062 100644 --- a/KREngine/kraken/KRLocator.cpp +++ b/KREngine/kraken/KRLocator.cpp @@ -11,7 +11,7 @@ KRLocator::KRLocator(KRScene &scene, std::string name) : KRNode(scene, name) { - setScaleCompensation(true); + } KRLocator::~KRLocator() diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 2e9c36c..87c2f66 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -404,11 +404,10 @@ bool KRScene::save(KRDataBlock &data) { KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock *data) { - data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely + std::string xml_string = data->getString(); + delete data; tinyxml2::XMLDocument doc; - data->lock(); - doc.Parse((char *)data->getStart()); - data->unlock(); + doc.Parse(xml_string.c_str()); KRScene *new_scene = new KRScene(context, name); tinyxml2::XMLElement *scene_element = doc.RootElement(); @@ -420,7 +419,7 @@ KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock new_scene->getRootNode()->addChild(n); } - delete data; + return new_scene; } diff --git a/KREngine/kraken/KRTexture2D.cpp b/KREngine/kraken/KRTexture2D.cpp index ea2a922..da79d62 100644 --- a/KREngine/kraken/KRTexture2D.cpp +++ b/KREngine/kraken/KRTexture2D.cpp @@ -36,11 +36,9 @@ KRTexture2D::KRTexture2D(KRContext &context, KRDataBlock *data, std::string name) : KRTexture(context, name) { m_current_lod_max_dim = 0; m_pData = data; - m_pData->lock(); } KRTexture2D::~KRTexture2D() { - m_pData->unlock(); delete m_pData; } diff --git a/KREngine/kraken/KRTexturePVR.cpp b/KREngine/kraken/KRTexturePVR.cpp index 63d6f4f..44d0b07 100644 --- a/KREngine/kraken/KRTexturePVR.cpp +++ b/KREngine/kraken/KRTexturePVR.cpp @@ -87,7 +87,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na m_iHeight = header->height; m_bHasAlpha = header->bitmaskAlpha; - uint8_t *bytes = ((uint8_t *)m_pData->getStart()) + sizeof(PVRTexHeader); + uint32_t dataStart = sizeof(PVRTexHeader); uint32_t dataLength = header->dataLength, dataOffset = 0, dataSize = 0; uint32_t width = m_iWidth, height = m_iHeight, bpp = 4; uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0; @@ -116,7 +116,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8); dataBlockStruct newBlock; - newBlock.start = bytes+dataOffset; + newBlock.start = dataStart + dataOffset; newBlock.length = dataSize; m_blocks.push_back(newBlock); @@ -245,16 +245,20 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo GLDEBUG(glCopyTextureLevelsAPPLE(m_iHandle, prev_handle, source_level, 1)); } else { // glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); - GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, block.start)); + m_pData->lock(); + GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, (char *)m_pData->getStart() + block.start)); + m_pData->unlock(); // GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, block.start)); memoryTransferred += block.length; // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE } #else + m_pData->lock(); #if GL_EXT_texture_storage - GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, block.start)); + GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, (char *)m_pData->getStart() + block.start)); #else - GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, block.start)); + GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, (char *)m_pData->getStart() + block.start)); #endif + m_pData->unlock(); memoryTransferred += block.length; // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE #endif memoryRequired += block.length; diff --git a/KREngine/kraken/KRTexturePVR.h b/KREngine/kraken/KRTexturePVR.h index db7f9c7..515387b 100644 --- a/KREngine/kraken/KRTexturePVR.h +++ b/KREngine/kraken/KRTexturePVR.h @@ -30,7 +30,7 @@ protected: bool m_bHasAlpha; struct dataBlockStruct { - void *start; + uint32_t start; uint32_t length; }; diff --git a/KREngine/kraken/KRTextureTGA.cpp b/KREngine/kraken/KRTextureTGA.cpp index 294c17b..e04d5a7 100644 --- a/KREngine/kraken/KRTextureTGA.cpp +++ b/KREngine/kraken/KRTextureTGA.cpp @@ -42,11 +42,13 @@ KRTextureTGA::~KRTextureTGA() } bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) -{ +{ + m_pData->lock(); TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); unsigned char *pData = (unsigned char *)pHeader + (long)pHeader->idlength + (long)pHeader->colourmaplength * (long)pHeader->colourmaptype + sizeof(TGA_HEADER); if(pHeader->colourmaptype != 0) { + m_pData->unlock(); return false; // Mapped colors not supported } @@ -78,6 +80,7 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo free(converted_image); err = glGetError(); if (err != GL_NO_ERROR) { + m_pData->unlock(); return false; } int memAllocated = pHeader->width * pHeader->height * 4; @@ -92,6 +95,7 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pData); err = glGetError(); if (err != GL_NO_ERROR) { + m_pData->unlock(); return false; } int memAllocated = pHeader->width * pHeader->height * 4; @@ -102,13 +106,16 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo } break; default: + m_pData->unlock(); return false; // 16-bit images not yet supported } break; default: + m_pData->unlock(); return false; // Image type not yet supported } + m_pData->unlock(); return true; } From 06436d72f5f9e9c1579c76acdc50a18e60cc813c Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 2 Nov 2013 01:08:51 -0700 Subject: [PATCH 15/43] Asynchronous streaming and memory management improvements in progress. --HG-- branch : async_streaming --- KREngine/Kraken.xcodeproj/project.pbxproj | 24 ++++++++++ KREngine/kraken/KRDataBlock.cpp | 3 +- KREngine/kraken/KREngine-common.h | 3 ++ KREngine/kraken/KRMeshManager.cpp | 2 +- KREngine/kraken/KRMeshManager.h | 4 ++ KREngine/kraken/KRMeshStreamer.cpp | 33 +++++++++++++ KREngine/kraken/KRMeshStreamer.h | 57 +++++++++++++++++++++++ KREngine/kraken/KRTextureManager.cpp | 2 +- KREngine/kraken/KRTextureManager.h | 3 ++ KREngine/kraken/KRTextureStreamer.cpp | 33 +++++++++++++ KREngine/kraken/KRTextureStreamer.h | 57 +++++++++++++++++++++++ 11 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 KREngine/kraken/KRMeshStreamer.cpp create mode 100644 KREngine/kraken/KRMeshStreamer.h create mode 100644 KREngine/kraken/KRTextureStreamer.cpp create mode 100644 KREngine/kraken/KRTextureStreamer.h diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index 471adaa..eaf6e96 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -77,6 +77,14 @@ E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; + E43F70E51824D9AB00136169 /* KRTextureStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */; }; + E43F70E61824D9AB00136169 /* KRTextureStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */; }; + E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; + E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; + E43F70FF1824E73100136169 /* KRMeshStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */; }; + E43F71001824E73100136169 /* KRMeshStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */; }; + E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; + E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; }; E44F38241683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (); }; }; E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -429,6 +437,10 @@ E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = ""; }; E43F70DA181B20E300136169 /* KRLODSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODSet.cpp; sourceTree = ""; }; E43F70DB181B20E400136169 /* KRLODSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODSet.h; sourceTree = ""; }; + E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureStreamer.cpp; sourceTree = ""; }; + E43F70E41824D9AB00136169 /* KRTextureStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureStreamer.h; sourceTree = ""; }; + E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRMeshStreamer.cpp; sourceTree = ""; }; + E43F70FE1824E73100136169 /* KRMeshStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshStreamer.h; sourceTree = ""; }; E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = ""; }; E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = ""; }; E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -890,6 +902,8 @@ E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */, E460292516681CFE00261BB9 /* KRTextureAnimated.h */, E460292716681D1000261BB9 /* KRTextureAnimated.cpp */, + E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */, + E43F70E41824D9AB00136169 /* KRTextureStreamer.h */, ); name = Texture; sourceTree = ""; @@ -905,6 +919,8 @@ E4C454AE167BB8FC003586CD /* KRMeshCube.cpp */, E4C454B1167BC04B003586CD /* KRMeshSphere.h */, E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */, + E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */, + E43F70FE1824E73100136169 /* KRMeshStreamer.h */, ); name = Mesh; sourceTree = ""; @@ -1216,6 +1232,7 @@ E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */, E461A168152E570700F2044A /* KRSpotLight.h in Headers */, E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */, + E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */, E4F975321536220900FD60B2 /* KRNode.h in Headers */, E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */, E48C696F15374F5B00232E28 /* KRContext.h in Headers */, @@ -1264,6 +1281,7 @@ E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */, E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */, E48CF944173453990005EBBB /* KRFloat.h in Headers */, + E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */, E45134B81746A4A300443C21 /* KRBehavior.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1291,7 +1309,9 @@ E4F9754C153632F000FD60B2 /* KRCamera.h in Headers */, E4F975501536333500FD60B2 /* KRMesh.h in Headers */, E488399F15F92BE000BD66D5 /* KRBundleManager.h in Headers */, + E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */, E4AFC6BC15F7C95D00DDB4C8 /* KRSceneManager.h in Headers */, + E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */, E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */, E4D133661537685A0070068C /* KRShader.h in Headers */, E461A153152E54B500F2044A /* KRLight.h in Headers */, @@ -1563,6 +1583,7 @@ E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */, E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */, + E43F70FF1824E73100136169 /* KRMeshStreamer.cpp in Sources */, E461A156152E54F800F2044A /* KRLight.cpp in Sources */, E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */, E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */, @@ -1588,6 +1609,7 @@ E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */, + E43F70E51824D9AB00136169 /* KRTextureStreamer.cpp in Sources */, E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */, E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */, E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */, @@ -1660,6 +1682,7 @@ E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */, E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */, E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */, + E43F71001824E73100136169 /* KRMeshStreamer.cpp in Sources */, E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, @@ -1675,6 +1698,7 @@ E428C31A1669A25D00A16EDF /* KRAnimationAttribute.cpp in Sources */, E416AA9D1671375C000F6786 /* KRAnimationCurveManager.cpp in Sources */, E480BE6D1671C653004EC8AD /* KRBone.cpp in Sources */, + E43F70E61824D9AB00136169 /* KRTextureStreamer.cpp in Sources */, E4C454B0167BB8FC003586CD /* KRMeshCube.cpp in Sources */, E4C454B6167BC05C003586CD /* KRMeshSphere.cpp in Sources */, E4C454BC167BD248003586CD /* KRHitInfo.cpp in Sources */, diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index c92a1e6..c420a50 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -31,6 +31,7 @@ #include "KRDataBlock.h" #include "KREngine-common.h" +#include "KRResource.h" KRDataBlock::KRDataBlock() { m_data = NULL; @@ -97,7 +98,7 @@ bool KRDataBlock::load(const std::string &path) m_fdPackFile = open(path.c_str(), O_RDONLY); if(m_fdPackFile >= 0) { m_fileOwnerDataBlock = this; - m_fileName = path; + m_fileName = KRResource::GetFileBase(path); if(fstat(m_fdPackFile, &statbuf) >= 0) { m_data_size = statbuf.st_size; m_data_offset = 0; diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 5ad60fc..8ad0ac6 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -45,6 +45,9 @@ float const D2R = PI * 2 / 360; #include #include +#include +#include + #include "tinyxml2.h" diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 110416d..9905f3b 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -37,7 +37,7 @@ #include "KRMeshCube.h" #include "KRMeshSphere.h" -KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context) { +KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_streamer(context) { m_currentVBO.vbo_handle = -1; m_currentVBO.vbo_handle_indexes = -1; m_currentVBO.vao_handle = -1; diff --git a/KREngine/kraken/KRMeshManager.h b/KREngine/kraken/KRMeshManager.h index 6e17df4..3d8910c 100644 --- a/KREngine/kraken/KRMeshManager.h +++ b/KREngine/kraken/KRMeshManager.h @@ -37,6 +37,8 @@ #include "KRDataBlock.h" #include "KRNode.h" +#include "KRMeshStreamer.h" + class KRContext; class KRMesh; @@ -135,6 +137,8 @@ private: std::vector m_draw_calls; bool m_draw_call_logging_enabled; bool m_draw_call_log_used; + + KRMeshStreamer m_streamer; }; diff --git a/KREngine/kraken/KRMeshStreamer.cpp b/KREngine/kraken/KRMeshStreamer.cpp new file mode 100644 index 0000000..51b1902 --- /dev/null +++ b/KREngine/kraken/KRMeshStreamer.cpp @@ -0,0 +1,33 @@ +// +// KRMeshStreamer.cpp +// Kraken +// +// Created by Kearwood Gilbert on 11/1/2013. +// Copyright (c) 2013 Kearwood Software. All rights reserved. +// + +#include "KRMeshStreamer.h" + +#include + +KRMeshStreamer::KRMeshStreamer(KRContext &context) : m_context(context) +{ + m_stop = false; + m_thread = std::thread(&KRMeshStreamer::run, this); +} + +KRMeshStreamer::~KRMeshStreamer() +{ + m_stop = true; + m_thread.join(); +} + +void KRMeshStreamer::run() +{ + std::chrono::microseconds sleep_duration( 100 ); + + while(!m_stop) + { + std::this_thread::sleep_for( sleep_duration ); + } +} diff --git a/KREngine/kraken/KRMeshStreamer.h b/KREngine/kraken/KRMeshStreamer.h new file mode 100644 index 0000000..a0c36e9 --- /dev/null +++ b/KREngine/kraken/KRMeshStreamer.h @@ -0,0 +1,57 @@ +// +// KRMeshManager.h +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +#ifndef KRMESHSTREAMER_H +#define KRMESHSTREAMER_H + +#include "KREngine-common.h" + +#include +#include + +class KRContext; + +class KRMeshStreamer +{ +public: + KRMeshStreamer(KRContext &context); + ~KRMeshStreamer(); + +private: + KRContext &m_context; + + std::thread m_thread; + std::atomic m_stop; + + void run(); +}; + +#endif /* defined(KRMESHSTREAMER_H) */ diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index c81d104..643a7f3 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -39,7 +39,7 @@ #include "KRTextureAnimated.h" #include "KRContext.h" -KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context) { +KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context), m_streamer(context) { m_textureMemUsed = 0; for(int iTexture=0; iTexture + +KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context) +{ + m_stop = false; + m_thread = std::thread(&KRTextureStreamer::run, this); +} + +KRTextureStreamer::~KRTextureStreamer() +{ + m_stop = true; + m_thread.join(); +} + +void KRTextureStreamer::run() +{ + std::chrono::microseconds sleep_duration( 100 ); + + while(!m_stop) + { + std::this_thread::sleep_for( sleep_duration ); + } +} diff --git a/KREngine/kraken/KRTextureStreamer.h b/KREngine/kraken/KRTextureStreamer.h new file mode 100644 index 0000000..b370871 --- /dev/null +++ b/KREngine/kraken/KRTextureStreamer.h @@ -0,0 +1,57 @@ +// +// KRTextureManager.h +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +#ifndef KRTEXTURESTREAMER_H +#define KRTEXTURESTREAMER_H + +#include "KREngine-common.h" + +#include +#include + +class KRContext; + +class KRTextureStreamer +{ +public: + KRTextureStreamer(KRContext &context); + ~KRTextureStreamer(); + +private: + KRContext &m_context; + + std::thread m_thread; + std::atomic m_stop; + + void run(); +}; + +#endif /* defined(KRTEXTURESTREAMER_H) */ From 48d3a6a2c8a003a7e029b4bad88b3c1945e7f17c Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 2 Nov 2013 16:27:24 -0700 Subject: [PATCH 16/43] Asynchronous streaming and memory management improvements in progress. --HG-- branch : async_streaming --- KREngine/Kraken.xcodeproj/project.pbxproj | 24 +++++----- KREngine/kraken/KRAudioSample.cpp | 4 -- KREngine/kraken/KRDataBlock.cpp | 47 +++++++++++++++++- KREngine/kraken/KREngine-common.h | 3 +- KREngine/kraken/KRMeshManager.h | 1 - .../{KRMeshStreamer.cpp => KRMeshStreamer.mm} | 8 ++++ KREngine/kraken/KRTexture.cpp | 48 +++++++++++++++---- KREngine/kraken/KRTexture.h | 10 +++- KREngine/kraken/KRTexture2D.cpp | 33 ++++++------- KREngine/kraken/KRTexture2D.h | 2 +- KREngine/kraken/KRTextureAnimated.cpp | 1 + KREngine/kraken/KRTextureCube.cpp | 33 ++++++------- KREngine/kraken/KRTextureManager.cpp | 7 ++- KREngine/kraken/KRTexturePVR.cpp | 7 +-- KREngine/kraken/KRTexturePVR.h | 2 +- ...xtureStreamer.cpp => KRTextureStreamer.mm} | 8 ++++ KREngine/kraken/KRTextureTGA.cpp | 2 +- KREngine/kraken/KRTextureTGA.h | 2 +- 18 files changed, 167 insertions(+), 75 deletions(-) rename KREngine/kraken/{KRMeshStreamer.cpp => KRMeshStreamer.mm} (66%) rename KREngine/kraken/{KRTextureStreamer.cpp => KRTextureStreamer.mm} (66%) diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index eaf6e96..b3554fb 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -77,12 +77,12 @@ E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; - E43F70E51824D9AB00136169 /* KRTextureStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */; }; - E43F70E61824D9AB00136169 /* KRTextureStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */; }; + E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; + E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; - E43F70FF1824E73100136169 /* KRMeshStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */; }; - E43F71001824E73100136169 /* KRMeshStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */; }; + E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; + E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; }; @@ -437,9 +437,9 @@ E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = ""; }; E43F70DA181B20E300136169 /* KRLODSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODSet.cpp; sourceTree = ""; }; E43F70DB181B20E400136169 /* KRLODSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODSet.h; sourceTree = ""; }; - E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureStreamer.cpp; sourceTree = ""; }; + E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRTextureStreamer.mm; sourceTree = ""; }; E43F70E41824D9AB00136169 /* KRTextureStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureStreamer.h; sourceTree = ""; }; - E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRMeshStreamer.cpp; sourceTree = ""; }; + E43F70FD1824E73100136169 /* KRMeshStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRMeshStreamer.mm; sourceTree = ""; }; E43F70FE1824E73100136169 /* KRMeshStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshStreamer.h; sourceTree = ""; }; E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = ""; }; E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = ""; }; @@ -902,7 +902,7 @@ E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */, E460292516681CFE00261BB9 /* KRTextureAnimated.h */, E460292716681D1000261BB9 /* KRTextureAnimated.cpp */, - E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */, + E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */, E43F70E41824D9AB00136169 /* KRTextureStreamer.h */, ); name = Texture; @@ -919,7 +919,7 @@ E4C454AE167BB8FC003586CD /* KRMeshCube.cpp */, E4C454B1167BC04B003586CD /* KRMeshSphere.h */, E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */, - E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */, + E43F70FD1824E73100136169 /* KRMeshStreamer.mm */, E43F70FE1824E73100136169 /* KRMeshStreamer.h */, ); name = Mesh; @@ -1583,7 +1583,7 @@ E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */, E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */, - E43F70FF1824E73100136169 /* KRMeshStreamer.cpp in Sources */, + E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */, E461A156152E54F800F2044A /* KRLight.cpp in Sources */, E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */, E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */, @@ -1609,7 +1609,7 @@ E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */, - E43F70E51824D9AB00136169 /* KRTextureStreamer.cpp in Sources */, + E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */, E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */, E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */, E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */, @@ -1682,7 +1682,7 @@ E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */, E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */, E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */, - E43F71001824E73100136169 /* KRMeshStreamer.cpp in Sources */, + E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */, E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, @@ -1698,7 +1698,7 @@ E428C31A1669A25D00A16EDF /* KRAnimationAttribute.cpp in Sources */, E416AA9D1671375C000F6786 /* KRAnimationCurveManager.cpp in Sources */, E480BE6D1671C653004EC8AD /* KRBone.cpp in Sources */, - E43F70E61824D9AB00136169 /* KRTextureStreamer.cpp in Sources */, + E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */, E4C454B0167BB8FC003586CD /* KRMeshCube.cpp in Sources */, E4C454B6167BC05C003586CD /* KRMeshSphere.cpp in Sources */, E4C454BC167BD248003586CD /* KRHitInfo.cpp in Sources */, diff --git a/KREngine/kraken/KRAudioSample.cpp b/KREngine/kraken/KRAudioSample.cpp index b9bd250..b115711 100644 --- a/KREngine/kraken/KRAudioSample.cpp +++ b/KREngine/kraken/KRAudioSample.cpp @@ -40,7 +40,6 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension) : KRResource(context, name) { m_pData = new KRDataBlock(); - m_pData->lock(); m_extension = extension; m_audio_file_id = 0; @@ -56,7 +55,6 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name) { m_pData = data; - m_pData->lock(); m_extension = extension; m_audio_file_id = 0; @@ -73,7 +71,6 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e KRAudioSample::~KRAudioSample() { closeFile(); - m_pData->unlock(); delete m_pData; } @@ -202,7 +199,6 @@ OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc UInt32 max_count = sound->m_pData->getSize() - inPosition; *actualCount = requestCount < max_count ? requestCount : max_count; sound->m_pData->copy(buffer, inPosition, *actualCount); - //memcpy(buffer, (unsigned char *)sound->m_pData->getStart() + inPosition, *actualCount); return noErr; } diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index c420a50..33050ad 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -33,6 +33,12 @@ #include "KREngine-common.h" #include "KRResource.h" +#include + +int m_mapCount = 0; +size_t m_mapSize = 0; +size_t m_mapOverhead = 0; + KRDataBlock::KRDataBlock() { m_data = NULL; m_data_size = 0; @@ -271,17 +277,49 @@ void KRDataBlock::lock() { m_lockCount++; + if(m_lockCount == 1) { // Memory mapped file; ensure data is mapped to ram if(m_fdPackFile) { - fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + //fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); // Round m_data_offset down to the next memory page, as required by mmap size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) { + int iError = errno; + switch(iError) { + case EACCES: + fprintf(stderr, "mmap failed with EACCES\n"); + break; + case EBADF: + fprintf(stderr, "mmap failed with EBADF\n"); + break; + case EMFILE: + fprintf(stderr, "mmap failed with EMFILE\n"); + break; + case EINVAL: + fprintf(stderr, "mmap failed with EINVAL\n"); + break; + case ENOMEM: + fprintf(stderr, "mmap failed with ENOMEM\n"); + break; + case ENXIO: + fprintf(stderr, "mmap failed with ENXIO\n"); + break; + case EOVERFLOW: + fprintf(stderr, "mmap failed with EOVERFLOW\n"); + break; + default: + fprintf(stderr, "mmap failed with errno: %i\n", iError); + break; + } assert(false); // mmap() failed. } + m_mapCount++; + m_mapSize += m_data_size; + m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; + fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); m_data = (unsigned char *)m_mmapData + alignment_offset; } @@ -299,11 +337,16 @@ void KRDataBlock::unlock() // Memory mapped file; ensure data is unmapped from ram if(m_fdPackFile) { - fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + //fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); munmap(m_mmapData, m_data_size); m_data = NULL; m_mmapData = NULL; + m_mapCount--; + m_mapSize -= m_data_size; + size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); + m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; + fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); } } diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 8ad0ac6..fbde9bc 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -72,7 +72,8 @@ using std::queue; int KRAKEN_MEM_PAGE_SIZE = getpagesize(); -#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) (x & ~(KRAKEN_MEM_PAGE_SIZE - 1)) +#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) ((x) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) +#define KRAKEN_MEM_ROUND_UP_PAGE(x) ((((x) - 1) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) + KRAKEN_MEM_PAGE_SIZE) #define KRENGINE_MAX_TEXTURE_UNITS 8 diff --git a/KREngine/kraken/KRMeshManager.h b/KREngine/kraken/KRMeshManager.h index 3d8910c..f1782b4 100644 --- a/KREngine/kraken/KRMeshManager.h +++ b/KREngine/kraken/KRMeshManager.h @@ -110,7 +110,6 @@ public: void log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count); std::vector getDrawCalls(); - private: unordered_multimap m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model diff --git a/KREngine/kraken/KRMeshStreamer.cpp b/KREngine/kraken/KRMeshStreamer.mm similarity index 66% rename from KREngine/kraken/KRMeshStreamer.cpp rename to KREngine/kraken/KRMeshStreamer.mm index 51b1902..b2aa5de 100644 --- a/KREngine/kraken/KRMeshStreamer.cpp +++ b/KREngine/kraken/KRMeshStreamer.mm @@ -8,10 +8,15 @@ #include "KRMeshStreamer.h" +#include "KREngine-common.h" + #include +EAGLContext *gMeshStreamerContext; + KRMeshStreamer::KRMeshStreamer(KRContext &context) : m_context(context) { + gMeshStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; m_stop = false; m_thread = std::thread(&KRMeshStreamer::run, this); } @@ -20,11 +25,14 @@ KRMeshStreamer::~KRMeshStreamer() { m_stop = true; m_thread.join(); + + [gMeshStreamerContext release]; } void KRMeshStreamer::run() { std::chrono::microseconds sleep_duration( 100 ); + [EAGLContext setCurrentContext: gMeshStreamerContext]; while(!m_stop) { diff --git a/KREngine/kraken/KRTexture.cpp b/KREngine/kraken/KRTexture.cpp index 24aee65..5c0830c 100644 --- a/KREngine/kraken/KRTexture.cpp +++ b/KREngine/kraken/KRTexture.cpp @@ -15,16 +15,24 @@ KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name) { m_iHandle = 0; + m_iNewHandle = 0; m_textureMemUsed = 0; + m_newTextureMemUsed = 0; m_last_frame_used = 0; + m_last_frame_bound = 0; } KRTexture::~KRTexture() { - releaseHandle(); + releaseHandles(); } -void KRTexture::releaseHandle() { +void KRTexture::releaseHandles() { + if(m_iNewHandle != 0) { + GLDEBUG(glDeleteTextures(1, &m_iNewHandle)); + m_iNewHandle = 0; + m_newTextureMemUsed = 0; + } if(m_iHandle != 0) { GLDEBUG(glDeleteTextures(1, &m_iHandle)); getContext().getTextureManager()->memoryChanged(-getMemSize()); @@ -34,7 +42,7 @@ void KRTexture::releaseHandle() { } long KRTexture::getMemSize() { - return m_textureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory + return m_textureMemUsed + m_newTextureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory } long KRTexture::getReferencedMemSize() { @@ -44,8 +52,10 @@ long KRTexture::getReferencedMemSize() { void KRTexture::resize(int max_dim) { + assert(m_iHandle == m_iNewHandle); // Only allow one resize() per frame + if(max_dim == 0) { - releaseHandle(); + m_iNewHandle = 0; } else { int target_dim = max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; @@ -65,7 +75,7 @@ void KRTexture::resize(int max_dim) return; } - if(m_current_lod_max_dim != target_dim || m_iHandle == 0) { + if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) { if(!createGLTexture(target_dim)) { assert(false); } @@ -74,12 +84,12 @@ void KRTexture::resize(int max_dim) } } - GLuint KRTexture::getHandle() { - if(m_iHandle == 0) { - //resize(getContext().KRENGINE_MIN_TEXTURE_DIM); + /* + if(m_iHandle == 0 && m_iNewHandle == 0) { resize(m_min_lod_max_dim); } + */ resetPoolExpiry(); return m_iHandle; } @@ -147,3 +157,25 @@ int KRTexture::getMinMipMap() { bool KRTexture::hasMipmaps() { return m_max_lod_max_dim != m_min_lod_max_dim; } + +void KRTexture::bind(GLuint texture_unit) { + m_last_frame_bound = getContext().getCurrentFrame(); +} + +bool KRTexture::canStreamOut() const { + return (m_last_frame_bound + 2 > getContext().getCurrentFrame()); +} + +void KRTexture::_swapHandles() +{ + if(m_iNewHandle != m_iHandle) { + if(m_iHandle != 0) { + GLDEBUG(glDeleteTextures(1, &m_iHandle)); + getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed - m_textureMemUsed); + m_textureMemUsed = m_newTextureMemUsed; + m_newTextureMemUsed = 0; + } + m_iHandle = m_iNewHandle; + } +} + diff --git a/KREngine/kraken/KRTexture.h b/KREngine/kraken/KRTexture.h index 1a38e4f..8ecd169 100644 --- a/KREngine/kraken/KRTexture.h +++ b/KREngine/kraken/KRTexture.h @@ -46,8 +46,8 @@ public: KRTexture(KRContext &context, std::string name); virtual ~KRTexture(); - virtual void bind(GLuint texture_unit) = 0; - void releaseHandle(); + virtual void bind(GLuint texture_unit); + void releaseHandles(); long getMemSize(); virtual long getReferencedMemSize(); @@ -66,13 +66,18 @@ public: int getMinMipMap(); bool hasMipmaps(); + bool canStreamOut() const; + + void _swapHandles(); protected: virtual bool createGLTexture(int lod_max_dim) = 0; GLuint getHandle(); GLuint m_iHandle; + GLuint m_iNewHandle; long m_textureMemUsed; + long m_newTextureMemUsed; int m_current_lod_max_dim; @@ -80,6 +85,7 @@ protected: uint32_t m_min_lod_max_dim; long m_last_frame_used; + long m_last_frame_bound; }; diff --git a/KREngine/kraken/KRTexture2D.cpp b/KREngine/kraken/KRTexture2D.cpp index da79d62..e5d6138 100644 --- a/KREngine/kraken/KRTexture2D.cpp +++ b/KREngine/kraken/KRTexture2D.cpp @@ -43,54 +43,52 @@ KRTexture2D::~KRTexture2D() { } bool KRTexture2D::createGLTexture(int lod_max_dim) { + if(m_iHandle != m_iNewHandle) { + return true; + } + bool success = true; - GLuint prev_handle = 0; int prev_lod_max_dim = 0; long prev_mem_size = 0; #if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage if(m_iHandle != 0) { - prev_handle = m_iHandle; prev_mem_size = getMemSize(); - m_iHandle = 0; m_textureMemUsed = 0; prev_lod_max_dim = m_current_lod_max_dim; } -#else - releaseHandle(); #endif + m_iNewHandle = 0; m_current_lod_max_dim = 0; - GLDEBUG(glGenTextures(1, &m_iHandle)); + GLDEBUG(glGenTextures(1, &m_iNewHandle)); - if(m_iHandle == 0) { + if(m_iNewHandle == 0) { success = false; } else { - GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iHandle)); + GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iNewHandle)); if (hasMipmaps()) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); } else { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); } - if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, m_textureMemUsed, prev_lod_max_dim, prev_handle)) { - GLDEBUG(glDeleteTextures(1, &m_iHandle)); - m_iHandle = 0; - m_current_lod_max_dim = 0; + if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, m_newTextureMemUsed, prev_lod_max_dim)) { + GLDEBUG(glDeleteTextures(1, &m_iNewHandle)); + getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed); + m_newTextureMemUsed = 0; + m_iNewHandle = m_iHandle; + m_current_lod_max_dim = prev_lod_max_dim; success = false; } } - if(prev_handle != 0) { - getContext().getTextureManager()->memoryChanged(-prev_mem_size); - GLDEBUG(glDeleteTextures(1, &prev_handle)); - } - return success; } void KRTexture2D::bind(GLuint texture_unit) { + KRTexture::bind(texture_unit); GLuint handle = getHandle(); GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle)); @@ -101,7 +99,6 @@ void KRTexture2D::bind(GLuint texture_unit) { } } - bool KRTexture2D::save(const std::string& path) { if(m_pData) { diff --git a/KREngine/kraken/KRTexture2D.h b/KREngine/kraken/KRTexture2D.h index f3e8684..87efc8f 100644 --- a/KREngine/kraken/KRTexture2D.h +++ b/KREngine/kraken/KRTexture2D.h @@ -46,7 +46,7 @@ public: virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data); - virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) = 0; + virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) = 0; virtual void bind(GLuint texture_unit); protected: diff --git a/KREngine/kraken/KRTextureAnimated.cpp b/KREngine/kraken/KRTextureAnimated.cpp index c3b5669..a38d970 100644 --- a/KREngine/kraken/KRTextureAnimated.cpp +++ b/KREngine/kraken/KRTextureAnimated.cpp @@ -114,6 +114,7 @@ void KRTextureAnimated::resetPoolExpiry() void KRTextureAnimated::bind(GLuint texture_unit) { + KRTexture::bind(texture_unit); int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count)); KRTexture2D *frame_texture = textureForFrame(frame_number); if(frame_texture) { diff --git a/KREngine/kraken/KRTextureCube.cpp b/KREngine/kraken/KRTextureCube.cpp index a9e532d..710aef0 100644 --- a/KREngine/kraken/KRTextureCube.cpp +++ b/KREngine/kraken/KRTextureCube.cpp @@ -55,32 +55,30 @@ KRTextureCube::~KRTextureCube() bool KRTextureCube::createGLTexture(int lod_max_dim) { + assert(m_iNewHandle == m_iHandle); // Only allow one resize per frame + bool success = true; - GLuint prev_handle = 0; int prev_lod_max_dim = 0; - long prev_mem_size = 0; #if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage if(m_iHandle != 0) { - prev_handle = m_iHandle; - prev_mem_size = getMemSize(); - m_iHandle = 0; - m_textureMemUsed = 0; prev_lod_max_dim = m_current_lod_max_dim; } -#else - releaseHandle(); #endif - m_current_lod_max_dim = 0; - GLDEBUG(glGenTextures(1, &m_iHandle)); - if(m_iHandle == 0) { + + + + m_iNewHandle = 0; + GLDEBUG(glGenTextures(1, &m_iNewHandle)); + if(m_iNewHandle == 0) { + m_iNewHandle = m_iHandle; success = false; } else { - - GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iHandle)); + m_current_lod_max_dim = 0; + GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iNewHandle)); bool bMipMaps = false; @@ -89,7 +87,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim) KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); if(faceTexture) { if(faceTexture->hasMipmaps()) bMipMaps = true; - faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, m_textureMemUsed, prev_lod_max_dim, prev_handle); + faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, m_newTextureMemUsed, prev_lod_max_dim); } } @@ -101,11 +99,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim) GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); } } - - if(prev_handle != 0) { - getContext().getTextureManager()->memoryChanged(-prev_mem_size); - GLDEBUG(glDeleteTextures(1, &prev_handle)); - } + return success; } @@ -141,6 +135,7 @@ void KRTextureCube::resetPoolExpiry() void KRTextureCube::bind(GLuint texture_unit) { + KRTexture::bind(texture_unit); GLuint handle = getHandle(); GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, handle)); if(handle) { diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 643a7f3..e258841 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -216,6 +216,10 @@ long KRTextureManager::getMemActive() { void KRTextureManager::startFrame(float deltaTime) { _clearGLState(); + for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { + KRTexture *activeTexture = *itr; + activeTexture->_swapHandles(); + } m_memoryTransferredThisFrame = 0; balanceTextureMemory(); rotateBuffers(); @@ -310,7 +314,7 @@ void KRTextureManager::rotateBuffers() KRTexture *poolTexture = *itr; if(poolTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { expiredTextures.insert(poolTexture); - poolTexture->releaseHandle(); + poolTexture->releaseHandles(); } } for(std::set::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) { @@ -318,6 +322,7 @@ void KRTextureManager::rotateBuffers() } // ----====---- Swap the buffers ----====---- + m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end()); m_activeTextures.clear(); } diff --git a/KREngine/kraken/KRTexturePVR.cpp b/KREngine/kraken/KRTexturePVR.cpp index 44d0b07..4765597 100644 --- a/KREngine/kraken/KRTexturePVR.cpp +++ b/KREngine/kraken/KRTexturePVR.cpp @@ -135,6 +135,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight; m_min_lod_max_dim = width > height ? width : height; + m_pData->unlock(); #endif } @@ -172,7 +173,7 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim) return memoryRequired; } -bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) +bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) { int target_dim = lod_max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; @@ -242,7 +243,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo if(target == GL_TEXTURE_2D && width <= prev_lod_max_dim && height <= prev_lod_max_dim) { //GLDEBUG(glCompressedTexImage2D(target, i, m_internalFormat, width, height, 0, block.length, NULL)); // Allocate, but don't copy // GLDEBUG(glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); - GLDEBUG(glCopyTextureLevelsAPPLE(m_iHandle, prev_handle, source_level, 1)); + GLDEBUG(glCopyTextureLevelsAPPLE(m_iNewHandle, m_iHandle, source_level, 1)); } else { // glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); m_pData->lock(); @@ -288,7 +289,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo } textureMemUsed += memoryRequired; - getContext().getTextureManager()->memoryChanged(memoryTransferred); + getContext().getTextureManager()->memoryChanged(memoryRequired); getContext().getTextureManager()->addMemoryTransferredThisFrame(memoryTransferred); return true; diff --git a/KREngine/kraken/KRTexturePVR.h b/KREngine/kraken/KRTexturePVR.h index 515387b..97c6505 100644 --- a/KREngine/kraken/KRTexturePVR.h +++ b/KREngine/kraken/KRTexturePVR.h @@ -18,7 +18,7 @@ public: virtual ~KRTexturePVR(); virtual std::string getExtension(); - bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle); + bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim); virtual long getMemRequiredForSize(int max_dim); diff --git a/KREngine/kraken/KRTextureStreamer.cpp b/KREngine/kraken/KRTextureStreamer.mm similarity index 66% rename from KREngine/kraken/KRTextureStreamer.cpp rename to KREngine/kraken/KRTextureStreamer.mm index a968cc0..004b2d9 100644 --- a/KREngine/kraken/KRTextureStreamer.cpp +++ b/KREngine/kraken/KRTextureStreamer.mm @@ -6,12 +6,17 @@ // Copyright (c) 2013 Kearwood Software. All rights reserved. // +#include "KREngine-common.h" + #include "KRTextureStreamer.h" #include +EAGLContext *gTextureStreamerContext; + KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context) { + gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; m_stop = false; m_thread = std::thread(&KRTextureStreamer::run, this); } @@ -20,11 +25,14 @@ KRTextureStreamer::~KRTextureStreamer() { m_stop = true; m_thread.join(); + + [gTextureStreamerContext release]; } void KRTextureStreamer::run() { std::chrono::microseconds sleep_duration( 100 ); + [EAGLContext setCurrentContext: gTextureStreamerContext]; while(!m_stop) { diff --git a/KREngine/kraken/KRTextureTGA.cpp b/KREngine/kraken/KRTextureTGA.cpp index e04d5a7..b5fd7fa 100644 --- a/KREngine/kraken/KRTextureTGA.cpp +++ b/KREngine/kraken/KRTextureTGA.cpp @@ -41,7 +41,7 @@ KRTextureTGA::~KRTextureTGA() } -bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) +bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) { m_pData->lock(); TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); diff --git a/KREngine/kraken/KRTextureTGA.h b/KREngine/kraken/KRTextureTGA.h index 458ca3a..1624341 100644 --- a/KREngine/kraken/KRTextureTGA.h +++ b/KREngine/kraken/KRTextureTGA.h @@ -18,7 +18,7 @@ public: virtual ~KRTextureTGA(); virtual std::string getExtension(); - bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle); + bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim); virtual long getMemRequiredForSize(int max_dim); }; From 05626214d4fc0dfe1e8308125c3addd468d5036d Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 9 Nov 2013 16:08:08 -0800 Subject: [PATCH 17/43] Asynchronous streaming and memory management improvements in progress. --HG-- branch : async_streaming --- KREngine/kraken/KRCamera.cpp | 94 ++++---- KREngine/kraken/KRCamera.h | 2 +- KREngine/kraken/KRDataBlock.cpp | 14 ++ KREngine/kraken/KRDataBlock.h | 1 + KREngine/kraken/KRDirectionalLight.cpp | 2 +- KREngine/kraken/KRLight.cpp | 8 +- KREngine/kraken/KRMesh.cpp | 194 ++++++++++------ KREngine/kraken/KRMesh.h | 30 ++- KREngine/kraken/KRMeshManager.cpp | 208 +++++++++++------- KREngine/kraken/KRMeshManager.h | 27 ++- KREngine/kraken/KRParticleSystemNewtonian.cpp | 4 +- KREngine/kraken/KRPointLight.cpp | 2 +- KREngine/kraken/KRRenderSettings.cpp | 2 +- KREngine/kraken/KRScene.cpp | 2 +- KREngine/kraken/KRStockGeometry.h | 31 +-- KREngine/kraken/KRTextureManager.cpp | 1 + 16 files changed, 379 insertions(+), 243 deletions(-) diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index fb67f83..b997093 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -54,14 +54,9 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) { volumetricLightAccumulationBuffer = 0; volumetricLightAccumulationTexture = 0; m_frame_times_filled = 0; - - m_debug_text_vertices = NULL; } KRCamera::~KRCamera() { - if(m_debug_text_vertices) { - delete m_debug_text_vertices; - } destroyBuffers(); } @@ -315,7 +310,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } @@ -472,7 +467,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true); for(unordered_map::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { KRMat4 matModel = KRMat4(); matModel.scale((*itr).first.size() * 0.5f); @@ -704,7 +699,7 @@ void KRCamera::renderPost() } // Update attribute values. - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); @@ -726,7 +721,7 @@ void KRCamera::renderPost() // viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0); // getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); // m_pContext->getTextureManager()->selectTexture(1, NULL); -// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); +// m_pContext->getModelManager()->bindVBO(KRENGINE_VBO_2D_SQUARE_INDICES, KRENGINE_VBO_2D_SQUARE_VERTEXES, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); // m_pContext->getTextureManager()->_setActiveTexture(0); // GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); //#if GL_EXT_shadow_samplers @@ -745,7 +740,7 @@ void KRCamera::renderPost() - if(m_debug_text_vertices) { + if(m_debug_text_vertices.getSize()) { m_pContext->getModelManager()->releaseVBO(m_debug_text_vertices); } @@ -791,12 +786,13 @@ void KRCamera::renderPost() const int DEBUG_TEXT_COLUMNS = 256; const int DEBUG_TEXT_ROWS = 128; - if(m_debug_text_vertices == NULL) { - m_debug_text_vertices = new DebugTextVertexData[DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6]; + if(m_debug_text_vertices.getSize() == 0) { + m_debug_text_vertices.expand(sizeof(DebugTextVertexData) * DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6); } int vertex_count = 0; - + m_debug_text_vertices.lock(); + DebugTextVertexData *vertex_data = (DebugTextVertexData *)m_debug_text_vertices.getStart(); pChar = szText; float dScaleX = 2.0 / (1024 / 16); @@ -824,47 +820,47 @@ void KRCamera::renderPost() KRVector2 top_left_uv = KRVector2(dTexScale * iTexCol, dTexScale * iTexRow); KRVector2 bottom_right_uv = KRVector2(dTexScale * iTexCol + dTexScale, dTexScale * iTexRow + dTexScale); - m_debug_text_vertices[vertex_count].x = top_left_pos.x; - m_debug_text_vertices[vertex_count].y = top_left_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = top_left_uv.x; - m_debug_text_vertices[vertex_count].v = top_left_uv.y; + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; - m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; - m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = top_left_pos.x; - m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = top_left_uv.x; - m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = top_left_pos.x; - m_debug_text_vertices[vertex_count].y = top_left_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = top_left_uv.x; - m_debug_text_vertices[vertex_count].v = top_left_uv.y; + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; - m_debug_text_vertices[vertex_count].y = top_left_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; - m_debug_text_vertices[vertex_count].v = top_left_uv.y; + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; - m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; - m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; vertex_count++; } @@ -892,18 +888,20 @@ void KRCamera::renderPost() m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font")); - - m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + KRDataBlock index_data; + //m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + m_pContext->getModelManager()->bindVBO(m_debug_text_vertices, index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count)); // Re-enable z-buffer write GLDEBUG(glDepthMask(GL_TRUE)); + + m_debug_text_vertices.unlock(); } else { - if(m_debug_text_vertices) { - delete m_debug_text_vertices; - m_debug_text_vertices = NULL; + if(m_debug_text_vertices.getSize() > 0) { + m_debug_text_vertices = KRDataBlock(); } } } diff --git a/KREngine/kraken/KRCamera.h b/KREngine/kraken/KRCamera.h index 03d518a..560dd4e 100644 --- a/KREngine/kraken/KRCamera.h +++ b/KREngine/kraken/KRCamera.h @@ -99,7 +99,7 @@ private: GLfloat v; } DebugTextVertexData; - DebugTextVertexData *m_debug_text_vertices; + KRDataBlock m_debug_text_vertices; // std::string getDebugText(); diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index 33050ad..7331f70 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -52,6 +52,20 @@ KRDataBlock::KRDataBlock() { m_bReadOnly = false; } +KRDataBlock::KRDataBlock(void *data, size_t size) { + m_data = NULL; + m_data_size = 0; + m_data_offset = 0; + m_fdPackFile = 0; + m_fileName = ""; + m_mmapData = NULL; + m_fileOwnerDataBlock = NULL; + m_bMalloced = false; + m_lockCount = 0; + m_bReadOnly = false; + load(data, size); +} + KRDataBlock::~KRDataBlock() { unload(); } diff --git a/KREngine/kraken/KRDataBlock.h b/KREngine/kraken/KRDataBlock.h index 80aeb0c..5198375 100644 --- a/KREngine/kraken/KRDataBlock.h +++ b/KREngine/kraken/KRDataBlock.h @@ -37,6 +37,7 @@ class KRDataBlock { public: KRDataBlock(); + KRDataBlock(void *data, size_t size); ~KRDataBlock(); // Encapsulate a pointer. Note - The pointer will not be free'ed diff --git a/KREngine/kraken/KRDirectionalLight.cpp b/KREngine/kraken/KRDirectionalLight.cpp index 2335b95..db78f9c 100644 --- a/KREngine/kraken/KRDirectionalLight.cpp +++ b/KREngine/kraken/KRDirectionalLight.cpp @@ -119,7 +119,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector & GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index c5337a6..d6162f5 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -226,7 +226,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero())); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + KRDataBlock particle_index_data; + m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), particle_index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } @@ -266,7 +267,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing)); pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); + KRDataBlock index_data; + m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getVolumetricLightingVertexes(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6)); } @@ -333,7 +335,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index a044244..5082a07 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -42,22 +42,23 @@ KRMesh::KRMesh(KRContext &context, std::string name) : KRResource(context, name) { - m_hasTransparency = false; - m_materials.clear(); - m_uniqueMaterials.clear(); - m_pData = new KRDataBlock(); - m_pData->lock(); setName(name); + + m_hasTransparency = false; + m_pData = NULL; + m_pMetaData = NULL; + m_pIndexBaseData = NULL; + } KRMesh::KRMesh(KRContext &context, std::string name, KRDataBlock *data) : KRResource(context, name) { - m_hasTransparency = false; - m_materials.clear(); - m_uniqueMaterials.clear(); - m_pData = new KRDataBlock(); - m_pData->lock(); setName(name); + m_hasTransparency = false; + m_pData = NULL; + m_pMetaData = NULL; + m_pIndexBaseData = NULL; + loadPack(data); } @@ -105,9 +106,24 @@ int KRMesh::GetLODCoverage(const std::string &name) KRMesh::~KRMesh() { - clearData(); - m_pData->unlock(); - if(m_pData) delete m_pData; + releaseData(); +} + +void KRMesh::releaseData() { + if(m_pIndexBaseData) { + m_pIndexBaseData->unlock(); + delete m_pIndexBaseData; + m_pIndexBaseData = NULL; + } + if(m_pMetaData) { + m_pMetaData->unlock(); + delete m_pMetaData; + m_pMetaData = NULL; + } + if(m_pData) { + delete m_pData; + m_pData = NULL; + } } std::string KRMesh::getExtension() { @@ -115,32 +131,36 @@ std::string KRMesh::getExtension() { } bool KRMesh::save(const std::string& path) { - clearBuffers(); return m_pData->save(path); } bool KRMesh::save(KRDataBlock &data) { - clearBuffers(); data.append(*m_pData); return true; } void KRMesh::loadPack(KRDataBlock *data) { - clearData(); - m_pData->unlock(); - delete m_pData; + releaseData(); + m_pData = data; - m_pData->lock(); + + pack_header ph; + m_pData->copy((void *)&ph, 0, sizeof(ph)); + m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); + m_pMetaData->lock(); + + m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); + m_pIndexBaseData->lock(); + + m_minPoint = KRVector3(ph.minx, ph.miny, ph.minz); + m_maxPoint = KRVector3(ph.maxx, ph.maxy, ph.maxz); + updateAttributeOffsets(); - pack_header *pHeader = getHeader(); - m_minPoint = KRVector3(pHeader->minx, pHeader->miny, pHeader->minz); - m_maxPoint = KRVector3(pHeader->maxx, pHeader->maxy, pHeader->maxz); } void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones) { - m_pData->lock(); - + //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { getSubmeshes(); @@ -221,8 +241,6 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect } } } - - m_pData->unlock(); } GLfloat KRMesh::getMaxDimension() { @@ -259,21 +277,21 @@ void KRMesh::getSubmeshes() { } void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const std::string &object_name, const std::string &material_name) { + //m_pData->lock(); getSubmeshes(); Submesh *pSubmesh = m_submeshes[iSubmesh]; int cVertexes = pSubmesh->vertex_count; // fprintf(stderr, "start - object: %s material: %s vertices: %i\n", object_name.c_str(), material_name.c_str(), cVertexes); - unsigned char *pVertexData = getVertexData(); + int vertex_data_offset = getVertexDataOffset(); + int index_data_offset = getIndexDataOffset(); pack_header *pHeader = getHeader(); - + int32_t vertex_attrib_flags = pHeader->vertex_attrib_flags; + int32_t vertex_count = pHeader->vertex_count; + int vbo_index=0; if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { - - - - __uint16_t *index_data = getIndexData(); int index_group = getSubmesh(iSubmesh)->index_group; int index_group_offset = getSubmesh(iSubmesh)->index_group_offset; while(cVertexes > 0) { @@ -281,7 +299,22 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st int start_index_offset, start_vertex_offset, index_count, vertex_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, pHeader->vertex_attrib_flags, true); + KRDataBlock *vertex_data_block = NULL; + KRDataBlock *index_data_block = NULL; + if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { + vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size); + index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2); + m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); + m_submeshes[iSubmesh]->index_data_blocks.push_back(index_data_block); + } else { + vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index]; + index_data_block = m_submeshes[iSubmesh]->index_data_blocks[vbo_index]; + } + vbo_index++; + + //m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, vertex_attrib_flags, true); + m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true); + int vertex_draw_count = cVertexes; if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; @@ -293,21 +326,27 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st } } else { - int cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; + int cBuffers = (vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; int iVertex = pSubmesh->start_vertex; int iBuffer = iVertex / MAX_VBO_SIZE; iVertex = iVertex % MAX_VBO_SIZE; while(cVertexes > 0) { - GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE; + GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : vertex_count % MAX_VBO_SIZE; int vertex_size = m_vertex_size; - void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size + vertex_size * cBufferVertexes; - void *buffer_end = m_pData->getEnd(); - assert(vbo_end <= buffer_end); - assert(cBufferVertexes <= 65535); + KRDataBlock *vertex_data_block = NULL; + KRDataBlock *index_data_block = NULL; + if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { + vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes); + + m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); + } else { + vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index]; + } + vbo_index++; - - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, pHeader->vertex_attrib_flags, true); + //m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, vertex_attrib_flags, true); + m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true); if(iVertex + cVertexes >= MAX_VBO_SIZE) { @@ -353,13 +392,12 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st } } - // fprintf(stderr, "end object\n"); - + //m_pData->unlock(); } -void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector > vertex_index_bases, std::vector vertices, std::vector uva, std::vector uvb, std::vector normals, std::vector tangents, std::vector submesh_starts, std::vector submesh_lengths, std::vector material_names, std::vector bone_names, std::vector bone_bind_poses, std::vector > bone_indexes, std::vector > bone_weights, model_format_t model_format, */const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { +void KRMesh::LoadData(const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { - clearData(); + clearBuffers(); // TODO, FINDME - These values should be passed as a parameter and set by GUI flags bool use_short_vertexes = false; @@ -438,10 +476,10 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vectorunlock(); + m_pData = new KRDataBlock(); + m_pMetaData = m_pData; m_pData->expand(new_file_size); m_pData->lock(); - pack_header *pHeader = getHeader(); memset(pHeader, 0, sizeof(pack_header)); pHeader->vertex_attrib_flags = vertex_attrib_flags; @@ -583,6 +621,18 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vectorunlock(); + + // ---- + + pack_header ph; + m_pData->copy((void *)&ph, 0, sizeof(ph)); + m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); + m_pMetaData->lock(); + m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); + m_pIndexBaseData->lock(); + + // ---- optimize(); } @@ -595,12 +645,6 @@ KRVector3 KRMesh::getMaxPoint() const { return m_maxPoint; } -void KRMesh::clearData() { - m_pData->unlock(); - m_pData->unload(); - m_pData->lock(); -} - void KRMesh::clearBuffers() { m_submeshes.clear(); } @@ -632,34 +676,47 @@ bool KRMesh::has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attri KRMesh::pack_header *KRMesh::getHeader() const { - return (pack_header *)m_pData->getStart(); + return (pack_header *)m_pMetaData->getStart(); } KRMesh::pack_bone *KRMesh::getBone(int index) { pack_header *header = getHeader(); - return (pack_bone *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); + return (pack_bone *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); } unsigned char *KRMesh::getVertexData() const { + return ((unsigned char *)m_pData->getStart()) + getVertexDataOffset(); +} + +size_t KRMesh::getVertexDataOffset() const { pack_header *pHeader = getHeader(); - return ((unsigned char *)m_pData->getStart()) + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count); + return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count); } __uint16_t *KRMesh::getIndexData() const { + + return (__uint16_t *)((unsigned char *)m_pData->getStart() + getIndexDataOffset()); +} + +size_t KRMesh::getIndexDataOffset() const { pack_header *pHeader = getHeader(); - return (__uint16_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count); + return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count; } __uint32_t *KRMesh::getIndexBaseData() const { - pack_header *pHeader = getHeader(); - return (__uint32_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count)); + if(m_pIndexBaseData == NULL) { + pack_header *pHeader = getHeader(); + return (__uint32_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count)); + } else { + return (__uint32_t *)m_pIndexBaseData->getStart(); + } } KRMesh::pack_material *KRMesh::getSubmesh(int mesh_index) const { - return (pack_material *)((unsigned char *)m_pData->getStart() + sizeof(pack_header)) + mesh_index; + return (pack_material *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header)) + mesh_index; } unsigned char *KRMesh::getVertexData(int index) const @@ -670,7 +727,8 @@ unsigned char *KRMesh::getVertexData(int index) const int KRMesh::getSubmeshCount() const { pack_header *header = getHeader(); - return header->submesh_count; + int submesh_count = header->submesh_count; + return submesh_count; } int KRMesh::getVertexCount(int submesh) const @@ -904,10 +962,8 @@ size_t KRMesh::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_ int KRMesh::getBoneCount() { - m_pData->lock(); pack_header *header = getHeader(); int bone_count = header->bone_count; - m_pData->unlock(); return bone_count; } @@ -923,9 +979,7 @@ KRMat4 KRMesh::getBoneBindPose(int bone_index) KRMesh::model_format_t KRMesh::getModelFormat() const { - m_pData->lock(); model_format_t f = (model_format_t)getHeader()->model_format; - m_pData->unlock(); return f; } @@ -1018,6 +1072,7 @@ bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_ind bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo) const { + m_pData->lock(); bool hit_found = false; for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { // int vertex_start = getSubmesh(submesh_index)->start_vertex; @@ -1054,20 +1109,24 @@ bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitin break; } } + m_pData->unlock(); return hit_found; } bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const { + m_pData->lock(); KRHitInfo new_hitinfo; KRVector3 dir = KRVector3::Normalize(v1 - v0); if(rayCast(v0, dir, new_hitinfo)) { if((new_hitinfo.getPosition() - v0).sqrMagnitude() <= (v1 - v0).sqrMagnitude()) { // The hit was between v1 and v2 hitinfo = new_hitinfo; + m_pData->unlock(); return true; } } + m_pData->unlock(); return false; // Either no hit, or the hit was beyond v1 } @@ -1284,6 +1343,9 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const switch(getModelFormat()) { case KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: { + __uint16_t *index_data = getIndexData(); + + int start_index_offset, start_vertex_offset, index_count, vertex_count; int index_group = getSubmesh(submesh)->index_group; int index_group_offset = getSubmesh(submesh)->index_group_offset; @@ -1293,7 +1355,7 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const remaining_vertices -= index_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); } - return getIndexData()[start_index_offset + remaining_vertices] + start_vertex_offset; + return index_data[start_index_offset + remaining_vertices] + start_vertex_offset; } break; default: diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index abc03d7..602a5a6 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -133,11 +133,24 @@ public: - typedef struct { + class Submesh { + public: + Submesh() {}; + ~Submesh() { + for(std::vector::iterator itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) { + delete (*itr); + } + for(std::vector::iterator itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) { + delete (*itr); + } + }; + GLint start_vertex; GLsizei vertex_count; char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; - } Submesh; + vector vertex_data_blocks; + vector index_data_blocks; + }; typedef struct { union { @@ -198,6 +211,10 @@ public: static int GetLODCoverage(const std::string &name); private: + KRDataBlock *m_pData; + KRDataBlock *m_pMetaData; + KRDataBlock *m_pIndexBaseData; + void getSubmeshes(); // bool rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const; @@ -212,8 +229,7 @@ private: KRVector3 m_minPoint, m_maxPoint; - KRDataBlock *m_pData; - + typedef struct { @@ -235,7 +251,6 @@ private: void updateAttributeOffsets(); - void clearData(); void clearBuffers(); void setName(const std::string name); @@ -244,14 +259,19 @@ private: pack_material *getSubmesh(int mesh_index) const; unsigned char *getVertexData() const; + size_t getVertexDataOffset() const; unsigned char *getVertexData(int index) const; __uint16_t *getIndexData() const; + size_t getIndexDataOffset() const; __uint32_t *getIndexBaseData() const; pack_header *getHeader() const; pack_bone *getBone(int index); void getIndexedRange(int index_group, int &start_index_offset, int &start_vertex_offset, int &index_count, int &vertex_count) const; + + void releaseData(); + }; diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 9905f3b..d4905d0 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -43,8 +43,6 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_s m_currentVBO.vao_handle = -1; m_currentVBO.data = NULL; m_vboMemUsed = 0; - m_randomParticleVertexData = NULL; - m_volumetricLightingVertexData = NULL; m_memoryTransferredThisFrame = 0; // addModel(new KRMeshCube(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults @@ -52,6 +50,45 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_s addModel(new KRMeshSphere(context)); m_draw_call_logging_enabled = false; m_draw_call_log_used = false; + + + + // ---- Initialize stock models ---- + + static const GLfloat _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = { + 1.0, 1.0, 1.0, + -1.0, 1.0, 1.0, + 1.0,-1.0, 1.0, + -1.0,-1.0, 1.0, + -1.0,-1.0,-1.0, + -1.0, 1.0, 1.0, + -1.0, 1.0,-1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0,-1.0, + 1.0,-1.0, 1.0, + 1.0,-1.0,-1.0, + -1.0,-1.0,-1.0, + 1.0, 1.0,-1.0, + -1.0, 1.0,-1.0 + }; + + KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); + KRENGINE_VBO_3D_CUBE_VERTICES.expand(sizeof(GLfloat) * 3 * 14); + KRENGINE_VBO_3D_CUBE_VERTICES.lock(); + memcpy(KRENGINE_VBO_3D_CUBE_VERTICES.getStart(), _KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(GLfloat) * 3 * 14); + KRENGINE_VBO_3D_CUBE_VERTICES.unlock(); + + static const GLfloat _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = { + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f + }; + KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); + KRENGINE_VBO_2D_SQUARE_VERTICES.expand(sizeof(GLfloat) * 5 * 4); + KRENGINE_VBO_2D_SQUARE_VERTICES.lock(); + memcpy(KRENGINE_VBO_2D_SQUARE_VERTICES.getStart(), _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(GLfloat) * 5 * 4); + KRENGINE_VBO_2D_SQUARE_VERTICES.unlock(); } KRMeshManager::~KRMeshManager() { @@ -59,8 +96,6 @@ KRMeshManager::~KRMeshManager() { delete (*itr).second; } m_models.empty(); - if(m_randomParticleVertexData != NULL) delete m_randomParticleVertexData; - if(m_volumetricLightingVertexData != NULL) delete m_volumetricLightingVertexData; } KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) { @@ -115,24 +150,24 @@ void KRMeshManager::unbindVBO() { } } -void KRMeshManager::releaseVBO(GLvoid *data) +void KRMeshManager::releaseVBO(KRDataBlock &data) { - if(m_currentVBO.data == data) { + if(m_currentVBO.data == &data) { unbindVBO(); } vbo_info_type vbo_to_release; - if(m_vbosActive.find(data) != m_vbosActive.end()) { + if(m_vbosActive.find(&data) != m_vbosActive.end()) { fprintf(stderr, "glFinish called due to releasing a VBO that is active in the current frame.\n"); GLDEBUG(glFinish()); // The VBO is active - vbo_to_release = m_vbosActive[data]; - m_vbosActive.erase(data); + vbo_to_release = m_vbosActive[&data]; + m_vbosActive.erase(&data); } else { // The VBO is inactive - vbo_to_release = m_vbosPool[data]; - m_vbosPool.erase(data); + vbo_to_release = m_vbosPool[&data]; + m_vbosPool.erase(&data); } m_vboMemUsed -= vbo_to_release.size; @@ -146,12 +181,12 @@ void KRMeshManager::releaseVBO(GLvoid *data) } } -void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo) { +void KRMeshManager::bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo) { - if(m_currentVBO.data != data || m_currentVBO.size != size + index_data_size) { + if(m_currentVBO.data != &data) { - if(m_vbosActive.find(data) != m_vbosActive.end()) { - m_currentVBO = m_vbosActive[data]; + if(m_vbosActive.find(&data) != m_vbosActive.end()) { + m_currentVBO = m_vbosActive[&data]; #if GL_OES_vertex_array_object GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); #else @@ -163,10 +198,10 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); } #endif - } else if(m_vbosPool.find(data) != m_vbosPool.end()) { - m_currentVBO = m_vbosPool[data]; - m_vbosPool.erase(data); - m_vbosActive[data] = m_currentVBO; + } else if(m_vbosPool.find(&data) != m_vbosPool.end()) { + m_currentVBO = m_vbosPool[&data]; + m_vbosPool.erase(&data); + m_vbosActive[&data] = m_currentVBO; #if GL_OES_vertex_array_object GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); #else @@ -181,12 +216,12 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G } else { - while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + size + index_data_size >= KRContext::KRENGINE_MAX_VBO_MEM) { + while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + data.getSize() + index_data.getSize() >= KRContext::KRENGINE_MAX_VBO_MEM) { if(m_vbosPool.empty()) { fprintf(stderr, "flushBuffers due to VBO exhaustion...\n"); m_pContext->rotateBuffers(false); } - unordered_map::iterator first_itr = m_vbosPool.begin(); + unordered_map::iterator first_itr = m_vbosPool.begin(); vbo_info_type firstVBO = first_itr->second; #if GL_OES_vertex_array_object GLDEBUG(glDeleteVertexArraysOES(1, &firstVBO.vao_handle)); @@ -204,7 +239,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G m_currentVBO.vbo_handle = -1; m_currentVBO.vbo_handle_indexes = -1; GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle)); - if(index_data != NULL) { + if(index_data.getSize() > 0) { GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle_indexes)); } @@ -216,41 +251,47 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); #if GL_OES_mapbuffer - GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); GLDEBUG(void *map_ptr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); - memcpy(map_ptr, data, size); + data.copy(map_ptr); + //memcpy(map_ptr, data, size); GLDEBUG(glUnmapBufferOES(GL_ARRAY_BUFFER)); #else - GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + data.lock(); + GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + data.unlock(); #endif - m_memoryTransferredThisFrame += size; - m_vboMemUsed += size; + m_memoryTransferredThisFrame += data.getSize(); + m_vboMemUsed += data.getSize(); configureAttribs(vertex_attrib_flags); - m_currentVBO.size = size; - m_currentVBO.data = data; + m_currentVBO.size = data.getSize(); + m_currentVBO.data = &data; - if(index_data == NULL) { + if(index_data.getSize() == 0) { GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); #if GL_OES_mapbuffer - GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); GLDEBUG(void *map_ptr = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); - memcpy(map_ptr, index_data, index_data_size); + index_data.copy(map_ptr); + //memcpy(map_ptr, index_data, index_data.getSize()); GLDEBUG(glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER)); #else - GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, index_data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + index_data.lock(); + GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), index_data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + index_data.unlock(); #endif - m_memoryTransferredThisFrame += index_data_size; - m_vboMemUsed += index_data_size; - m_currentVBO.size += index_data_size; + m_memoryTransferredThisFrame += index_data.getSize(); + m_vboMemUsed += index_data.getSize(); + m_currentVBO.size += index_data.getSize(); } - m_vbosActive[data] = m_currentVBO; + m_vbosActive[&data] = m_currentVBO; } } } @@ -332,7 +373,7 @@ long KRMeshManager::getMemUsed() long KRMeshManager::getMemActive() { long mem_active = 0; - for(unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { + for(unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { mem_active += (*itr).second.size; } return mem_active; @@ -350,56 +391,56 @@ void KRMeshManager::rotateBuffers(bool new_frame) } -KRMeshManager::VolumetricLightingVertexData *KRMeshManager::getVolumetricLightingVertexes() +KRDataBlock &KRMeshManager::getVolumetricLightingVertexes() { - if(m_volumetricLightingVertexData == NULL) { - m_volumetricLightingVertexData = (VolumetricLightingVertexData *)malloc(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6); + if(m_volumetricLightingVertexData.getSize() == 0) { + m_volumetricLightingVertexData.expand(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6); + m_volumetricLightingVertexData.lock(); + VolumetricLightingVertexData * vertex_data = (VolumetricLightingVertexData *)m_volumetricLightingVertexData.getStart(); int iVertex=0; for(int iPlane=0; iPlane < KRENGINE_MAX_VOLUMETRIC_PLANES; iPlane++) { - m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = iPlane; + iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; - iVertex++; - -// -1.0f, -1.0f, -// 1.0f, -1.0f, -// -1.0f, 1.0f, -// 1.0f, 1.0f, } + m_volumetricLightingVertexData.unlock(); } return m_volumetricLightingVertexData; } -KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles() +KRDataBlock &KRMeshManager::getRandomParticles() { - if(m_randomParticleVertexData == NULL) { - m_randomParticleVertexData = (RandomParticleVertexData *)malloc(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3); + if(m_randomParticleVertexData.getSize() == 0) { + m_randomParticleVertexData.expand(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3); + m_randomParticleVertexData.lock(); + RandomParticleVertexData *vertex_data = (RandomParticleVertexData *)m_randomParticleVertexData.getStart(); // Generate vertices for randomly placed equilateral triangles with a side length of 1 and an origin point centered so that an inscribed circle can be efficiently rendered without wasting fill @@ -408,27 +449,28 @@ KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles() int iVertex=0; for(int iParticle=0; iParticle < KRENGINE_MAX_RANDOM_PARTICLES; iParticle++) { - m_randomParticleVertexData[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; - m_randomParticleVertexData[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; - m_randomParticleVertexData[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; - m_randomParticleVertexData[iVertex].uva.u = -0.5f; - m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius; + vertex_data[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].uva.u = -0.5f; + vertex_data[iVertex].uva.v = -inscribed_circle_radius; iVertex++; - m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x; - m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y; - m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z; - m_randomParticleVertexData[iVertex].uva.u = 0.5f; - m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius; + vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x; + vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y; + vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z; + vertex_data[iVertex].uva.u = 0.5f; + vertex_data[iVertex].uva.v = -inscribed_circle_radius; iVertex++; - m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x; - m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y; - m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z; - m_randomParticleVertexData[iVertex].uva.u = 0.0f; - m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height; + vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x; + vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y; + vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z; + vertex_data[iVertex].uva.u = 0.0f; + vertex_data[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height; iVertex++; } + m_randomParticleVertexData.unlock(); } return m_randomParticleVertexData; } diff --git a/KREngine/kraken/KRMeshManager.h b/KREngine/kraken/KRMeshManager.h index f1782b4..2783617 100644 --- a/KREngine/kraken/KRMeshManager.h +++ b/KREngine/kraken/KRMeshManager.h @@ -61,8 +61,8 @@ public: std::vector getModelNames(); unordered_multimap &getModels(); - void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo); - void releaseVBO(GLvoid *data); + void bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo); + void releaseVBO(KRDataBlock &data); void unbindVBO(); long getMemUsed(); long getMemActive(); @@ -90,10 +90,8 @@ public: } VolumetricLightingVertexData; - - - RandomParticleVertexData *getRandomParticles(); - VolumetricLightingVertexData *getVolumetricLightingVertexes(); + KRDataBlock &getRandomParticles(); + KRDataBlock &getVolumetricLightingVertexes(); long getMemoryTransferedThisFrame(); @@ -111,6 +109,13 @@ public: void log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count); std::vector getDrawCalls(); + + KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES; + __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS; + + KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES; + __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS; + private: unordered_multimap m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model @@ -119,17 +124,17 @@ private: GLuint vbo_handle_indexes; GLuint vao_handle; GLsizeiptr size; - GLvoid *data; + KRDataBlock *data; } vbo_info_type; long m_vboMemUsed; vbo_info_type m_currentVBO; - unordered_map m_vbosActive; - unordered_map m_vbosPool; + unordered_map m_vbosActive; + unordered_map m_vbosPool; - RandomParticleVertexData *m_randomParticleVertexData; - VolumetricLightingVertexData *m_volumetricLightingVertexData; + KRDataBlock m_randomParticleVertexData; + KRDataBlock m_volumetricLightingVertexData; long m_memoryTransferredThisFrame; diff --git a/KREngine/kraken/KRParticleSystemNewtonian.cpp b/KREngine/kraken/KRParticleSystemNewtonian.cpp index 81324cd..f6bbdb5 100644 --- a/KREngine/kraken/KRParticleSystemNewtonian.cpp +++ b/KREngine/kraken/KRParticleSystemNewtonian.cpp @@ -77,7 +77,9 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorselectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); + //m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); + KRDataBlock index_data; + m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } diff --git a/KREngine/kraken/KRPointLight.cpp b/KREngine/kraken/KRPointLight.cpp index d18ddcb..db5a3d2 100644 --- a/KREngine/kraken/KRPointLight.cpp +++ b/KREngine/kraken/KRPointLight.cpp @@ -96,7 +96,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &point_ GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } else { #if GL_OES_vertex_array_object diff --git a/KREngine/kraken/KRRenderSettings.cpp b/KREngine/kraken/KRRenderSettings.cpp index 6c9efe8..7a31679 100644 --- a/KREngine/kraken/KRRenderSettings.cpp +++ b/KREngine/kraken/KRRenderSettings.cpp @@ -15,7 +15,7 @@ KRRenderSettings::KRRenderSettings() siren_enable_hrtf = true; siren_reverb_max_length = 2.0f; - m_enable_realtime_occlusion = true; + m_enable_realtime_occlusion = false; bShowShadowBuffer = false; bShowOctree = false; bShowDeferred = false; diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 87c2f66..4f04ad2 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -272,7 +272,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map &visi KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix(); - getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); + getContext().getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true); // Enable additive blending if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { diff --git a/KREngine/kraken/KRStockGeometry.h b/KREngine/kraken/KRStockGeometry.h index 4dc7e18..37297c2 100644 --- a/KREngine/kraken/KRStockGeometry.h +++ b/KREngine/kraken/KRStockGeometry.h @@ -10,8 +10,9 @@ #define KRSTOCKGEOMETRY_H #include "KRMesh.h" - -static const GLfloat KRENGINE_VBO_3D_CUBE[] = { +#include "KRDataBlock.h" +/* +static const GLfloat _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = { 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0,-1.0, 1.0, @@ -28,32 +29,20 @@ static const GLfloat KRENGINE_VBO_3D_CUBE[] = { -1.0, 1.0,-1.0 }; -static int KRENGINE_VBO_3D_CUBE_SIZE = sizeof(GLfloat) * 3 * 14; +static KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES; +KRENGINE_VBO_3D_CUBE_VERTICES.load((void *)_KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(GLfloat) * 3 * 14); + static const __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); -static const GLfloat KRENGINE_VERTICES_2D_SQUARE[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f, -}; - -static const GLfloat KRENGINE_VERTICES_2D_SQUARE_UV[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, -}; - -static const GLfloat KRENGINE_VBO_2D_SQUARE[] = { +static const GLfloat _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; -static const int KRENGINE_VBO_2D_SQUARE_SIZE = sizeof(GLfloat) * 5 * 4; +static KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES; +KRENGINE_VBO_2D_SQUARE_VERTICES.load((void *)_KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(GLfloat) * 5 * 4); static const __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); - - +*/ #endif diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index e258841..605e48e 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -236,6 +236,7 @@ void KRTextureManager::endFrame(float deltaTime) void KRTextureManager::balanceTextureMemory() { + return; // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures // Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution. From cf732a6721e2b3443cb8b14fdb0bb6e753f448f6 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Wed, 13 Nov 2013 23:52:17 -0800 Subject: [PATCH 18/43] Asynchronous streaming and memory management improvements in progress. --HG-- branch : async_streaming --- KREngine/kraken/KRContext.cpp | 12 ++++++++++- KREngine/kraken/KRContext.h | 4 ++++ KREngine/kraken/KREngine-common.h | 1 + KREngine/kraken/KRMeshStreamer.mm | 4 ++++ KREngine/kraken/KRTexture.cpp | 11 +++++----- KREngine/kraken/KRTextureManager.cpp | 31 +++++++++++++++++++++------- KREngine/kraken/KRTextureManager.h | 11 ++++++++++ KREngine/kraken/KRTextureStreamer.h | 4 ++++ KREngine/kraken/KRTextureStreamer.mm | 20 +++++++++++++++--- 9 files changed, 82 insertions(+), 16 deletions(-) diff --git a/KREngine/kraken/KRContext.cpp b/KREngine/kraken/KRContext.cpp index 6c1145d..ffa113a 100644 --- a/KREngine/kraken/KRContext.cpp +++ b/KREngine/kraken/KRContext.cpp @@ -27,6 +27,7 @@ const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = { }; KRContext::KRContext() { + m_streamingEnabled = false; mach_timebase_info(&m_timebase_info); m_bDetectedExtensions = false; @@ -43,7 +44,7 @@ KRContext::KRContext() { m_pAnimationCurveManager = new KRAnimationCurveManager(*this); m_pSoundManager = new KRAudioManager(*this); m_pUnknownManager = new KRUnknownManager(*this); - + m_streamingEnabled = true; } KRContext::~KRContext() { @@ -271,3 +272,12 @@ long KRContext::getAbsoluteTimeMilliseconds() return (long)(mach_absolute_time() / 1000 * m_timebase_info.numer / m_timebase_info.denom); // Division done first to avoid potential overflow } +bool KRContext::getStreamingEnabled() +{ + return m_streamingEnabled; +} + +void KRContext::setStreamingEnabled(bool enable) +{ + m_streamingEnabled = enable; +} diff --git a/KREngine/kraken/KRContext.h b/KREngine/kraken/KRContext.h index 47a0b34..824afbd 100644 --- a/KREngine/kraken/KRContext.h +++ b/KREngine/kraken/KRContext.h @@ -73,6 +73,8 @@ public: long getAbsoluteTimeMilliseconds(); std::vector getResources(); + bool getStreamingEnabled(); + void setStreamingEnabled(bool enable); private: KRBundleManager *m_pBundleManager; @@ -93,6 +95,8 @@ private: float m_absolute_time; mach_timebase_info_data_t m_timebase_info; + + std::atomic m_streamingEnabled; }; #endif diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index fbde9bc..1edc1af 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -14,6 +14,7 @@ float const PI = 3.141592653589793f; float const D2R = PI * 2 / 360; + #include #include #include diff --git a/KREngine/kraken/KRMeshStreamer.mm b/KREngine/kraken/KRMeshStreamer.mm index b2aa5de..ec30a22 100644 --- a/KREngine/kraken/KRMeshStreamer.mm +++ b/KREngine/kraken/KRMeshStreamer.mm @@ -9,6 +9,7 @@ #include "KRMeshStreamer.h" #include "KREngine-common.h" +#include "KRContext.h" #include @@ -36,6 +37,9 @@ void KRMeshStreamer::run() while(!m_stop) { + if(m_context.getStreamingEnabled()) { + + } std::this_thread::sleep_for( sleep_duration ); } } diff --git a/KREngine/kraken/KRTexture.cpp b/KREngine/kraken/KRTexture.cpp index 5c0830c..1588ff1 100644 --- a/KREngine/kraken/KRTexture.cpp +++ b/KREngine/kraken/KRTexture.cpp @@ -52,19 +52,20 @@ long KRTexture::getReferencedMemSize() { void KRTexture::resize(int max_dim) { - assert(m_iHandle == m_iNewHandle); // Only allow one resize() per frame + if(m_iHandle != m_iNewHandle) return; // Only allow one resize() per frame if(max_dim == 0) { m_iNewHandle = 0; } else { int target_dim = max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; +/* int requiredMemoryTransfer = getThroughputRequiredForResize(target_dim); int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize() - getReferencedMemSize(); - + if(requiredMemoryDelta) { // Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory) - + if(getContext().getTextureManager()->getMemoryTransferedThisFrame() + requiredMemoryTransfer > getContext().KRENGINE_MAX_TEXTURE_THROUGHPUT) { // Exceeding per-frame transfer throughput; can't resize now return; @@ -74,13 +75,13 @@ void KRTexture::resize(int max_dim) // Exceeding total memory allocated to textures; can't resize now return; } - +*/ if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) { if(!createGLTexture(target_dim)) { assert(false); } } - } +// } } } diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 605e48e..5484a9d 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -215,13 +215,20 @@ long KRTextureManager::getMemActive() { void KRTextureManager::startFrame(float deltaTime) { + m_streamer.startStreamer(); _clearGLState(); for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { KRTexture *activeTexture = *itr; activeTexture->_swapHandles(); } + + // TODO - Implement proper double-buffering to reduce copy operations + m_streamerFenceMutex.lock(); + m_activeTextures_streamer_copy = m_activeTextures; + m_poolTextures_streamer_copy = m_poolTextures; + m_streamerFenceMutex.unlock(); + m_memoryTransferredThisFrame = 0; - balanceTextureMemory(); rotateBuffers(); } @@ -234,15 +241,25 @@ void KRTextureManager::endFrame(float deltaTime) } } +void KRTextureManager::doStreaming() +{ + // TODO - Implement proper double-buffering to reduce copy operations + m_streamerFenceMutex.lock(); + m_activeTextures_streamer = m_activeTextures_streamer_copy; + m_poolTextures_streamer = m_poolTextures_streamer_copy; + m_streamerFenceMutex.unlock(); + + balanceTextureMemory(); +} + void KRTextureManager::balanceTextureMemory() { - return; // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures // Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution. // Determine the additional amount of memory required in order to resize all active textures to the maximum size long wantedTextureMem = 0; - for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { + for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { KRTexture *activeTexture = *itr; wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize(); @@ -259,7 +276,7 @@ void KRTextureManager::balanceTextureMemory() maxDimInactive = maxDimInactive >> 1; potentialMemorySaving = 0; - for(std::set::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { + for(std::set::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) { KRTexture *poolTexture = *itr; long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); if(potentialMemoryDelta < 0) { @@ -270,7 +287,7 @@ void KRTextureManager::balanceTextureMemory() // Strip off mipmap levels of inactive textures to free up memory long inactive_texture_mem_used_target = 0; - for(std::set::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { + for(std::set::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) { KRTexture *poolTexture = *itr; long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); if(potentialMemoryDelta < 0) { @@ -286,7 +303,7 @@ void KRTextureManager::balanceTextureMemory() long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM; while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) { memory_available = getContext().KRENGINE_MAX_TEXTURE_MEM - inactive_texture_mem_used_target; - for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end() && memory_available > 0; itr++) { + for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) { KRTexture *activeTexture = *itr; memory_available -= activeTexture->getMemRequiredForSize(maxDimActive); } @@ -297,7 +314,7 @@ void KRTextureManager::balanceTextureMemory() } // Resize active textures to balance the memory usage and mipmap levels - for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end() && memory_available > 0; itr++) { + for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) { KRTexture *activeTexture = *itr; activeTexture->resize(maxDimActive); } diff --git a/KREngine/kraken/KRTextureManager.h b/KREngine/kraken/KRTextureManager.h index 02af498..222aac8 100644 --- a/KREngine/kraken/KRTextureManager.h +++ b/KREngine/kraken/KRTextureManager.h @@ -78,6 +78,8 @@ public: void _clearGLState(); void setMaxAnisotropy(float max_anisotropy); + void doStreaming(); + private: int m_iActiveTexture; @@ -89,15 +91,24 @@ private: GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS]; float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS]; + + std::set m_activeTextures; std::set m_poolTextures; + std::set m_activeTextures_streamer; + std::set m_poolTextures_streamer; + std::set m_activeTextures_streamer_copy; + std::set m_poolTextures_streamer_copy; + long m_textureMemUsed; void rotateBuffers(); void balanceTextureMemory(); KRTextureStreamer m_streamer; + + std::mutex m_streamerFenceMutex; }; #endif diff --git a/KREngine/kraken/KRTextureStreamer.h b/KREngine/kraken/KRTextureStreamer.h index b370871..22dbdb0 100644 --- a/KREngine/kraken/KRTextureStreamer.h +++ b/KREngine/kraken/KRTextureStreamer.h @@ -45,13 +45,17 @@ public: KRTextureStreamer(KRContext &context); ~KRTextureStreamer(); + void startStreamer(); + private: KRContext &m_context; std::thread m_thread; std::atomic m_stop; + std::atomic m_running; void run(); + }; #endif /* defined(KRTEXTURESTREAMER_H) */ diff --git a/KREngine/kraken/KRTextureStreamer.mm b/KREngine/kraken/KRTextureStreamer.mm index 004b2d9..26bc2ca 100644 --- a/KREngine/kraken/KRTextureStreamer.mm +++ b/KREngine/kraken/KRTextureStreamer.mm @@ -9,16 +9,25 @@ #include "KREngine-common.h" #include "KRTextureStreamer.h" +#include "KRContext.h" #include -EAGLContext *gTextureStreamerContext; +EAGLContext *gTextureStreamerContext = nil; KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context) { - gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; + m_running = false; m_stop = false; - m_thread = std::thread(&KRTextureStreamer::run, this); +} + +void KRTextureStreamer::startStreamer() +{ + if(!m_running) { + m_running = true; + gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; + m_thread = std::thread(&KRTextureStreamer::run, this); + } } KRTextureStreamer::~KRTextureStreamer() @@ -36,6 +45,11 @@ void KRTextureStreamer::run() while(!m_stop) { + if(m_context.getStreamingEnabled()) { + m_context.getTextureManager()->doStreaming(); + } std::this_thread::sleep_for( sleep_duration ); } + + m_running = false; } From 8b29ffab69e095b34f62d568e7b521e8ca295e86 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 16 Nov 2013 02:34:18 -0800 Subject: [PATCH 19/43] Asynchronous streaming and memory management improvements in progress. --HG-- branch : async_streaming --- KREngine/kraken/KRAnimation.cpp | 28 ++++++ KREngine/kraken/KRAnimation.h | 3 + KREngine/kraken/KRAnimationCurve.cpp | 10 +++ KREngine/kraken/KRAnimationCurve.h | 3 + KREngine/kraken/KRAnimationManager.cpp | 7 ++ KREngine/kraken/KRContext.cpp | 24 ++++- KREngine/kraken/KRContext.h | 3 +- KREngine/kraken/KRDataBlock.cpp | 119 +++++++++++++------------ KREngine/kraken/KRDataBlock.h | 2 + KREngine/kraken/KREngine.mm | 4 - KREngine/kraken/KRMeshStreamer.mm | 2 + KREngine/kraken/KRTexture.cpp | 103 ++++++++------------- KREngine/kraken/KRTexture.h | 10 ++- KREngine/kraken/KRTexture2D.cpp | 7 +- KREngine/kraken/KRTexture2D.h | 2 +- KREngine/kraken/KRTextureCube.cpp | 46 +++++----- KREngine/kraken/KRTextureManager.cpp | 27 ++++-- KREngine/kraken/KRTextureManager.h | 2 +- KREngine/kraken/KRTexturePVR.cpp | 73 +++++++-------- KREngine/kraken/KRTexturePVR.h | 9 +- KREngine/kraken/KRTextureStreamer.mm | 2 + KREngine/kraken/KRTextureTGA.cpp | 58 ++++++------ KREngine/kraken/KRTextureTGA.h | 4 +- 23 files changed, 301 insertions(+), 247 deletions(-) diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index f5db97b..d8ef8de 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -297,3 +297,31 @@ void KRAnimation::deleteCurves() } } +void KRAnimation::_lockData() +{ + for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer *layer = (*layer_itr).second; + for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute *attribute = *attribute_itr; + KRAnimationCurve *curve = attribute->getCurve(); + if(curve) { + curve->_lockData(); + } + } + } +} + +void KRAnimation::_unlockData() +{ + for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer *layer = (*layer_itr).second; + for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute *attribute = *attribute_itr; + KRAnimationCurve *curve = attribute->getCurve(); + if(curve) { + curve->_unlockData(); + } + } + } +} + diff --git a/KREngine/kraken/KRAnimation.h b/KREngine/kraken/KRAnimation.h index a052177..2c731ea 100644 --- a/KREngine/kraken/KRAnimation.h +++ b/KREngine/kraken/KRAnimation.h @@ -71,6 +71,9 @@ public: KRAnimation *split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes = true, bool clone_curves = true); void deleteCurves(); + void _lockData(); + void _unlockData(); + private: unordered_map m_layers; bool m_auto_play; diff --git a/KREngine/kraken/KRAnimationCurve.cpp b/KREngine/kraken/KRAnimationCurve.cpp index a99138e..366ae26 100644 --- a/KREngine/kraken/KRAnimationCurve.cpp +++ b/KREngine/kraken/KRAnimationCurve.cpp @@ -228,3 +228,13 @@ KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_fra getContext().getAnimationCurveManager()->addAnimationCurve(new_curve); return new_curve; } + +void KRAnimationCurve::_lockData() +{ + m_pData->lock(); +} + +void KRAnimationCurve::_unlockData() +{ + m_pData->unlock(); +} diff --git a/KREngine/kraken/KRAnimationCurve.h b/KREngine/kraken/KRAnimationCurve.h index ff5309c..2a2beda 100644 --- a/KREngine/kraken/KRAnimationCurve.h +++ b/KREngine/kraken/KRAnimationCurve.h @@ -67,6 +67,9 @@ public: KRAnimationCurve *split(const std::string &name, float start_time, float duration); KRAnimationCurve *split(const std::string &name, int start_frame, int frame_count); + void _lockData(); + void _unlockData(); + private: KRDataBlock *m_pData; diff --git a/KREngine/kraken/KRAnimationManager.cpp b/KREngine/kraken/KRAnimationManager.cpp index 76224e7..40e3667 100644 --- a/KREngine/kraken/KRAnimationManager.cpp +++ b/KREngine/kraken/KRAnimationManager.cpp @@ -38,6 +38,11 @@ KRAnimationManager::KRAnimationManager(KRContext &context) : KRContextObject(con } KRAnimationManager::~KRAnimationManager() { + for(std::set::iterator itr = m_activeAnimations.begin(); itr != m_activeAnimations.end(); itr++) { + KRAnimation *animation = *itr; + animation->_unlockData(); + } + for(unordered_map::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr){ delete (*itr).second; } @@ -52,11 +57,13 @@ void KRAnimationManager::startFrame(float deltaTime) // Add playing animations to the active animations list if(active_animations_itr == m_activeAnimations.end()) { m_activeAnimations.insert(animation); + animation->_lockData(); } } else { // Remove stopped animations from the active animations list if(active_animations_itr != m_activeAnimations.end()) { m_activeAnimations.erase(active_animations_itr); + animation->_unlockData(); } } } diff --git a/KREngine/kraken/KRContext.cpp b/KREngine/kraken/KRContext.cpp index ffa113a..fa4d2b9 100644 --- a/KREngine/kraken/KRContext.cpp +++ b/KREngine/kraken/KRContext.cpp @@ -17,7 +17,6 @@ int KRContext::KRENGINE_MAX_SHADER_HANDLES; int KRContext::KRENGINE_MAX_TEXTURE_HANDLES; int KRContext::KRENGINE_MAX_TEXTURE_MEM; int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX; -int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN; int KRContext::KRENGINE_MAX_TEXTURE_DIM; int KRContext::KRENGINE_MIN_TEXTURE_DIM; int KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT; @@ -281,3 +280,26 @@ void KRContext::setStreamingEnabled(bool enable) { m_streamingEnabled = enable; } + +void KRContext::getMemoryStats(long &free_memory) +{ + free_memory = 0; +#if TARGET_OS_IPHONE + mach_port_t host_port = mach_host_self(); + mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); + vm_size_t pagesize = 0; + vm_statistics_data_t vm_stat; + int total_ram = 256 * 1024 * 1024; + if(host_page_size(host_port, &pagesize) != KERN_SUCCESS) { + fprintf(stderr, "ERROR: Could not get VM page size.\n"); + } else if(host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { + fprintf(stderr, "ERROR: Could not get VM stats.\n"); + } else { + total_ram = (vm_stat.wire_count + vm_stat.active_count + vm_stat.inactive_count + vm_stat.free_count) * pagesize; + + free_memory = vm_stat.free_count * pagesize; + } +#else +#error Unsupported Platform +#endif +} diff --git a/KREngine/kraken/KRContext.h b/KREngine/kraken/KRContext.h index 824afbd..c75f846 100644 --- a/KREngine/kraken/KRContext.h +++ b/KREngine/kraken/KRContext.h @@ -29,7 +29,6 @@ public: static int KRENGINE_MAX_TEXTURE_HANDLES; static int KRENGINE_MAX_TEXTURE_MEM; static int KRENGINE_TARGET_TEXTURE_MEM_MAX; - static int KRENGINE_TARGET_TEXTURE_MEM_MIN; static int KRENGINE_MAX_TEXTURE_DIM; static int KRENGINE_MIN_TEXTURE_DIM; static int KRENGINE_MAX_TEXTURE_THROUGHPUT; @@ -76,6 +75,8 @@ public: bool getStreamingEnabled(); void setStreamingEnabled(bool enable); + void getMemoryStats(long &free_memory); + private: KRBundleManager *m_pBundleManager; KRSceneManager *m_pSceneManager; diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index 7331f70..fe7d522 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -146,6 +146,7 @@ KRDataBlock *KRDataBlock::getSubBlock(int start, int length) new_block->m_data = (unsigned char *)m_data + start + m_data_offset; } new_block->m_bReadOnly = true; + return new_block; } @@ -289,55 +290,58 @@ std::string KRDataBlock::getString() // Lock the memory, forcing it to be loaded into a contiguous block of address space void KRDataBlock::lock() { - - m_lockCount++; - - if(m_lockCount == 1) { + if(m_lockCount == 0) { // Memory mapped file; ensure data is mapped to ram if(m_fdPackFile) { - //fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); - - // Round m_data_offset down to the next memory page, as required by mmap - size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); - if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) { - int iError = errno; - switch(iError) { - case EACCES: - fprintf(stderr, "mmap failed with EACCES\n"); - break; - case EBADF: - fprintf(stderr, "mmap failed with EBADF\n"); - break; - case EMFILE: - fprintf(stderr, "mmap failed with EMFILE\n"); - break; - case EINVAL: - fprintf(stderr, "mmap failed with EINVAL\n"); - break; - case ENOMEM: - fprintf(stderr, "mmap failed with ENOMEM\n"); - break; - case ENXIO: - fprintf(stderr, "mmap failed with ENXIO\n"); - break; - case EOVERFLOW: - fprintf(stderr, "mmap failed with EOVERFLOW\n"); - break; - default: - fprintf(stderr, "mmap failed with errno: %i\n", iError); - break; + if(m_data_size < KRENGINE_MIN_MMAP) { + m_data = malloc(m_data_size); + assert(m_data != NULL); + copy(m_data); + } else { + //fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + + // Round m_data_offset down to the next memory page, as required by mmap + size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); + if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) { + int iError = errno; + switch(iError) { + case EACCES: + fprintf(stderr, "mmap failed with EACCES\n"); + break; + case EBADF: + fprintf(stderr, "mmap failed with EBADF\n"); + break; + case EMFILE: + fprintf(stderr, "mmap failed with EMFILE\n"); + break; + case EINVAL: + fprintf(stderr, "mmap failed with EINVAL\n"); + break; + case ENOMEM: + fprintf(stderr, "mmap failed with ENOMEM\n"); + break; + case ENXIO: + fprintf(stderr, "mmap failed with ENXIO\n"); + break; + case EOVERFLOW: + fprintf(stderr, "mmap failed with EOVERFLOW\n"); + break; + default: + fprintf(stderr, "mmap failed with errno: %i\n", iError); + break; + } + assert(false); // mmap() failed. } - assert(false); // mmap() failed. + m_mapCount++; + m_mapSize += m_data_size; + m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; + fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); + m_data = (unsigned char *)m_mmapData + alignment_offset; } - m_mapCount++; - m_mapSize += m_data_size; - m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; - fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); - m_data = (unsigned char *)m_mmapData + alignment_offset; } - } + m_lockCount++; } // Unlock the memory, releasing the address space for use by other allocations @@ -346,24 +350,29 @@ void KRDataBlock::unlock() // We expect that the data block was previously locked assertLocked(); - m_lockCount--; - if(m_lockCount == 0) { + + if(m_lockCount == 1) { // Memory mapped file; ensure data is unmapped from ram if(m_fdPackFile) { - //fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); - - munmap(m_mmapData, m_data_size); - m_data = NULL; - m_mmapData = NULL; - m_mapCount--; - m_mapSize -= m_data_size; - size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); - m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; - fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); + if(m_data_size < KRENGINE_MIN_MMAP) { + free(m_data); + m_data = NULL; + } else { + //fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + + munmap(m_mmapData, m_data_size); + m_data = NULL; + m_mmapData = NULL; + m_mapCount--; + m_mapSize -= m_data_size; + size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); + m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; + fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); + } } - } + m_lockCount--; } // Assert if not locked diff --git a/KREngine/kraken/KRDataBlock.h b/KREngine/kraken/KRDataBlock.h index 5198375..c1db34c 100644 --- a/KREngine/kraken/KRDataBlock.h +++ b/KREngine/kraken/KRDataBlock.h @@ -34,6 +34,8 @@ #include "KREngine-common.h" +#define KRENGINE_MIN_MMAP 327680000 + class KRDataBlock { public: KRDataBlock(); diff --git a/KREngine/kraken/KREngine.mm b/KREngine/kraken/KREngine.mm index b5fbb11..e1c8eb6 100644 --- a/KREngine/kraken/KREngine.mm +++ b/KREngine/kraken/KREngine.mm @@ -101,7 +101,6 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_MAX_VBO_MEM = total_ram * 2 / 4; KRContext::KRENGINE_MAX_TEXTURE_MEM = total_ram * 1 / 8; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = KRContext::KRENGINE_MAX_TEXTURE_MEM * 3 / 4; - KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = KRContext::KRENGINE_MAX_TEXTURE_MEM / 2; @@ -115,7 +114,6 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 64000000 * 2; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000 * 2; - KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 32000000 * 2; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000; @@ -126,7 +124,6 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 64000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000; - KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 32000000; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000; @@ -139,7 +136,6 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 512000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000; - KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 256000000; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000; diff --git a/KREngine/kraken/KRMeshStreamer.mm b/KREngine/kraken/KRMeshStreamer.mm index ec30a22..1940386 100644 --- a/KREngine/kraken/KRMeshStreamer.mm +++ b/KREngine/kraken/KRMeshStreamer.mm @@ -32,6 +32,8 @@ KRMeshStreamer::~KRMeshStreamer() void KRMeshStreamer::run() { + pthread_setname_np("Kraken - Mesh Streamer"); + std::chrono::microseconds sleep_duration( 100 ); [EAGLContext setCurrentContext: gMeshStreamerContext]; diff --git a/KREngine/kraken/KRTexture.cpp b/KREngine/kraken/KRTexture.cpp index 1588ff1..8eb872d 100644 --- a/KREngine/kraken/KRTexture.cpp +++ b/KREngine/kraken/KRTexture.cpp @@ -28,6 +28,8 @@ KRTexture::~KRTexture() } void KRTexture::releaseHandles() { + long mem_size = getMemSize(); + if(m_iNewHandle != 0) { GLDEBUG(glDeleteTextures(1, &m_iNewHandle)); m_iNewHandle = 0; @@ -35,10 +37,10 @@ void KRTexture::releaseHandles() { } if(m_iHandle != 0) { GLDEBUG(glDeleteTextures(1, &m_iHandle)); - getContext().getTextureManager()->memoryChanged(-getMemSize()); m_iHandle = 0; m_textureMemUsed = 0; } + getContext().getTextureManager()->memoryChanged(-mem_size); } long KRTexture::getMemSize() { @@ -52,45 +54,36 @@ long KRTexture::getReferencedMemSize() { void KRTexture::resize(int max_dim) { - if(m_iHandle != m_iNewHandle) return; // Only allow one resize() per frame - - if(max_dim == 0) { - m_iNewHandle = 0; - } else { - int target_dim = max_dim; - if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; -/* - int requiredMemoryTransfer = getThroughputRequiredForResize(target_dim); - int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize() - getReferencedMemSize(); + if(m_handle_lock.test_and_set()) + { + if(m_iHandle == m_iNewHandle) { + if(max_dim == 0) { + m_iNewHandle = 0; + } else { + int target_dim = max_dim; + if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - if(requiredMemoryDelta) { - // Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory) - - if(getContext().getTextureManager()->getMemoryTransferedThisFrame() + requiredMemoryTransfer > getContext().KRENGINE_MAX_TEXTURE_THROUGHPUT) { - // Exceeding per-frame transfer throughput; can't resize now - return; - } - - if(getContext().getTextureManager()->getMemUsed() + requiredMemoryDelta > getContext().KRENGINE_MAX_TEXTURE_MEM) { - // Exceeding total memory allocated to textures; can't resize now - return; - } -*/ - if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) { - if(!createGLTexture(target_dim)) { - assert(false); + if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) { + assert(m_newTextureMemUsed == 0); + m_newTextureMemUsed = getMemRequiredForSize(target_dim); + + getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed); + getContext().getTextureManager()->addMemoryTransferredThisFrame(m_newTextureMemUsed); + + if(!createGLTexture(target_dim)) { + getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed); + m_newTextureMemUsed = 0; + assert(false); + } } } -// } + } + + m_handle_lock.clear(); } } GLuint KRTexture::getHandle() { - /* - if(m_iHandle == 0 && m_iNewHandle == 0) { - resize(m_min_lod_max_dim); - } - */ resetPoolExpiry(); return m_iHandle; } @@ -100,34 +93,6 @@ void KRTexture::resetPoolExpiry() m_last_frame_used = getContext().getCurrentFrame(); } -long KRTexture::getThroughputRequiredForResize(int max_dim) -{ - // Calculate the throughput required for GPU texture upload if the texture is resized to max_dim. - // This default behaviour assumes that the texture will need to be deleted and regenerated to change the maximum mip-map level. - // If an OpenGL extension is present that allows a texture to be resized incrementally, then this method should be overridden - - if(max_dim == 0) { - return 0; - } else { - int target_dim = max_dim; - if(target_dim < m_min_lod_max_dim) target_dim = target_dim; - - - if(target_dim != m_current_lod_max_dim) { - int requiredMemory = getMemRequiredForSize(target_dim); - int requiredMemoryDelta = requiredMemory - getMemSize() - getReferencedMemSize(); - - if(requiredMemoryDelta == 0) { - // Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory) - return 0; - } - return requiredMemory; - } else { - return 0; - } - } -} - long KRTexture::getLastFrameUsed() { return m_last_frame_used; @@ -169,14 +134,18 @@ bool KRTexture::canStreamOut() const { void KRTexture::_swapHandles() { - if(m_iNewHandle != m_iHandle) { - if(m_iHandle != 0) { - GLDEBUG(glDeleteTextures(1, &m_iHandle)); - getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed - m_textureMemUsed); - m_textureMemUsed = m_newTextureMemUsed; + if(m_handle_lock.test_and_set()) + { + if(m_iHandle != m_iNewHandle) { + if(m_iHandle != 0) { + GLDEBUG(glDeleteTextures(1, &m_iHandle)); + getContext().getTextureManager()->memoryChanged(-m_textureMemUsed); + } + m_textureMemUsed = (long)m_newTextureMemUsed; m_newTextureMemUsed = 0; + m_iHandle = m_iNewHandle; } - m_iHandle = m_iNewHandle; + m_handle_lock.clear(); } } diff --git a/KREngine/kraken/KRTexture.h b/KREngine/kraken/KRTexture.h index 8ecd169..592ac14 100644 --- a/KREngine/kraken/KRTexture.h +++ b/KREngine/kraken/KRTexture.h @@ -52,7 +52,6 @@ public: virtual long getReferencedMemSize(); virtual long getMemRequiredForSize(int max_dim) = 0; - virtual long getThroughputRequiredForResize(int max_dim); virtual void resize(int max_dim); long getLastFrameUsed(); @@ -74,10 +73,9 @@ protected: GLuint getHandle(); - GLuint m_iHandle; + GLuint m_iHandle; GLuint m_iNewHandle; - long m_textureMemUsed; - long m_newTextureMemUsed; + std::atomic_flag m_handle_lock; int m_current_lod_max_dim; @@ -86,6 +84,10 @@ protected: long m_last_frame_used; long m_last_frame_bound; + +private: + std::atomic m_textureMemUsed; + std::atomic m_newTextureMemUsed; }; diff --git a/KREngine/kraken/KRTexture2D.cpp b/KREngine/kraken/KRTexture2D.cpp index e5d6138..11918d9 100644 --- a/KREngine/kraken/KRTexture2D.cpp +++ b/KREngine/kraken/KRTexture2D.cpp @@ -49,12 +49,9 @@ bool KRTexture2D::createGLTexture(int lod_max_dim) { bool success = true; int prev_lod_max_dim = 0; - long prev_mem_size = 0; #if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage if(m_iHandle != 0) { - prev_mem_size = getMemSize(); - m_textureMemUsed = 0; prev_lod_max_dim = m_current_lod_max_dim; } #endif @@ -74,10 +71,8 @@ bool KRTexture2D::createGLTexture(int lod_max_dim) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); } - if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, m_newTextureMemUsed, prev_lod_max_dim)) { + if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, prev_lod_max_dim)) { GLDEBUG(glDeleteTextures(1, &m_iNewHandle)); - getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed); - m_newTextureMemUsed = 0; m_iNewHandle = m_iHandle; m_current_lod_max_dim = prev_lod_max_dim; success = false; diff --git a/KREngine/kraken/KRTexture2D.h b/KREngine/kraken/KRTexture2D.h index 87efc8f..139e5d5 100644 --- a/KREngine/kraken/KRTexture2D.h +++ b/KREngine/kraken/KRTexture2D.h @@ -46,7 +46,7 @@ public: virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data); - virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) = 0; + virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim) = 0; virtual void bind(GLuint texture_unit); protected: diff --git a/KREngine/kraken/KRTextureCube.cpp b/KREngine/kraken/KRTextureCube.cpp index 710aef0..dcf8e0f 100644 --- a/KREngine/kraken/KRTextureCube.cpp +++ b/KREngine/kraken/KRTextureCube.cpp @@ -68,37 +68,31 @@ bool KRTextureCube::createGLTexture(int lod_max_dim) #endif - - - m_iNewHandle = 0; GLDEBUG(glGenTextures(1, &m_iNewHandle)); - if(m_iNewHandle == 0) { - m_iNewHandle = m_iHandle; - success = false; - } else { - m_current_lod_max_dim = 0; - GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iNewHandle)); - - bool bMipMaps = false; + assert(m_iNewHandle != 0); + + m_current_lod_max_dim = 0; + GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iNewHandle)); + + bool bMipMaps = false; - for(int i=0; i<6; i++) { - std::string faceName = getName() + SUFFIXES[i]; - KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); - if(faceTexture) { - if(faceTexture->hasMipmaps()) bMipMaps = true; - faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, m_newTextureMemUsed, prev_lod_max_dim); - } - } - - if(bMipMaps) { - GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); - } else { - // GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); - GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); + for(int i=0; i<6; i++) { + std::string faceName = getName() + SUFFIXES[i]; + KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); + if(faceTexture) { + if(faceTexture->hasMipmaps()) bMipMaps = true; + faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, prev_lod_max_dim); } } + + if(bMipMaps) { + GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); + } else { + // GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); + GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); + } return success; diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 5484a9d..b7b8bfa 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -266,7 +266,7 @@ void KRTextureManager::balanceTextureMemory() } // Determine how much memory we need to free up - long memoryDeficit = wantedTextureMem - (getContext().KRENGINE_MAX_TEXTURE_MEM - getMemUsed()); + long memoryDeficit = wantedTextureMem - (getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - getMemUsed()); // Determine how many mip map levels we need to strip off of inactive textures to free the memory we need @@ -289,10 +289,17 @@ void KRTextureManager::balanceTextureMemory() long inactive_texture_mem_used_target = 0; for(std::set::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) { KRTexture *poolTexture = *itr; - long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); + long mem_required = poolTexture->getMemRequiredForSize(maxDimInactive); + long potentialMemoryDelta = mem_required - poolTexture->getMemSize(); if(potentialMemoryDelta < 0) { - poolTexture->resize(maxDimInactive); - inactive_texture_mem_used_target += poolTexture->getMemRequiredForSize(maxDimInactive); + if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) { + long mem_free; + m_pContext->getMemoryStats(mem_free); + if(mem_required * 2 < mem_free - 10000000) { + poolTexture->resize(maxDimInactive); + } + } + inactive_texture_mem_used_target += mem_required; } else { inactive_texture_mem_used_target += poolTexture->getMemSize(); } @@ -302,7 +309,7 @@ void KRTextureManager::balanceTextureMemory() long memory_available = 0; long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM; while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) { - memory_available = getContext().KRENGINE_MAX_TEXTURE_MEM - inactive_texture_mem_used_target; + memory_available = getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - inactive_texture_mem_used_target; for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) { KRTexture *activeTexture = *itr; memory_available -= activeTexture->getMemRequiredForSize(maxDimActive); @@ -316,7 +323,14 @@ void KRTextureManager::balanceTextureMemory() // Resize active textures to balance the memory usage and mipmap levels for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) { KRTexture *activeTexture = *itr; - activeTexture->resize(maxDimActive); + long mem_required = activeTexture->getMemRequiredForSize(maxDimActive); + if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) { + long mem_free; + m_pContext->getMemoryStats(mem_free); + if(mem_required * 2 < mem_free - 10000000) { + activeTexture->resize(maxDimActive); + } + } } //fprintf(stderr, "Active mipmap size: %i Inactive mapmap size: %i\n", (int)maxDimActive, (int)maxDimInactive); @@ -358,6 +372,7 @@ void KRTextureManager::addMemoryTransferredThisFrame(long memoryTransferred) void KRTextureManager::memoryChanged(long memoryDelta) { m_textureMemUsed += memoryDelta; + //fprintf(stderr, "Texture Memory: %ld / %i\n", (long)m_textureMemUsed, KRContext::KRENGINE_MAX_TEXTURE_MEM); } unordered_map &KRTextureManager::getTextures() diff --git a/KREngine/kraken/KRTextureManager.h b/KREngine/kraken/KRTextureManager.h index 222aac8..b55a473 100644 --- a/KREngine/kraken/KRTextureManager.h +++ b/KREngine/kraken/KRTextureManager.h @@ -101,7 +101,7 @@ private: std::set m_activeTextures_streamer_copy; std::set m_poolTextures_streamer_copy; - long m_textureMemUsed; + std::atomic m_textureMemUsed; void rotateBuffers(); void balanceTextureMemory(); diff --git a/KREngine/kraken/KRTexturePVR.cpp b/KREngine/kraken/KRTexturePVR.cpp index 4765597..6ce9a65 100644 --- a/KREngine/kraken/KRTexturePVR.cpp +++ b/KREngine/kraken/KRTexturePVR.cpp @@ -64,9 +64,11 @@ typedef struct _PVRTexHeader KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) { #if TARGET_OS_IPHONE - m_pData->lock(); - PVRTexHeader *header = (PVRTexHeader *)m_pData->getStart(); - uint32_t formatFlags = header->flags & PVR_TEXTURE_FLAG_TYPE_MASK; + + PVRTexHeader header; + m_pData->copy(&header, 0, sizeof(PVRTexHeader)); + + uint32_t formatFlags = header.flags & PVR_TEXTURE_FLAG_TYPE_MASK; if (formatFlags == kPVRTextureFlagTypePVRTC_4) { m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; } else if(formatFlags == kPVRTextureFlagTypePVRTC_2) { @@ -75,7 +77,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na assert(false); } - uint32_t pvrTag = header->pvrTag; + uint32_t pvrTag = header.pvrTag; if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) || gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) || gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) || @@ -83,12 +85,12 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na assert(false); } - m_iWidth = header->width; // Note: call __builtin_bswap32 when needed to switch endianness - m_iHeight = header->height; - m_bHasAlpha = header->bitmaskAlpha; + m_iWidth = header.width; // Note: call __builtin_bswap32 when needed to switch endianness + m_iHeight = header.height; + m_bHasAlpha = header.bitmaskAlpha; uint32_t dataStart = sizeof(PVRTexHeader); - uint32_t dataLength = header->dataLength, dataOffset = 0, dataSize = 0; + uint32_t dataLength = header.dataLength, dataOffset = 0, dataSize = 0; uint32_t width = m_iWidth, height = m_iHeight, bpp = 4; uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0; @@ -115,11 +117,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na } dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8); - dataBlockStruct newBlock; - newBlock.start = dataStart + dataOffset; - newBlock.length = dataSize; - - m_blocks.push_back(newBlock); + m_blocks.push_back(m_pData->getSubBlock(dataStart + dataOffset, dataSize)); dataOffset += dataSize; @@ -135,13 +133,15 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight; m_min_lod_max_dim = width > height ? width : height; - - m_pData->unlock(); #endif } KRTexturePVR::~KRTexturePVR() { - + for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock *block = *itr; + delete block; + } + m_blocks.clear(); } long KRTexturePVR::getMemRequiredForSize(int max_dim) @@ -154,10 +154,10 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim) int height = m_iHeight; long memoryRequired = 0; - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - dataBlockStruct block = *itr; + for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock *block = *itr; if(width <= target_dim && height <= target_dim) { - memoryRequired += block.length; + memoryRequired += block->getSize(); } width = width >> 1; @@ -173,7 +173,7 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim) return memoryRequired; } -bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) +bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim) { int target_dim = lod_max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; @@ -196,7 +196,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo int level_count=0; int max_lod_width=0; int max_lod_height=0; - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { if(width <= target_dim && height <= target_dim) { if(max_lod_width == 0) { max_lod_width = width; @@ -229,8 +229,8 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo // Upload texture data int destination_level=0; int source_level = 0; - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - dataBlockStruct block = *itr; + for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock *block = *itr; if(width <= target_dim && height <= target_dim) { if(width > current_lod_max_dim) { @@ -245,24 +245,23 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo // GLDEBUG(glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glCopyTextureLevelsAPPLE(m_iNewHandle, m_iHandle, source_level, 1)); } else { - // glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); - m_pData->lock(); - GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, (char *)m_pData->getStart() + block.start)); - m_pData->unlock(); -// GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, block.start)); - memoryTransferred += block.length; // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE + block->lock(); + GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, (GLsizei)block->getSize(), block->getStart())); + block->unlock(); + + memoryTransferred += block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE } #else - m_pData->lock(); + block->lock(); #if GL_EXT_texture_storage - GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, (char *)m_pData->getStart() + block.start)); + GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block->getSize(), block->getStart())); #else - GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, (char *)m_pData->getStart() + block.start)); + GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block->getSize(), block->getStart())); #endif - m_pData->unlock(); - memoryTransferred += block.length; // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE + block->unlock(); + memoryTransferred += block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE #endif - memoryRequired += block.length; + memoryRequired += block->getSize(); // // err = glGetError(); // if (err != GL_NO_ERROR) { @@ -288,10 +287,6 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo } } - textureMemUsed += memoryRequired; - getContext().getTextureManager()->memoryChanged(memoryRequired); - getContext().getTextureManager()->addMemoryTransferredThisFrame(memoryTransferred); - return true; } diff --git a/KREngine/kraken/KRTexturePVR.h b/KREngine/kraken/KRTexturePVR.h index 97c6505..974619e 100644 --- a/KREngine/kraken/KRTexturePVR.h +++ b/KREngine/kraken/KRTexturePVR.h @@ -18,7 +18,7 @@ public: virtual ~KRTexturePVR(); virtual std::string getExtension(); - bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim); + bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim); virtual long getMemRequiredForSize(int max_dim); @@ -29,12 +29,7 @@ protected: GLenum m_internalFormat; bool m_bHasAlpha; - struct dataBlockStruct { - uint32_t start; - uint32_t length; - }; - - std::list m_blocks; + std::list m_blocks; }; #endif diff --git a/KREngine/kraken/KRTextureStreamer.mm b/KREngine/kraken/KRTextureStreamer.mm index 26bc2ca..5dc8682 100644 --- a/KREngine/kraken/KRTextureStreamer.mm +++ b/KREngine/kraken/KRTextureStreamer.mm @@ -40,6 +40,8 @@ KRTextureStreamer::~KRTextureStreamer() void KRTextureStreamer::run() { + pthread_setname_np("Kraken - Texture Streamer"); + std::chrono::microseconds sleep_duration( 100 ); [EAGLContext setCurrentContext: gTextureStreamerContext]; diff --git a/KREngine/kraken/KRTextureTGA.cpp b/KREngine/kraken/KRTextureTGA.cpp index b5fd7fa..373385b 100644 --- a/KREngine/kraken/KRTextureTGA.cpp +++ b/KREngine/kraken/KRTextureTGA.cpp @@ -33,6 +33,34 @@ KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string na m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height; m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images + switch(pHeader->imagetype) { + case 2: // rgb + switch(pHeader->bitsperpixel) { + case 24: + { + m_imageSize = pHeader->width * pHeader->height * 4; + } + break; + case 32: + { + m_imageSize = pHeader->width * pHeader->height * 4; + } + break; + + default: + { + assert(false); + } + break; + } + break; + default: + { + assert(false); + break; + } + } + data->unlock(); } @@ -41,7 +69,7 @@ KRTextureTGA::~KRTextureTGA() } -bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) +bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim) { m_pData->lock(); TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); @@ -83,10 +111,6 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo m_pData->unlock(); return false; } - int memAllocated = pHeader->width * pHeader->height * 4; - textureMemUsed += memAllocated; - getContext().getTextureManager()->memoryChanged(memAllocated); - getContext().getTextureManager()->addMemoryTransferredThisFrame(memAllocated); current_lod_max_dim = m_max_lod_max_dim; } break; @@ -98,10 +122,6 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo m_pData->unlock(); return false; } - int memAllocated = pHeader->width * pHeader->height * 4; - textureMemUsed += memAllocated; - getContext().getTextureManager()->memoryChanged(memAllocated); - getContext().getTextureManager()->addMemoryTransferredThisFrame(memAllocated); current_lod_max_dim = m_max_lod_max_dim; } break; @@ -121,25 +141,7 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo long KRTextureTGA::getMemRequiredForSize(int max_dim) { - TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); - switch(pHeader->imagetype) { - case 2: // rgb - switch(pHeader->bitsperpixel) { - case 24: - { - return pHeader->width * pHeader->height * 4; - } - break; - case 32: - { - return pHeader->width * pHeader->height * 4; - } - break; - } - break; - } - - return 0; + return m_imageSize; } std::string KRTextureTGA::getExtension() diff --git a/KREngine/kraken/KRTextureTGA.h b/KREngine/kraken/KRTextureTGA.h index 1624341..82826d7 100644 --- a/KREngine/kraken/KRTextureTGA.h +++ b/KREngine/kraken/KRTextureTGA.h @@ -18,9 +18,11 @@ public: virtual ~KRTextureTGA(); virtual std::string getExtension(); - bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim); + bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim); virtual long getMemRequiredForSize(int max_dim); +private: + long m_imageSize; }; #endif From 240d2ee27825dcb0021c4c7d0117033e3fd70278 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 16 Nov 2013 03:22:31 -0800 Subject: [PATCH 20/43] Asynchronous streaming and memory management improvements in progress. Stability improved. --HG-- branch : async_streaming --- KREngine/kraken/KRDataBlock.h | 2 +- KREngine/kraken/KRTexture.cpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/KREngine/kraken/KRDataBlock.h b/KREngine/kraken/KRDataBlock.h index c1db34c..fc001cf 100644 --- a/KREngine/kraken/KRDataBlock.h +++ b/KREngine/kraken/KRDataBlock.h @@ -34,7 +34,7 @@ #include "KREngine-common.h" -#define KRENGINE_MIN_MMAP 327680000 +#define KRENGINE_MIN_MMAP 32768 class KRDataBlock { public: diff --git a/KREngine/kraken/KRTexture.cpp b/KREngine/kraken/KRTexture.cpp index 8eb872d..af9f351 100644 --- a/KREngine/kraken/KRTexture.cpp +++ b/KREngine/kraken/KRTexture.cpp @@ -20,6 +20,7 @@ KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, m_newTextureMemUsed = 0; m_last_frame_used = 0; m_last_frame_bound = 0; + m_handle_lock.clear(); } KRTexture::~KRTexture() @@ -30,6 +31,8 @@ KRTexture::~KRTexture() void KRTexture::releaseHandles() { long mem_size = getMemSize(); + while(m_handle_lock.test_and_set()); // Spin lock + if(m_iNewHandle != 0) { GLDEBUG(glDeleteTextures(1, &m_iNewHandle)); m_iNewHandle = 0; @@ -40,6 +43,9 @@ void KRTexture::releaseHandles() { m_iHandle = 0; m_textureMemUsed = 0; } + + m_handle_lock.clear(); + getContext().getTextureManager()->memoryChanged(-mem_size); } @@ -54,7 +60,7 @@ long KRTexture::getReferencedMemSize() { void KRTexture::resize(int max_dim) { - if(m_handle_lock.test_and_set()) + if(!m_handle_lock.test_and_set()) { if(m_iHandle == m_iNewHandle) { if(max_dim == 0) { @@ -134,8 +140,7 @@ bool KRTexture::canStreamOut() const { void KRTexture::_swapHandles() { - if(m_handle_lock.test_and_set()) - { + if(!m_handle_lock.test_and_set()) { if(m_iHandle != m_iNewHandle) { if(m_iHandle != 0) { GLDEBUG(glDeleteTextures(1, &m_iHandle)); From 7f09dae997b753bf35e3ce0fe4939bdbade000b8 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 16 Nov 2013 16:27:23 -0800 Subject: [PATCH 21/43] Synced up with default branch --HG-- branch : nfb --- KREngine/kraken/KRDataBlock.cpp | 4 ++-- KREngine/kraken/KRRenderSettings.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index fe7d522..28578f8 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -336,7 +336,7 @@ void KRDataBlock::lock() m_mapCount++; m_mapSize += m_data_size; m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; - fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); + // fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); m_data = (unsigned char *)m_mmapData + alignment_offset; } } @@ -368,7 +368,7 @@ void KRDataBlock::unlock() m_mapSize -= m_data_size; size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1); m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; - fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); + // fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); } } } diff --git a/KREngine/kraken/KRRenderSettings.cpp b/KREngine/kraken/KRRenderSettings.cpp index 7a31679..6c9efe8 100644 --- a/KREngine/kraken/KRRenderSettings.cpp +++ b/KREngine/kraken/KRRenderSettings.cpp @@ -15,7 +15,7 @@ KRRenderSettings::KRRenderSettings() siren_enable_hrtf = true; siren_reverb_max_length = 2.0f; - m_enable_realtime_occlusion = false; + m_enable_realtime_occlusion = true; bShowShadowBuffer = false; bShowOctree = false; bShowDeferred = false; From 29b518610b7cae44a59aec955484803f1a3ba6e3 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 17 Nov 2013 01:46:12 -0800 Subject: [PATCH 22/43] Implemented API to read and seek the audio playback position of KRAudioSource --HG-- extra : source : 5ef720e0f476c72b85a7e2fc841af965d2038264 --- KREngine/kraken/KRAudioSource.cpp | 96 +++++++++++++++++++++++-------- KREngine/kraken/KRAudioSource.h | 39 +++++++++++-- 2 files changed, 106 insertions(+), 29 deletions(-) diff --git a/KREngine/kraken/KRAudioSource.cpp b/KREngine/kraken/KRAudioSource.cpp index afef53d..094817d 100644 --- a/KREngine/kraken/KRAudioSource.cpp +++ b/KREngine/kraken/KRAudioSource.cpp @@ -56,6 +56,7 @@ KRAudioSource::KRAudioSource(KRScene &scene, std::string name) : KRNode(scene, n m_enable_obstruction = true; m_start_audio_frame = -1; + m_paused_audio_frame = 0; } KRAudioSource::~KRAudioSource() @@ -314,12 +315,13 @@ void KRAudioSource::setRolloffFactor(float rolloff_factor) void KRAudioSource::setLooping(bool looping) { + // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect m_looping = looping; - // Audio source must be stopped and re-started for loop mode changes to take effect } bool KRAudioSource::getLooping() { + // Returns true if the playback will automatically loop return m_looping; } @@ -400,38 +402,54 @@ void KRAudioSource::physicsUpdate(float deltaTime) void KRAudioSource::play() { - KRAudioManager *audioManager = getContext().getAudioManager(); - m_start_audio_frame = audioManager->getAudioFrame(); - audioManager->activateAudioSource(this); - if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { - getContext().getAudioManager()->makeCurrentContext(); - prime(); - updatePosition(); + // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. + // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. + // If not set to looping, audio playback ends automatically at the end of the sample + + if(!m_playing) { + KRAudioManager *audioManager = getContext().getAudioManager(); + assert(m_start_audio_frame == -1); + m_start_audio_frame = audioManager->getAudioFrame() - m_paused_audio_frame; + m_paused_audio_frame = -1; + audioManager->activateAudioSource(this); + if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { + getContext().getAudioManager()->makeCurrentContext(); + prime(); + updatePosition(); - if(m_is3d) { - ALDEBUG(alSource3f(m_sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f)); - ALDEBUG(alSourcef(m_sourceID, AL_REFERENCE_DISTANCE, m_referenceDistance)); - ALDEBUG(alSourcef(m_sourceID, AL_ROLLOFF_FACTOR, m_rolloffFactor)); - ALDEBUG(alcASASetSourceProc(ALC_ASA_REVERB_SEND_LEVEL, m_sourceID, &m_reverb, sizeof(m_reverb))); - ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_FALSE)); - } else { - ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_TRUE)); - ALDEBUG(alSource3f(m_sourceID, AL_POSITION, 0.0, 0.0, 0.0)); + if(m_is3d) { + ALDEBUG(alSource3f(m_sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f)); + ALDEBUG(alSourcef(m_sourceID, AL_REFERENCE_DISTANCE, m_referenceDistance)); + ALDEBUG(alSourcef(m_sourceID, AL_ROLLOFF_FACTOR, m_rolloffFactor)); + ALDEBUG(alcASASetSourceProc(ALC_ASA_REVERB_SEND_LEVEL, m_sourceID, &m_reverb, sizeof(m_reverb))); + ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_FALSE)); + } else { + ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_TRUE)); + ALDEBUG(alSource3f(m_sourceID, AL_POSITION, 0.0, 0.0, 0.0)); + } + ALDEBUG(alSourcePlay(m_sourceID)); } - ALDEBUG(alSourcePlay(m_sourceID)); } m_playing = true; } void KRAudioSource::stop() { - m_start_audio_frame = -1; - m_playing = false; - getContext().getAudioManager()->deactivateAudioSource(this); + // Stop playback of audio. If audio is already stopped, this has no effect. + // If play() is called afterwards, playback will continue at the current audio sample position. + + if(m_playing) { + m_paused_audio_frame = getAudioFrame(); + m_start_audio_frame = -1; + m_playing = false; + getContext().getAudioManager()->deactivateAudioSource(this); + } } bool KRAudioSource::isPlaying() { + // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. + return m_playing; } @@ -504,16 +522,46 @@ int KRAudioSource::getBufferFrame() return m_currentBufferFrame; } -__int64_t KRAudioSource::getStartAudioFrame() +__int64_t KRAudioSource::getAudioFrame() { - return m_start_audio_frame; + // Returns the audio playback position in units of integer audio frames. + + if(m_playing) { + return getContext().getAudioManager()->getAudioFrame() - m_start_audio_frame; + } else { + return m_paused_audio_frame; + } +} + +void KRAudioSource::setAudioFrame(__int64_t next_frame) +{ + // Sets the audio playback position with units of integer audio frames. + if(m_playing) { + m_start_audio_frame = getContext().getAudioManager()->getAudioFrame() - next_frame; + } else { + m_paused_audio_frame = next_frame; + } +} + + +float KRAudioSource::getAudioTime() +{ + // Gets the audio playback position with units of floating point seconds. + + return getAudioFrame() / 44100.0f; +} + +void KRAudioSource::setAudioTime(float new_position) +{ + // Sets the audio playback position with units of floating point seconds. + setAudioFrame(new_position * 44100.0f); } void KRAudioSource::sample(int frame_count, int channel, float *buffer, float gain) { KRAudioSample *source_sample = getAudioSample(); if(source_sample && m_playing) { - __int64_t next_frame = getContext().getAudioManager()->getAudioFrame() - getStartAudioFrame(); + __int64_t next_frame = getAudioFrame(); source_sample->sample(next_frame, frame_count, channel, buffer, gain, m_looping); if(!m_looping && next_frame > source_sample->getFrameCount()) { stop(); diff --git a/KREngine/kraken/KRAudioSource.h b/KREngine/kraken/KRAudioSource.h index 8472f36..a82343e 100644 --- a/KREngine/kraken/KRAudioSource.h +++ b/KREngine/kraken/KRAudioSource.h @@ -51,10 +51,41 @@ public: virtual void physicsUpdate(float deltaTime); void render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass); + + // ---- Audio Playback Controls ---- + + // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. + // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. + // If not set to looping, audio playback ends automatically at the end of the sample void play(); + + // Stop playback of audio. If audio is already stopped, this has no effect. + // If play() is called afterwards, playback will continue at the current audio sample position. void stop(); + + // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. bool isPlaying(); + // Returns the audio playback position in units of integer audio frames. + __int64_t getAudioFrame(); + + // Sets the audio playback position with units of integer audio frames. + void setAudioFrame(__int64_t next_frame); + + // Gets the audio playback position with units of floating point seconds. + float getAudioTime(); + + // Sets the audio playback position with units of floating point seconds. + void setAudioTime(float new_position); + + // Returns true if the playback will automatically loop + bool getLooping(); + + // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect + void setLooping(bool looping); + + // ---- End: Audio Playback Controls ---- + void setSample(const std::string &sound_name); std::string getSample(); @@ -66,8 +97,7 @@ public: float getPitch(); void setPitch(float pitch); - bool getLooping(); - void setLooping(bool looping); + bool getIs3D(); void setIs3D(bool is3D); @@ -94,12 +124,11 @@ public: KRAudioBuffer *getBuffer(); int getBufferFrame(); - - __int64_t getStartAudioFrame(); void sample(int frame_count, int channel, float *buffer, float gain); private: - __int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback + __int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback; when paused or not playing, this contains a value of -1 + __int64_t m_paused_audio_frame; // When paused or not playing, this contains the local audio frame number. When playing, this contains a value of -1 int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer void advanceBuffer(); From 19bf71938d016fead47ee1a23f524194d262a245 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 17 Nov 2013 01:46:12 -0800 Subject: [PATCH 23/43] Implemented API to read and seek the audio playback position of KRAudioSource --HG-- branch : nfb --- KREngine/kraken/KRAudioSource.cpp | 96 +++++++++++++++++++++++-------- KREngine/kraken/KRAudioSource.h | 39 +++++++++++-- 2 files changed, 106 insertions(+), 29 deletions(-) diff --git a/KREngine/kraken/KRAudioSource.cpp b/KREngine/kraken/KRAudioSource.cpp index afef53d..094817d 100644 --- a/KREngine/kraken/KRAudioSource.cpp +++ b/KREngine/kraken/KRAudioSource.cpp @@ -56,6 +56,7 @@ KRAudioSource::KRAudioSource(KRScene &scene, std::string name) : KRNode(scene, n m_enable_obstruction = true; m_start_audio_frame = -1; + m_paused_audio_frame = 0; } KRAudioSource::~KRAudioSource() @@ -314,12 +315,13 @@ void KRAudioSource::setRolloffFactor(float rolloff_factor) void KRAudioSource::setLooping(bool looping) { + // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect m_looping = looping; - // Audio source must be stopped and re-started for loop mode changes to take effect } bool KRAudioSource::getLooping() { + // Returns true if the playback will automatically loop return m_looping; } @@ -400,38 +402,54 @@ void KRAudioSource::physicsUpdate(float deltaTime) void KRAudioSource::play() { - KRAudioManager *audioManager = getContext().getAudioManager(); - m_start_audio_frame = audioManager->getAudioFrame(); - audioManager->activateAudioSource(this); - if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { - getContext().getAudioManager()->makeCurrentContext(); - prime(); - updatePosition(); + // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. + // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. + // If not set to looping, audio playback ends automatically at the end of the sample + + if(!m_playing) { + KRAudioManager *audioManager = getContext().getAudioManager(); + assert(m_start_audio_frame == -1); + m_start_audio_frame = audioManager->getAudioFrame() - m_paused_audio_frame; + m_paused_audio_frame = -1; + audioManager->activateAudioSource(this); + if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { + getContext().getAudioManager()->makeCurrentContext(); + prime(); + updatePosition(); - if(m_is3d) { - ALDEBUG(alSource3f(m_sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f)); - ALDEBUG(alSourcef(m_sourceID, AL_REFERENCE_DISTANCE, m_referenceDistance)); - ALDEBUG(alSourcef(m_sourceID, AL_ROLLOFF_FACTOR, m_rolloffFactor)); - ALDEBUG(alcASASetSourceProc(ALC_ASA_REVERB_SEND_LEVEL, m_sourceID, &m_reverb, sizeof(m_reverb))); - ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_FALSE)); - } else { - ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_TRUE)); - ALDEBUG(alSource3f(m_sourceID, AL_POSITION, 0.0, 0.0, 0.0)); + if(m_is3d) { + ALDEBUG(alSource3f(m_sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f)); + ALDEBUG(alSourcef(m_sourceID, AL_REFERENCE_DISTANCE, m_referenceDistance)); + ALDEBUG(alSourcef(m_sourceID, AL_ROLLOFF_FACTOR, m_rolloffFactor)); + ALDEBUG(alcASASetSourceProc(ALC_ASA_REVERB_SEND_LEVEL, m_sourceID, &m_reverb, sizeof(m_reverb))); + ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_FALSE)); + } else { + ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_TRUE)); + ALDEBUG(alSource3f(m_sourceID, AL_POSITION, 0.0, 0.0, 0.0)); + } + ALDEBUG(alSourcePlay(m_sourceID)); } - ALDEBUG(alSourcePlay(m_sourceID)); } m_playing = true; } void KRAudioSource::stop() { - m_start_audio_frame = -1; - m_playing = false; - getContext().getAudioManager()->deactivateAudioSource(this); + // Stop playback of audio. If audio is already stopped, this has no effect. + // If play() is called afterwards, playback will continue at the current audio sample position. + + if(m_playing) { + m_paused_audio_frame = getAudioFrame(); + m_start_audio_frame = -1; + m_playing = false; + getContext().getAudioManager()->deactivateAudioSource(this); + } } bool KRAudioSource::isPlaying() { + // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. + return m_playing; } @@ -504,16 +522,46 @@ int KRAudioSource::getBufferFrame() return m_currentBufferFrame; } -__int64_t KRAudioSource::getStartAudioFrame() +__int64_t KRAudioSource::getAudioFrame() { - return m_start_audio_frame; + // Returns the audio playback position in units of integer audio frames. + + if(m_playing) { + return getContext().getAudioManager()->getAudioFrame() - m_start_audio_frame; + } else { + return m_paused_audio_frame; + } +} + +void KRAudioSource::setAudioFrame(__int64_t next_frame) +{ + // Sets the audio playback position with units of integer audio frames. + if(m_playing) { + m_start_audio_frame = getContext().getAudioManager()->getAudioFrame() - next_frame; + } else { + m_paused_audio_frame = next_frame; + } +} + + +float KRAudioSource::getAudioTime() +{ + // Gets the audio playback position with units of floating point seconds. + + return getAudioFrame() / 44100.0f; +} + +void KRAudioSource::setAudioTime(float new_position) +{ + // Sets the audio playback position with units of floating point seconds. + setAudioFrame(new_position * 44100.0f); } void KRAudioSource::sample(int frame_count, int channel, float *buffer, float gain) { KRAudioSample *source_sample = getAudioSample(); if(source_sample && m_playing) { - __int64_t next_frame = getContext().getAudioManager()->getAudioFrame() - getStartAudioFrame(); + __int64_t next_frame = getAudioFrame(); source_sample->sample(next_frame, frame_count, channel, buffer, gain, m_looping); if(!m_looping && next_frame > source_sample->getFrameCount()) { stop(); diff --git a/KREngine/kraken/KRAudioSource.h b/KREngine/kraken/KRAudioSource.h index 8472f36..a82343e 100644 --- a/KREngine/kraken/KRAudioSource.h +++ b/KREngine/kraken/KRAudioSource.h @@ -51,10 +51,41 @@ public: virtual void physicsUpdate(float deltaTime); void render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass); + + // ---- Audio Playback Controls ---- + + // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. + // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. + // If not set to looping, audio playback ends automatically at the end of the sample void play(); + + // Stop playback of audio. If audio is already stopped, this has no effect. + // If play() is called afterwards, playback will continue at the current audio sample position. void stop(); + + // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. bool isPlaying(); + // Returns the audio playback position in units of integer audio frames. + __int64_t getAudioFrame(); + + // Sets the audio playback position with units of integer audio frames. + void setAudioFrame(__int64_t next_frame); + + // Gets the audio playback position with units of floating point seconds. + float getAudioTime(); + + // Sets the audio playback position with units of floating point seconds. + void setAudioTime(float new_position); + + // Returns true if the playback will automatically loop + bool getLooping(); + + // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect + void setLooping(bool looping); + + // ---- End: Audio Playback Controls ---- + void setSample(const std::string &sound_name); std::string getSample(); @@ -66,8 +97,7 @@ public: float getPitch(); void setPitch(float pitch); - bool getLooping(); - void setLooping(bool looping); + bool getIs3D(); void setIs3D(bool is3D); @@ -94,12 +124,11 @@ public: KRAudioBuffer *getBuffer(); int getBufferFrame(); - - __int64_t getStartAudioFrame(); void sample(int frame_count, int channel, float *buffer, float gain); private: - __int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback + __int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback; when paused or not playing, this contains a value of -1 + __int64_t m_paused_audio_frame; // When paused or not playing, this contains the local audio frame number. When playing, this contains a value of -1 int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer void advanceBuffer(); From a8a8f32e77b803c4242d9f315ab0f3b4e835703f Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Mon, 18 Nov 2013 23:52:03 -0800 Subject: [PATCH 24/43] Implemented KRNode::getParent() --HG-- extra : source : 1bad435929f774f4da192fba4204fd7a85b17f01 --- KREngine/kraken/KRNode.cpp | 4 ++++ KREngine/kraken/KRNode.h | 1 + 2 files changed, 5 insertions(+) diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index 70e5ae1..aab2759 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -450,6 +450,10 @@ const std::set &KRNode::getChildren() { return m_childNodes; } +KRNode *KRNode::getParent() { + return m_parentNode; +} + const std::string &KRNode::getName() const { return m_name; } diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index 61cea10..e8d0f9d 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -58,6 +58,7 @@ public: void addChild(KRNode *child); const std::set &getChildren(); + KRNode *getParent(); void setLocalTranslation(const KRVector3 &v, bool set_original = false); void setLocalScale(const KRVector3 &v, bool set_original = false); From eee9be438d7535087f5f089c887c177eca5b44e4 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Mon, 18 Nov 2013 23:52:03 -0800 Subject: [PATCH 25/43] Implemented KRNode::getParent() --HG-- branch : nfb --- KREngine/kraken/KRNode.cpp | 4 ++++ KREngine/kraken/KRNode.h | 1 + 2 files changed, 5 insertions(+) diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index 70e5ae1..aab2759 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -450,6 +450,10 @@ const std::set &KRNode::getChildren() { return m_childNodes; } +KRNode *KRNode::getParent() { + return m_parentNode; +} + const std::string &KRNode::getName() const { return m_name; } diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index 61cea10..e8d0f9d 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -58,6 +58,7 @@ public: void addChild(KRNode *child); const std::set &getChildren(); + KRNode *getParent(); void setLocalTranslation(const KRVector3 &v, bool set_original = false); void setLocalScale(const KRVector3 &v, bool set_original = false); From 9cd9a8474cfc452aaebd8e4d112a81b9fa884cce Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 23 Nov 2013 12:16:31 -0800 Subject: [PATCH 26/43] Updated to FBX SDK 2014.2 Nodes in the FBX file starting with so_ will no longer be decorated with fbx_##_ prefixes. Updated import pipeline for compatibility with C++11 --HG-- extra : source : 39b8803b34f432b24279d4c6ca4c05f4f505174b --- KREngine/Kraken.xcodeproj/project.pbxproj | 34 ++- KREngine/kraken/KRContext.cpp | 2 +- KREngine/kraken/KRDataBlock.cpp | 4 + KREngine/kraken/KREngine-common.h | 21 +- KREngine/kraken/KRMeshStreamer.mm | 35 ++- KREngine/kraken/KRResource+fbx.cpp | 248 ++++++++++++---------- KREngine/kraken/KRTextureStreamer.mm | 40 ++++ 7 files changed, 227 insertions(+), 157 deletions(-) diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index b3554fb..e9aabca 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -76,15 +76,15 @@ E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; - E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; + E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; - E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; + E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; settings = {ATTRIBUTES = (Public, ); }; }; E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; - E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; + E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; settings = {ATTRIBUTES = (Public, ); }; }; E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; }; E44F38241683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (); }; }; E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -102,7 +102,7 @@ E459040616C30CD9002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040516C30CD9002B00A0 /* AudioUnit.framework */; }; E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */ = {isa = PBXBuildFile; fileRef = E460292516681CFE00261BB9 /* KRTextureAnimated.h */; settings = {ATTRIBUTES = (); }; }; E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E460292716681D1000261BB9 /* KRTextureAnimated.cpp */; }; - E460292B16682BF700261BB9 /* libfbxsdk-2013.3-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E460292916682BD900261BB9 /* libfbxsdk-2013.3-static.a */; }; + E460292B16682BF700261BB9 /* libfbxsdk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E460292916682BD900261BB9 /* libfbxsdk.a */; }; E460292C166834AB00261BB9 /* KRTextureAnimated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E460292716681D1000261BB9 /* KRTextureAnimated.cpp */; }; E461A152152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; settings = {ATTRIBUTES = (); }; }; E461A153152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -124,7 +124,7 @@ E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; }; E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; }; E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; }; - E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; }; + E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */; }; E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */ = {isa = PBXBuildFile; fileRef = E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; }; @@ -451,7 +451,7 @@ E459040516C30CD9002B00A0 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; E460292516681CFE00261BB9 /* KRTextureAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureAnimated.h; sourceTree = ""; }; E460292716681D1000261BB9 /* KRTextureAnimated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureAnimated.cpp; sourceTree = ""; }; - E460292916682BD900261BB9 /* libfbxsdk-2013.3-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libfbxsdk-2013.3-static.a"; path = "lib/gcc4/ub/libfbxsdk-2013.3-static.a"; sourceTree = FBXSDK; }; + E460292916682BD900261BB9 /* libfbxsdk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfbxsdk.a; path = "../../FBX SDK/2014.2/lib/ios-i386/release/libfbxsdk.a"; sourceTree = FBXSDK; }; E461A151152E54B500F2044A /* KRLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLight.h; sourceTree = ""; }; E461A155152E54F700F2044A /* KRLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRLight.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E461A157152E555400F2044A /* KRPointLight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRPointLight.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; @@ -671,7 +671,7 @@ E4BBBB9F1512A4B100F43B5B /* Cocoa.framework in Frameworks */, E497B95D151BF05F00D3DC67 /* CoreServices.framework in Frameworks */, E497B95F151BF09600D3DC67 /* SystemConfiguration.framework in Frameworks */, - E460292B16682BF700261BB9 /* libfbxsdk-2013.3-static.a in Frameworks */, + E460292B16682BF700261BB9 /* libfbxsdk.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1091,7 +1091,7 @@ E459040316C30CC5002B00A0 /* AudioUnit.framework */, E41B6BA916BE437800B510EB /* CoreAudio.framework */, 10CC33A3168530A300BB9846 /* libPVRTexLib.a */, - E460292916682BD900261BB9 /* libfbxsdk-2013.3-static.a */, + E460292916682BD900261BB9 /* libfbxsdk.a */, E4BBBB9A1512A48200F43B5B /* Foundation.framework */, E46DBE7D1512AD4900D59F86 /* OpenGL.framework */, E4F027D41697A02D00D4427D /* OpenAL.framework */, @@ -1293,7 +1293,6 @@ E497B948151BB89D00D3DC67 /* KRVector2.h in Headers */, E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */, E461A177152E5C6600F2044A /* KRMat4.h in Headers */, - E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */, E4F975461536327C00FD60B2 /* KRMeshManager.h in Headers */, E497B94B151BCEE900D3DC67 /* KRResource.h in Headers */, E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */, @@ -1309,9 +1308,7 @@ E4F9754C153632F000FD60B2 /* KRCamera.h in Headers */, E4F975501536333500FD60B2 /* KRMesh.h in Headers */, E488399F15F92BE000BD66D5 /* KRBundleManager.h in Headers */, - E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */, E4AFC6BC15F7C95D00DDB4C8 /* KRSceneManager.h in Headers */, - E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */, E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */, E4D133661537685A0070068C /* KRShader.h in Headers */, E461A153152E54B500F2044A /* KRLight.h in Headers */, @@ -1328,7 +1325,6 @@ E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */, E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */, - E43F70DF181B20E400136169 /* KRLODSet.h in Headers */, E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */, E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */, E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */, @@ -1361,8 +1357,12 @@ E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */, E499BF1D16AE74FF007FCDBE /* KRTextureAnimated.h in Headers */, E4EC73C41720B1FF0065299F /* KRVector4.h in Headers */, + E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */, + E43F70DF181B20E400136169 /* KRLODSet.h in Headers */, E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */, E45134B91746A4A300443C21 /* KRBehavior.h in Headers */, + E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */, + E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */, E48CF945173453990005EBBB /* KRFloat.h in Headers */, E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */, E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */, @@ -1847,7 +1847,6 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LIBRARY = "libstdc++"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1866,14 +1865,14 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; HEADER_SEARCH_PATHS = ( - "\"/Applications/Autodesk/FBX SDK/2013.3/include\"", + "\"/Applications/Autodesk/FBX SDK/2014.2/include\"", /usr/local/include, ); INFOPLIST_FILE = "kraken_osx/Kraken-Info.plist"; LD_DYLIB_INSTALL_NAME = "@rpath/${EXECUTABLE_PATH}"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", + "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2014.2/lib/ios-i386/release\"", "\"$(SYSTEM_APPS_DIR)/Imagination/PowerVR/GraphicsSDK/PVRTexTool/Library/OSX_x86/Static\"", ); MACOSX_DEPLOYMENT_TARGET = 10.7; @@ -1891,7 +1890,6 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LIBRARY = "libstdc++"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1910,14 +1908,14 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; HEADER_SEARCH_PATHS = ( - "\"/Applications/Autodesk/FBX SDK/2013.3/include\"", + "\"/Applications/Autodesk/FBX SDK/2014.2/include\"", /usr/local/include, ); INFOPLIST_FILE = "kraken_osx/Kraken-Info.plist"; LD_DYLIB_INSTALL_NAME = "@rpath/${EXECUTABLE_PATH}"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", + "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2014.2/lib/ios-i386/release\"", "\"$(SYSTEM_APPS_DIR)/Imagination/PowerVR/GraphicsSDK/PVRTexTool/Library/OSX_x86/Static\"", ); MACOSX_DEPLOYMENT_TARGET = 10.7; diff --git a/KREngine/kraken/KRContext.cpp b/KREngine/kraken/KRContext.cpp index fa4d2b9..a26e398 100644 --- a/KREngine/kraken/KRContext.cpp +++ b/KREngine/kraken/KRContext.cpp @@ -284,7 +284,7 @@ void KRContext::setStreamingEnabled(bool enable) void KRContext::getMemoryStats(long &free_memory) { free_memory = 0; -#if TARGET_OS_IPHONE +#if TARGET_OS_IPHONE || TARGET_OS_MAC mach_port_t host_port = mach_host_self(); mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); vm_size_t pagesize = 0; diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index 28578f8..cfc2421 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -35,6 +35,10 @@ #include +int KRAKEN_MEM_PAGE_SIZE = getpagesize(); +#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) ((x) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) +#define KRAKEN_MEM_ROUND_UP_PAGE(x) ((((x) - 1) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) + KRAKEN_MEM_PAGE_SIZE) + int m_mapCount = 0; size_t m_mapSize = 0; size_t m_mapOverhead = 0; diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 1edc1af..1b60047 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -71,10 +71,6 @@ using std::queue; #define KRAKEN_HAVE_BLAS 1 #endif -int KRAKEN_MEM_PAGE_SIZE = getpagesize(); - -#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) ((x) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) -#define KRAKEN_MEM_ROUND_UP_PAGE(x) ((((x) - 1) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) + KRAKEN_MEM_PAGE_SIZE) #define KRENGINE_MAX_TEXTURE_UNITS 8 @@ -83,23 +79,11 @@ int KRAKEN_MEM_PAGE_SIZE = getpagesize(); #endif -#if TARGET_OS_IPHONE - #include using std::unordered_map; using std::unordered_multimap; using std::hash; -#else - -#include -using std::tr1::unordered_map; -using std::tr1::unordered_multimap; -using std::tr1::hash; - -#endif - - #if TARGET_OS_IPHONE #include @@ -137,9 +121,6 @@ using std::tr1::hash; #include #endif -#endif - - #if DEBUG #define GLDEBUG(x) \ @@ -205,3 +186,5 @@ fprintf(stderr, "Error at line number %d, in file %s. Returned %d for call %s\n" #include "KRVector3.h" #include "KRVector2.h" #include "KRBehavior.h" + +#endif diff --git a/KREngine/kraken/KRMeshStreamer.mm b/KREngine/kraken/KRMeshStreamer.mm index 1940386..3067fe3 100644 --- a/KREngine/kraken/KRMeshStreamer.mm +++ b/KREngine/kraken/KRMeshStreamer.mm @@ -13,11 +13,36 @@ #include -EAGLContext *gMeshStreamerContext; +#if TARGET_OS_IPHONE + +EAGLContext *gMeshStreamerContext = nil; + +#elif TARGET_OS_MAC + +NSOpenGLContext *gMeshStreamerContext = nil; + +#else + +#error Unsupported Platform +#endif KRMeshStreamer::KRMeshStreamer(KRContext &context) : m_context(context) { + +#if TARGET_OS_IPHONE gMeshStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; +#elif TARGET_OS_MAC + NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = + { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + 0 + }; + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; + gMeshStreamerContext = [[[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: [NSOpenGLContext currentContext] ] autorelease]; +#else + #error Unsupported Platform +#endif + m_stop = false; m_thread = std::thread(&KRMeshStreamer::run, this); } @@ -35,7 +60,15 @@ void KRMeshStreamer::run() pthread_setname_np("Kraken - Mesh Streamer"); std::chrono::microseconds sleep_duration( 100 ); + +#if TARGET_OS_IPHONE [EAGLContext setCurrentContext: gMeshStreamerContext]; +#elif TARGET_OS_MAC + [gMeshStreamerContext makeCurrentContext]; +#else + #error Unsupported Platform +#endif + while(!m_stop) { diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index c5ee30d..bb82a8f 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -34,21 +34,21 @@ #define IOS_REF (*(pSdkManager->GetIOSettings())) #endif -void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene); -void DestroySdkObjects(KFbxSdkManager* pSdkManager); -bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename); +void InitializeSdkObjects(FbxManager*& pSdkManager, FbxScene*& pScene); +void DestroySdkObjects(FbxManager* pSdkManager); +bool LoadScene(FbxManager* pSdkManager, FbxDocument* pScene, const char* pFilename); KRAnimation *LoadAnimation(KRContext &context, FbxAnimStack* pAnimStack); KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurve); KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer); -void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); +void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode); //void BakeNode(KFbxNode* pNode); void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial); -void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh); -KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); -KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode); -KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); -KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); -KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode); +void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxMesh* pSourceMesh); +KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode); +KRNode *LoadLight(KRNode *parent_node, FbxNode* pNode); +KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, FbxNode* pNode); +KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, FbxNode* pNode); +KRNode *LoadCamera(KRNode *parent_node, FbxNode* pNode); std::string GetFbxObjectName(FbxObject *obj); const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be configurable @@ -57,12 +57,12 @@ const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be c std::string GetFbxObjectName(FbxObject *obj) { bool is_locator = false; - KFbxNode *node = FbxCast(obj); + FbxNode *node = FbxCast(obj); if(node) { - KFbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType()); - if(attribute_type == KFbxNodeAttribute::eNull) { - KFbxNull* pSourceNull = (KFbxNull*) node->GetNodeAttribute(); - if(pSourceNull->Look.Get() == KFbxNull::eCross ) { + FbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType()); + if(attribute_type == FbxNodeAttribute::eNull) { + FbxNull* pSourceNull = (FbxNull*) node->GetNodeAttribute(); + if(pSourceNull->Look.Get() == FbxNull::eCross ) { is_locator = true; } } @@ -74,6 +74,9 @@ std::string GetFbxObjectName(FbxObject *obj) if(is_locator) { // We do not rename locators return std::string(obj->GetName()); + } else if(strncmp(obj->GetName(), "so_", 3) == 0) { + // An so_ prefix indicates that this is a "Scriptable Object" that should not have the name decorated; + return obj->GetName(); } else if(strcmp(obj->GetName(), "default_camera") == 0) { // There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera return "default_camera"; @@ -94,8 +97,8 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) KRScene *pScene = new KRScene(context, KRResource::GetFileBase(path)); context.getSceneManager()->add(pScene); - KFbxSdkManager* lSdkManager = NULL; - KFbxScene* pFbxScene = NULL; + FbxManager* lSdkManager = NULL; + FbxScene* pFbxScene = NULL; bool lResult; FbxGeometryConverter *pGeometryConverter = NULL; @@ -108,7 +111,7 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) // Load the scene. lResult = LoadScene(lSdkManager, pFbxScene, path.c_str()); - KFbxNode* pNode = pFbxScene->GetRootNode(); + FbxNode* pNode = pFbxScene->GetRootNode(); // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- /* @@ -189,11 +192,11 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) DestroySdkObjects(lSdkManager); } -void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene) +void InitializeSdkObjects(FbxManager*& pSdkManager, FbxScene*& pScene) { // The first thing to do is to create the FBX SDK manager which is the // object allocator for almost all the classes in the SDK. - pSdkManager = KFbxSdkManager::Create(); + pSdkManager = FbxManager::Create(); if (!pSdkManager) { @@ -202,25 +205,27 @@ void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene) } // create an IOSettings object - KFbxIOSettings * ios = KFbxIOSettings::Create(pSdkManager, IOSROOT ); + FbxIOSettings * ios = FbxIOSettings::Create(pSdkManager, IOSROOT ); pSdkManager->SetIOSettings(ios); // Load plugins from the executable directory - KString lPath = FbxGetApplicationDirectory(); -#if defined(KARCH_ENV_WIN) - KString lExtension = "dll"; -#elif defined(KARCH_ENV_MACOSX) - KString lExtension = "dylib"; -#elif defined(KARCH_ENV_LINUX) - KString lExtension = "so"; + FbxString lPath = FbxGetApplicationDirectory(); +#if TARGET_OS_WIN32 + FbxString lExtension = "dll"; +#elif TARGET_OS_MAC + FbxString lExtension = "dylib"; +#elif TARGET_OS_UNIX + FbxString lExtension = "so"; +#elif + #error Unsupported Platform #endif pSdkManager->LoadPluginsDirectory(lPath.Buffer(), lExtension.Buffer()); // Create the entity that will hold the scene. - pScene = KFbxScene::Create(pSdkManager,""); + pScene = FbxScene::Create(pSdkManager,""); } -void DestroySdkObjects(KFbxSdkManager* pSdkManager) +void DestroySdkObjects(FbxManager* pSdkManager) { // Delete the FBX SDK manager. All the objects that have been allocated // using the FBX SDK manager and that haven't been explicitly destroyed @@ -230,7 +235,7 @@ void DestroySdkObjects(KFbxSdkManager* pSdkManager) } -bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename) +bool LoadScene(FbxManager* pSdkManager, FbxDocument* pScene, const char* pFilename) { int lFileMajor, lFileMinor, lFileRevision; int lSDKMajor, lSDKMinor, lSDKRevision; @@ -240,10 +245,10 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF char lPassword[1024]; // Get the file version number generate by the FBX SDK. - KFbxSdkManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision); + FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision); // Create an importer. - KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager,""); + FbxImporter* lImporter = FbxImporter::Create(pSdkManager,""); // Initialize the importer by providing a filename. const bool lImportStatus = lImporter->Initialize(pFilename, -1, pSdkManager->GetIOSettings()); @@ -251,11 +256,14 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF if( !lImportStatus ) { - printf("Call to KFbxImporter::Initialize() failed.\n"); - printf("Error returned: %s\n\n", lImporter->GetLastErrorString()); + FbxStatus &status = lImporter->GetStatus(); - if (lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedYet || - lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedAnymore) + printf("Call to KFbxImporter::Initialize() failed.\n"); + printf("Error returned: %s\n\n", status.GetErrorString()); + + + + if (status.GetCode() == FbxStatus::EStatusCode::eInvalidFileVersion) { printf("FBX version number for this FBX SDK is %d.%d.%d\n", lSDKMajor, lSDKMinor, lSDKRevision); printf("FBX version number for file %s is %d.%d.%d\n\n", pFilename, lFileMajor, lFileMinor, lFileRevision); @@ -299,21 +307,21 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF // Import the scene. lStatus = lImporter->Import(pScene); - if(lStatus == false && lImporter->GetLastErrorID() == FbxIOBase::ePasswordError) + if(lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) { printf("Please enter password: "); lPassword[0] = '\0'; scanf("%s", lPassword); - KString lString(lPassword); + FbxString lString(lPassword); IOS_REF.SetStringProp(IMP_FBX_PASSWORD, lString); IOS_REF.SetBoolProp(IMP_FBX_PASSWORD_ENABLE, true); lStatus = lImporter->Import(pScene); - if(lStatus == false && lImporter->GetLastErrorID() == FbxIOBase::ePasswordError) + if(lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) { printf("\nPassword is wrong, import aborted.\n"); } @@ -561,8 +569,8 @@ KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLaye // } //} -void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { - KFbxVector4 lTmpVector; +void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode) { + FbxVector4 lTmpVector; pNode->UpdatePropertiesFromPivotsAndLimits(); @@ -832,26 +840,26 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p } } - fbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSourcePivot); - fbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); - fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSourcePivot); + FbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSourcePivot); + FbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); + FbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSourcePivot); bool rotation_active = pNode->RotationActive.Get(); - fbxDouble3 post_rotation = pNode->PostRotation.Get(); - fbxDouble3 pre_rotation = pNode->PreRotation.Get(); - fbxDouble3 rotation_offset = pNode->RotationOffset.Get(); - fbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); - fbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); - fbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); - fbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); - fbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); - fbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); - ERotationOrder rotation_order = pNode->RotationOrder.Get(); + FbxDouble3 post_rotation = pNode->PostRotation.Get(); + FbxDouble3 pre_rotation = pNode->PreRotation.Get(); + FbxDouble3 rotation_offset = pNode->RotationOffset.Get(); + FbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); + FbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); + FbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); + FbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); + FbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); + FbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); + EFbxRotationOrder rotation_order = pNode->RotationOrder.Get(); - KFbxVector4 lZero(0.0, 0.0, 0.0); - KFbxVector4 lOne(1.0, 1.0, 1.0); + FbxVector4 lZero(0.0, 0.0, 0.0); + FbxVector4 lOne(1.0, 1.0, 1.0); assert(geometric_rotation == lZero); assert(geometric_translation == lZero); @@ -879,8 +887,8 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p // printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]); // printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); - KFbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType()); - if(attribute_type == KFbxNodeAttribute::eLODGroup) { + FbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType()); + if(attribute_type == FbxNodeAttribute::eLODGroup) { std::string name = GetFbxObjectName(pNode); FbxLODGroup *fbx_lod_group = (FbxLODGroup*) pNode->GetNodeAttribute(); // FbxCast(pNode); bool use_world_space_units = fbx_lod_group->WorldSpace.Get(); @@ -964,25 +972,25 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p } else { KRNode *new_node = NULL; switch(attribute_type) { - case KFbxNodeAttribute::eMesh: + case FbxNodeAttribute::eMesh: new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode); break; - case KFbxNodeAttribute::eLight: + case FbxNodeAttribute::eLight: new_node = LoadLight(parent_node, pNode); break; - case KFbxNodeAttribute::eSkeleton: + case FbxNodeAttribute::eSkeleton: new_node = LoadSkeleton(parent_node, pFbxScene, pNode); break; - case KFbxNodeAttribute::eCamera: + case FbxNodeAttribute::eCamera: new_node = LoadCamera(parent_node, pNode); break; default: { bool is_locator = false; - if(attribute_type == KFbxNodeAttribute::eNull) { - KFbxNull* pSourceNull = (KFbxNull*) pNode->GetNodeAttribute(); - if(pSourceNull->Look.Get() == KFbxNull::eCross ) { + if(attribute_type == FbxNodeAttribute::eNull) { + FbxNull* pSourceNull = (FbxNull*) pNode->GetNodeAttribute(); + if(pSourceNull->Look.Get() == FbxNull::eCross ) { is_locator = true; } } @@ -1059,7 +1067,7 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { FbxPropertyT lKFbxDouble3; FbxPropertyT lKFbxDouble1; - if (pMaterial->GetClassId().Is(KFbxSurfacePhong::ClassId)) { + if (pMaterial->GetClassId().Is(FbxSurfacePhong::ClassId)) { // We found a Phong material. // Ambient Color @@ -1067,11 +1075,11 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Diffuse Color - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Diffuse; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Diffuse; new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Specular Color (unique to Phong materials) - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Specular; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Specular; new_material->setSpecular(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Emissive Color @@ -1084,7 +1092,7 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { */ // Shininess - lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->Shininess; + lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->Shininess; new_material->setShininess(lKFbxDouble1.Get()); /* @@ -1094,27 +1102,27 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { */ // Transparency Color - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->TransparentColor; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->TransparentColor; new_material->setTransparency( 1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); // Reflection factor - lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->ReflectionFactor; + lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->ReflectionFactor; // Reflection color - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Reflection; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection; // We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken new_material->setReflection(KRVector3(lKFbxDouble3.Get()[0] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[1] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[2] * lKFbxDouble1.Get())); - } else if(pMaterial->GetClassId().Is(KFbxSurfaceLambert::ClassId) ) { + } else if(pMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId) ) { // We found a Lambert material. // Ambient Color - lKFbxDouble3=((KFbxSurfaceLambert *)pMaterial)->Ambient; + lKFbxDouble3=((FbxSurfaceLambert *)pMaterial)->Ambient; new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Diffuse Color - lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Diffuse; + lKFbxDouble3 =((FbxSurfaceLambert *)pMaterial)->Diffuse; new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Emissive @@ -1126,7 +1134,7 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { */ // Transparency Color - lKFbxDouble3 =((KFbxSurfaceLambert *) pMaterial)->TransparentColor; + lKFbxDouble3 =((FbxSurfaceLambert *) pMaterial)->TransparentColor; new_material->setTransparency(1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); } else { @@ -1135,31 +1143,31 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { - KFbxProperty pProperty; + FbxProperty pProperty; // Diffuse Map Texture - pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse); - if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) { + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse); + if(pProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId) > 0) { printf("Warning! Layered textures not supported.\n"); } - int texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId); + int texture_count = pProperty.GetSrcObjectCount(FbxTexture::ClassId); if(texture_count > 1) { printf("Error! Multiple diffuse textures not supported.\n"); } else if(texture_count == 1) { - KFbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(KFbxTexture::ClassId,0)); + FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxTexture::ClassId,0)); assert(!pTexture->GetSwapUV()); assert(pTexture->GetCroppingTop() == 0); assert(pTexture->GetCroppingLeft() == 0); assert(pTexture->GetCroppingRight() == 0); assert(pTexture->GetCroppingBottom() == 0); - assert(pTexture->GetWrapModeU() == KFbxTexture::eRepeat); - assert(pTexture->GetWrapModeV() == KFbxTexture::eRepeat); + assert(pTexture->GetWrapModeU() == FbxTexture::eRepeat); + assert(pTexture->GetWrapModeV() == FbxTexture::eRepeat); assert(pTexture->GetRotationU() == 0.0f); assert(pTexture->GetRotationV() == 0.0f); assert(pTexture->GetRotationW() == 0.0f); - KFbxFileTexture *pFileTexture = FbxCast(pTexture); + FbxFileTexture *pFileTexture = FbxCast(pTexture); if(pFileTexture) { new_material->setDiffuseMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } @@ -1167,24 +1175,24 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { // Specular Map Texture - pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sSpecular); - if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) { + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecular); + if(pProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId) > 0) { printf("Warning! Layered textures not supported.\n"); } - texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId); + texture_count = pProperty.GetSrcObjectCount(FbxTexture::ClassId); if(texture_count > 1) { printf("Error! Multiple specular textures not supported.\n"); } else if(texture_count == 1) { - KFbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(KFbxTexture::ClassId,0)); - KFbxFileTexture *pFileTexture = FbxCast(pTexture); + FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxTexture::ClassId,0)); + FbxFileTexture *pFileTexture = FbxCast(pTexture); if(pFileTexture) { new_material->setSpecularMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } } // Normal Map Texture - pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sNormalMap); - if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) { + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap); + if(pProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId) > 0) { printf("Warning! Layered textures not supported.\n"); } @@ -1193,8 +1201,8 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { if(texture_count > 1) { printf("Error! Multiple normal map textures not supported.\n"); } else if(texture_count == 1) { - KFbxTexture* pTexture = pProperty.GetSrcObject(0); - KFbxFileTexture *pFileTexture = FbxCast(pTexture); + FbxTexture* pTexture = pProperty.GetSrcObject(0); + FbxFileTexture *pFileTexture = FbxCast(pTexture); if(pFileTexture) { new_material->setNormalMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } @@ -1211,8 +1219,8 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { -void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) { - KFbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh); +void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxMesh* pSourceMesh) { + FbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh); KRMesh::mesh_info mi; mi.format = KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES; @@ -1223,7 +1231,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG } control_point_weight_info_t; int control_point_count = pMesh->GetControlPointsCount(); - KFbxVector4* control_points = pMesh->GetControlPoints(); + FbxVector4* control_points = pMesh->GetControlPoints(); control_point_weight_info_t *control_point_weights = new control_point_weight_info_t[control_point_count]; for(int control_point=0; control_point < control_point_count; control_point++) { @@ -1346,7 +1354,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG bool need_tangents = false; for(int iMaterial=0; iMaterial < material_count; iMaterial++) { - KFbxSurfaceMaterial *pMaterial = pSourceMesh->GetNode()->GetMaterial(iMaterial); + FbxSurfaceMaterial *pMaterial = pSourceMesh->GetNode()->GetMaterial(iMaterial); KRMaterial *material = context.getMaterialManager()->getMaterial(pMaterial->GetName()); if(material) { @@ -1384,7 +1392,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG for(int iVertex=0; iVertex<3; iVertex++) { // ----====---- Read Vertex Position ----====---- int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex); - KFbxVector4 v = control_points[lControlPointIndex]; + FbxVector4 v = control_points[lControlPointIndex]; mi.vertices.push_back(KRVector3(v[0], v[1], v[2])); if(mi.bone_names.size() > 0) { @@ -1405,12 +1413,14 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG // ----====---- Read UVs ----====---- - KStringList uvNames; + FbxStringList uvNames; pMesh->GetUVSetNames(uvNames); if(uv_count >= 1) { const char *setName = uvNames[0].Buffer(); - KFbxVector2 uv; - if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { + FbxVector2 uv; + bool unmapped = false; + if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { + assert(!unmapped); new_uva = KRVector2(uv[0], uv[1]); } mi.uva.push_back(new_uva); @@ -1418,8 +1428,10 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG if(uv_count >= 2) { const char *setName = uvNames[1].Buffer(); - KFbxVector2 uv; - if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { + FbxVector2 uv; + bool unmapped = false; + if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { + assert(!unmapped); new_uvb = KRVector2(uv[0], uv[1]); } mi.uvb.push_back(new_uvb); @@ -1427,7 +1439,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG // ----====---- Read Normals ----====---- - KFbxVector4 new_normal; + FbxVector4 new_normal; if(pMesh->GetPolygonVertexNormal(iPolygon, iVertex, new_normal)) { mi.normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2])); } @@ -1436,7 +1448,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG // ----====---- Read Tangents ----====---- for(int l = 0; l < tangent_count; ++l) { - KFbxVector4 new_tangent; + FbxVector4 new_tangent; FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l); if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) { @@ -1488,10 +1500,10 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG context.getModelManager()->addModel(new_mesh); } -KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { +KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); - KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute(); + FbxMesh* pSourceMesh = (FbxMesh*) pNode->GetNodeAttribute(); if(KRMesh::GetLODCoverage(pNode->GetName()) == 100) { // If this is the full detail model, add an instance of it to the scene file @@ -1516,7 +1528,7 @@ KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter } -KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { +KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); KRBone *new_bone = new KRBone(parent_node->getScene(), name.c_str()); @@ -1530,7 +1542,7 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) return new_bone; } -KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { +KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str()); @@ -1545,7 +1557,7 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { return new_locator; } -KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) { +KRNode *LoadCamera(KRNode *parent_node, FbxNode* pNode) { FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute(); const char *szName = pNode->GetName(); @@ -1553,7 +1565,7 @@ KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) { return new_camera; } -KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { +KRNode *LoadLight(KRNode *parent_node, FbxNode* pNode) { const GLfloat PI = 3.14159265; const GLfloat d2r = PI * 2 / 360; @@ -1564,7 +1576,7 @@ KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { FbxDouble light_intensity = pLight->Intensity.Get(); FbxDouble light_hotspot = pLight->InnerAngle.Get(); // light inner cone angle (in degrees). Also know as the HotSpot FbxDouble light_coneangle = pLight->OuterAngle.Get(); // light outer cone angle (in degrees). Also known as the Falloff - KFbxLight::EDecayType light_decaytype = pLight->DecayType.Get(); // decay type + FbxLight::EDecayType light_decaytype = pLight->DecayType.Get(); // decay type FbxDouble light_decaystart = pLight->DecayStart.Get(); // decay start distance @@ -1576,20 +1588,20 @@ KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { KRLight *new_light = NULL; switch(pLight->LightType.Get()) { - case KFbxLight::ePoint: + case FbxLight::ePoint: { KRPointLight *l = new KRPointLight(parent_node->getScene(), szName); new_light = l; } break; - case KFbxLight::eDirectional: + case FbxLight::eDirectional: { KRDirectionalLight *l = new KRDirectionalLight(parent_node->getScene(), szName); new_light = l; } break; - case KFbxLight::eSpot: + case FbxLight::eSpot: { KRSpotLight *l = new KRSpotLight(parent_node->getScene(), szName); l->setInnerAngle(light_hotspot * d2r); @@ -1597,8 +1609,8 @@ KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { new_light = l; } break; - case KFbxLight::eVolume: - case KFbxLight::eArea: + case FbxLight::eVolume: + case FbxLight::eArea: // Not supported yet break; } diff --git a/KREngine/kraken/KRTextureStreamer.mm b/KREngine/kraken/KRTextureStreamer.mm index 5dc8682..46043cc 100644 --- a/KREngine/kraken/KRTextureStreamer.mm +++ b/KREngine/kraken/KRTextureStreamer.mm @@ -13,8 +13,21 @@ #include + +#if TARGET_OS_IPHONE + EAGLContext *gTextureStreamerContext = nil; +#elif TARGET_OS_MAC + +NSOpenGLContext *gTextureStreamerContext = nil; + +#else + +#error Unsupported Platform +#endif + + KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context) { m_running = false; @@ -25,7 +38,27 @@ void KRTextureStreamer::startStreamer() { if(!m_running) { m_running = true; + +#if TARGET_OS_IPHONE + gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; + + +#elif TARGET_OS_MAC + + NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = + { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + 0 + }; + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; + gTextureStreamerContext = [[[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: [NSOpenGLContext currentContext] ] autorelease]; + +#else + + #error Unsupported Platform +#endif + m_thread = std::thread(&KRTextureStreamer::run, this); } } @@ -43,7 +76,14 @@ void KRTextureStreamer::run() pthread_setname_np("Kraken - Texture Streamer"); std::chrono::microseconds sleep_duration( 100 ); + +#if TARGET_OS_IPHONE [EAGLContext setCurrentContext: gTextureStreamerContext]; +#elif TARGET_OS_MAC + [gTextureStreamerContext makeCurrentContext]; +#else +#error Unsupported Platform +#endif while(!m_stop) { From cc5c698b1389c80db09bb639de562ee59351a414 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 23 Nov 2013 12:16:31 -0800 Subject: [PATCH 27/43] Updated to FBX SDK 2014.2 Nodes in the FBX file starting with so_ will no longer be decorated with fbx_##_ prefixes. Updated import pipeline for compatibility with C++11 --HG-- branch : nfb --- KREngine/Kraken.xcodeproj/project.pbxproj | 34 ++- KREngine/kraken/KRContext.cpp | 2 +- KREngine/kraken/KRDataBlock.cpp | 4 + KREngine/kraken/KREngine-common.h | 21 +- KREngine/kraken/KRMeshStreamer.mm | 35 ++- KREngine/kraken/KRResource+fbx.cpp | 248 ++++++++++++---------- KREngine/kraken/KRTextureStreamer.mm | 40 ++++ 7 files changed, 227 insertions(+), 157 deletions(-) diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index b3554fb..e9aabca 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -76,15 +76,15 @@ E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; - E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; + E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; - E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; + E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; settings = {ATTRIBUTES = (Public, ); }; }; E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; - E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; + E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; settings = {ATTRIBUTES = (Public, ); }; }; E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; }; E44F38241683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (); }; }; E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -102,7 +102,7 @@ E459040616C30CD9002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040516C30CD9002B00A0 /* AudioUnit.framework */; }; E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */ = {isa = PBXBuildFile; fileRef = E460292516681CFE00261BB9 /* KRTextureAnimated.h */; settings = {ATTRIBUTES = (); }; }; E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E460292716681D1000261BB9 /* KRTextureAnimated.cpp */; }; - E460292B16682BF700261BB9 /* libfbxsdk-2013.3-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E460292916682BD900261BB9 /* libfbxsdk-2013.3-static.a */; }; + E460292B16682BF700261BB9 /* libfbxsdk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E460292916682BD900261BB9 /* libfbxsdk.a */; }; E460292C166834AB00261BB9 /* KRTextureAnimated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E460292716681D1000261BB9 /* KRTextureAnimated.cpp */; }; E461A152152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; settings = {ATTRIBUTES = (); }; }; E461A153152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -124,7 +124,7 @@ E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; }; E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; }; E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; }; - E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; }; + E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */; }; E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */ = {isa = PBXBuildFile; fileRef = E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; }; @@ -451,7 +451,7 @@ E459040516C30CD9002B00A0 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; E460292516681CFE00261BB9 /* KRTextureAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureAnimated.h; sourceTree = ""; }; E460292716681D1000261BB9 /* KRTextureAnimated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureAnimated.cpp; sourceTree = ""; }; - E460292916682BD900261BB9 /* libfbxsdk-2013.3-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libfbxsdk-2013.3-static.a"; path = "lib/gcc4/ub/libfbxsdk-2013.3-static.a"; sourceTree = FBXSDK; }; + E460292916682BD900261BB9 /* libfbxsdk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfbxsdk.a; path = "../../FBX SDK/2014.2/lib/ios-i386/release/libfbxsdk.a"; sourceTree = FBXSDK; }; E461A151152E54B500F2044A /* KRLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLight.h; sourceTree = ""; }; E461A155152E54F700F2044A /* KRLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRLight.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E461A157152E555400F2044A /* KRPointLight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRPointLight.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; @@ -671,7 +671,7 @@ E4BBBB9F1512A4B100F43B5B /* Cocoa.framework in Frameworks */, E497B95D151BF05F00D3DC67 /* CoreServices.framework in Frameworks */, E497B95F151BF09600D3DC67 /* SystemConfiguration.framework in Frameworks */, - E460292B16682BF700261BB9 /* libfbxsdk-2013.3-static.a in Frameworks */, + E460292B16682BF700261BB9 /* libfbxsdk.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1091,7 +1091,7 @@ E459040316C30CC5002B00A0 /* AudioUnit.framework */, E41B6BA916BE437800B510EB /* CoreAudio.framework */, 10CC33A3168530A300BB9846 /* libPVRTexLib.a */, - E460292916682BD900261BB9 /* libfbxsdk-2013.3-static.a */, + E460292916682BD900261BB9 /* libfbxsdk.a */, E4BBBB9A1512A48200F43B5B /* Foundation.framework */, E46DBE7D1512AD4900D59F86 /* OpenGL.framework */, E4F027D41697A02D00D4427D /* OpenAL.framework */, @@ -1293,7 +1293,6 @@ E497B948151BB89D00D3DC67 /* KRVector2.h in Headers */, E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */, E461A177152E5C6600F2044A /* KRMat4.h in Headers */, - E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */, E4F975461536327C00FD60B2 /* KRMeshManager.h in Headers */, E497B94B151BCEE900D3DC67 /* KRResource.h in Headers */, E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */, @@ -1309,9 +1308,7 @@ E4F9754C153632F000FD60B2 /* KRCamera.h in Headers */, E4F975501536333500FD60B2 /* KRMesh.h in Headers */, E488399F15F92BE000BD66D5 /* KRBundleManager.h in Headers */, - E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */, E4AFC6BC15F7C95D00DDB4C8 /* KRSceneManager.h in Headers */, - E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */, E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */, E4D133661537685A0070068C /* KRShader.h in Headers */, E461A153152E54B500F2044A /* KRLight.h in Headers */, @@ -1328,7 +1325,6 @@ E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */, E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */, - E43F70DF181B20E400136169 /* KRLODSet.h in Headers */, E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */, E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */, E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */, @@ -1361,8 +1357,12 @@ E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */, E499BF1D16AE74FF007FCDBE /* KRTextureAnimated.h in Headers */, E4EC73C41720B1FF0065299F /* KRVector4.h in Headers */, + E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */, + E43F70DF181B20E400136169 /* KRLODSet.h in Headers */, E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */, E45134B91746A4A300443C21 /* KRBehavior.h in Headers */, + E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */, + E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */, E48CF945173453990005EBBB /* KRFloat.h in Headers */, E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */, E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */, @@ -1847,7 +1847,6 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LIBRARY = "libstdc++"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1866,14 +1865,14 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; HEADER_SEARCH_PATHS = ( - "\"/Applications/Autodesk/FBX SDK/2013.3/include\"", + "\"/Applications/Autodesk/FBX SDK/2014.2/include\"", /usr/local/include, ); INFOPLIST_FILE = "kraken_osx/Kraken-Info.plist"; LD_DYLIB_INSTALL_NAME = "@rpath/${EXECUTABLE_PATH}"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", + "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2014.2/lib/ios-i386/release\"", "\"$(SYSTEM_APPS_DIR)/Imagination/PowerVR/GraphicsSDK/PVRTexTool/Library/OSX_x86/Static\"", ); MACOSX_DEPLOYMENT_TARGET = 10.7; @@ -1891,7 +1890,6 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LIBRARY = "libstdc++"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1910,14 +1908,14 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; HEADER_SEARCH_PATHS = ( - "\"/Applications/Autodesk/FBX SDK/2013.3/include\"", + "\"/Applications/Autodesk/FBX SDK/2014.2/include\"", /usr/local/include, ); INFOPLIST_FILE = "kraken_osx/Kraken-Info.plist"; LD_DYLIB_INSTALL_NAME = "@rpath/${EXECUTABLE_PATH}"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", + "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2014.2/lib/ios-i386/release\"", "\"$(SYSTEM_APPS_DIR)/Imagination/PowerVR/GraphicsSDK/PVRTexTool/Library/OSX_x86/Static\"", ); MACOSX_DEPLOYMENT_TARGET = 10.7; diff --git a/KREngine/kraken/KRContext.cpp b/KREngine/kraken/KRContext.cpp index fa4d2b9..a26e398 100644 --- a/KREngine/kraken/KRContext.cpp +++ b/KREngine/kraken/KRContext.cpp @@ -284,7 +284,7 @@ void KRContext::setStreamingEnabled(bool enable) void KRContext::getMemoryStats(long &free_memory) { free_memory = 0; -#if TARGET_OS_IPHONE +#if TARGET_OS_IPHONE || TARGET_OS_MAC mach_port_t host_port = mach_host_self(); mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); vm_size_t pagesize = 0; diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index 28578f8..cfc2421 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -35,6 +35,10 @@ #include +int KRAKEN_MEM_PAGE_SIZE = getpagesize(); +#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) ((x) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) +#define KRAKEN_MEM_ROUND_UP_PAGE(x) ((((x) - 1) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) + KRAKEN_MEM_PAGE_SIZE) + int m_mapCount = 0; size_t m_mapSize = 0; size_t m_mapOverhead = 0; diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 1edc1af..1b60047 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -71,10 +71,6 @@ using std::queue; #define KRAKEN_HAVE_BLAS 1 #endif -int KRAKEN_MEM_PAGE_SIZE = getpagesize(); - -#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) ((x) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) -#define KRAKEN_MEM_ROUND_UP_PAGE(x) ((((x) - 1) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) + KRAKEN_MEM_PAGE_SIZE) #define KRENGINE_MAX_TEXTURE_UNITS 8 @@ -83,23 +79,11 @@ int KRAKEN_MEM_PAGE_SIZE = getpagesize(); #endif -#if TARGET_OS_IPHONE - #include using std::unordered_map; using std::unordered_multimap; using std::hash; -#else - -#include -using std::tr1::unordered_map; -using std::tr1::unordered_multimap; -using std::tr1::hash; - -#endif - - #if TARGET_OS_IPHONE #include @@ -137,9 +121,6 @@ using std::tr1::hash; #include #endif -#endif - - #if DEBUG #define GLDEBUG(x) \ @@ -205,3 +186,5 @@ fprintf(stderr, "Error at line number %d, in file %s. Returned %d for call %s\n" #include "KRVector3.h" #include "KRVector2.h" #include "KRBehavior.h" + +#endif diff --git a/KREngine/kraken/KRMeshStreamer.mm b/KREngine/kraken/KRMeshStreamer.mm index 1940386..3067fe3 100644 --- a/KREngine/kraken/KRMeshStreamer.mm +++ b/KREngine/kraken/KRMeshStreamer.mm @@ -13,11 +13,36 @@ #include -EAGLContext *gMeshStreamerContext; +#if TARGET_OS_IPHONE + +EAGLContext *gMeshStreamerContext = nil; + +#elif TARGET_OS_MAC + +NSOpenGLContext *gMeshStreamerContext = nil; + +#else + +#error Unsupported Platform +#endif KRMeshStreamer::KRMeshStreamer(KRContext &context) : m_context(context) { + +#if TARGET_OS_IPHONE gMeshStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; +#elif TARGET_OS_MAC + NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = + { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + 0 + }; + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; + gMeshStreamerContext = [[[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: [NSOpenGLContext currentContext] ] autorelease]; +#else + #error Unsupported Platform +#endif + m_stop = false; m_thread = std::thread(&KRMeshStreamer::run, this); } @@ -35,7 +60,15 @@ void KRMeshStreamer::run() pthread_setname_np("Kraken - Mesh Streamer"); std::chrono::microseconds sleep_duration( 100 ); + +#if TARGET_OS_IPHONE [EAGLContext setCurrentContext: gMeshStreamerContext]; +#elif TARGET_OS_MAC + [gMeshStreamerContext makeCurrentContext]; +#else + #error Unsupported Platform +#endif + while(!m_stop) { diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index c5ee30d..bb82a8f 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -34,21 +34,21 @@ #define IOS_REF (*(pSdkManager->GetIOSettings())) #endif -void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene); -void DestroySdkObjects(KFbxSdkManager* pSdkManager); -bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename); +void InitializeSdkObjects(FbxManager*& pSdkManager, FbxScene*& pScene); +void DestroySdkObjects(FbxManager* pSdkManager); +bool LoadScene(FbxManager* pSdkManager, FbxDocument* pScene, const char* pFilename); KRAnimation *LoadAnimation(KRContext &context, FbxAnimStack* pAnimStack); KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurve); KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer); -void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); +void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode); //void BakeNode(KFbxNode* pNode); void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial); -void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh); -KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); -KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode); -KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); -KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); -KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode); +void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxMesh* pSourceMesh); +KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode); +KRNode *LoadLight(KRNode *parent_node, FbxNode* pNode); +KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, FbxNode* pNode); +KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, FbxNode* pNode); +KRNode *LoadCamera(KRNode *parent_node, FbxNode* pNode); std::string GetFbxObjectName(FbxObject *obj); const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be configurable @@ -57,12 +57,12 @@ const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be c std::string GetFbxObjectName(FbxObject *obj) { bool is_locator = false; - KFbxNode *node = FbxCast(obj); + FbxNode *node = FbxCast(obj); if(node) { - KFbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType()); - if(attribute_type == KFbxNodeAttribute::eNull) { - KFbxNull* pSourceNull = (KFbxNull*) node->GetNodeAttribute(); - if(pSourceNull->Look.Get() == KFbxNull::eCross ) { + FbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType()); + if(attribute_type == FbxNodeAttribute::eNull) { + FbxNull* pSourceNull = (FbxNull*) node->GetNodeAttribute(); + if(pSourceNull->Look.Get() == FbxNull::eCross ) { is_locator = true; } } @@ -74,6 +74,9 @@ std::string GetFbxObjectName(FbxObject *obj) if(is_locator) { // We do not rename locators return std::string(obj->GetName()); + } else if(strncmp(obj->GetName(), "so_", 3) == 0) { + // An so_ prefix indicates that this is a "Scriptable Object" that should not have the name decorated; + return obj->GetName(); } else if(strcmp(obj->GetName(), "default_camera") == 0) { // There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera return "default_camera"; @@ -94,8 +97,8 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) KRScene *pScene = new KRScene(context, KRResource::GetFileBase(path)); context.getSceneManager()->add(pScene); - KFbxSdkManager* lSdkManager = NULL; - KFbxScene* pFbxScene = NULL; + FbxManager* lSdkManager = NULL; + FbxScene* pFbxScene = NULL; bool lResult; FbxGeometryConverter *pGeometryConverter = NULL; @@ -108,7 +111,7 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) // Load the scene. lResult = LoadScene(lSdkManager, pFbxScene, path.c_str()); - KFbxNode* pNode = pFbxScene->GetRootNode(); + FbxNode* pNode = pFbxScene->GetRootNode(); // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- /* @@ -189,11 +192,11 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) DestroySdkObjects(lSdkManager); } -void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene) +void InitializeSdkObjects(FbxManager*& pSdkManager, FbxScene*& pScene) { // The first thing to do is to create the FBX SDK manager which is the // object allocator for almost all the classes in the SDK. - pSdkManager = KFbxSdkManager::Create(); + pSdkManager = FbxManager::Create(); if (!pSdkManager) { @@ -202,25 +205,27 @@ void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene) } // create an IOSettings object - KFbxIOSettings * ios = KFbxIOSettings::Create(pSdkManager, IOSROOT ); + FbxIOSettings * ios = FbxIOSettings::Create(pSdkManager, IOSROOT ); pSdkManager->SetIOSettings(ios); // Load plugins from the executable directory - KString lPath = FbxGetApplicationDirectory(); -#if defined(KARCH_ENV_WIN) - KString lExtension = "dll"; -#elif defined(KARCH_ENV_MACOSX) - KString lExtension = "dylib"; -#elif defined(KARCH_ENV_LINUX) - KString lExtension = "so"; + FbxString lPath = FbxGetApplicationDirectory(); +#if TARGET_OS_WIN32 + FbxString lExtension = "dll"; +#elif TARGET_OS_MAC + FbxString lExtension = "dylib"; +#elif TARGET_OS_UNIX + FbxString lExtension = "so"; +#elif + #error Unsupported Platform #endif pSdkManager->LoadPluginsDirectory(lPath.Buffer(), lExtension.Buffer()); // Create the entity that will hold the scene. - pScene = KFbxScene::Create(pSdkManager,""); + pScene = FbxScene::Create(pSdkManager,""); } -void DestroySdkObjects(KFbxSdkManager* pSdkManager) +void DestroySdkObjects(FbxManager* pSdkManager) { // Delete the FBX SDK manager. All the objects that have been allocated // using the FBX SDK manager and that haven't been explicitly destroyed @@ -230,7 +235,7 @@ void DestroySdkObjects(KFbxSdkManager* pSdkManager) } -bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename) +bool LoadScene(FbxManager* pSdkManager, FbxDocument* pScene, const char* pFilename) { int lFileMajor, lFileMinor, lFileRevision; int lSDKMajor, lSDKMinor, lSDKRevision; @@ -240,10 +245,10 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF char lPassword[1024]; // Get the file version number generate by the FBX SDK. - KFbxSdkManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision); + FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision); // Create an importer. - KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager,""); + FbxImporter* lImporter = FbxImporter::Create(pSdkManager,""); // Initialize the importer by providing a filename. const bool lImportStatus = lImporter->Initialize(pFilename, -1, pSdkManager->GetIOSettings()); @@ -251,11 +256,14 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF if( !lImportStatus ) { - printf("Call to KFbxImporter::Initialize() failed.\n"); - printf("Error returned: %s\n\n", lImporter->GetLastErrorString()); + FbxStatus &status = lImporter->GetStatus(); - if (lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedYet || - lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedAnymore) + printf("Call to KFbxImporter::Initialize() failed.\n"); + printf("Error returned: %s\n\n", status.GetErrorString()); + + + + if (status.GetCode() == FbxStatus::EStatusCode::eInvalidFileVersion) { printf("FBX version number for this FBX SDK is %d.%d.%d\n", lSDKMajor, lSDKMinor, lSDKRevision); printf("FBX version number for file %s is %d.%d.%d\n\n", pFilename, lFileMajor, lFileMinor, lFileRevision); @@ -299,21 +307,21 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF // Import the scene. lStatus = lImporter->Import(pScene); - if(lStatus == false && lImporter->GetLastErrorID() == FbxIOBase::ePasswordError) + if(lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) { printf("Please enter password: "); lPassword[0] = '\0'; scanf("%s", lPassword); - KString lString(lPassword); + FbxString lString(lPassword); IOS_REF.SetStringProp(IMP_FBX_PASSWORD, lString); IOS_REF.SetBoolProp(IMP_FBX_PASSWORD_ENABLE, true); lStatus = lImporter->Import(pScene); - if(lStatus == false && lImporter->GetLastErrorID() == FbxIOBase::ePasswordError) + if(lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) { printf("\nPassword is wrong, import aborted.\n"); } @@ -561,8 +569,8 @@ KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLaye // } //} -void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { - KFbxVector4 lTmpVector; +void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode) { + FbxVector4 lTmpVector; pNode->UpdatePropertiesFromPivotsAndLimits(); @@ -832,26 +840,26 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p } } - fbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSourcePivot); - fbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); - fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSourcePivot); + FbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSourcePivot); + FbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); + FbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSourcePivot); bool rotation_active = pNode->RotationActive.Get(); - fbxDouble3 post_rotation = pNode->PostRotation.Get(); - fbxDouble3 pre_rotation = pNode->PreRotation.Get(); - fbxDouble3 rotation_offset = pNode->RotationOffset.Get(); - fbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); - fbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); - fbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); - fbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); - fbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); - fbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); - ERotationOrder rotation_order = pNode->RotationOrder.Get(); + FbxDouble3 post_rotation = pNode->PostRotation.Get(); + FbxDouble3 pre_rotation = pNode->PreRotation.Get(); + FbxDouble3 rotation_offset = pNode->RotationOffset.Get(); + FbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); + FbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); + FbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); + FbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); + FbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); + FbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); + EFbxRotationOrder rotation_order = pNode->RotationOrder.Get(); - KFbxVector4 lZero(0.0, 0.0, 0.0); - KFbxVector4 lOne(1.0, 1.0, 1.0); + FbxVector4 lZero(0.0, 0.0, 0.0); + FbxVector4 lOne(1.0, 1.0, 1.0); assert(geometric_rotation == lZero); assert(geometric_translation == lZero); @@ -879,8 +887,8 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p // printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]); // printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); - KFbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType()); - if(attribute_type == KFbxNodeAttribute::eLODGroup) { + FbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType()); + if(attribute_type == FbxNodeAttribute::eLODGroup) { std::string name = GetFbxObjectName(pNode); FbxLODGroup *fbx_lod_group = (FbxLODGroup*) pNode->GetNodeAttribute(); // FbxCast(pNode); bool use_world_space_units = fbx_lod_group->WorldSpace.Get(); @@ -964,25 +972,25 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p } else { KRNode *new_node = NULL; switch(attribute_type) { - case KFbxNodeAttribute::eMesh: + case FbxNodeAttribute::eMesh: new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode); break; - case KFbxNodeAttribute::eLight: + case FbxNodeAttribute::eLight: new_node = LoadLight(parent_node, pNode); break; - case KFbxNodeAttribute::eSkeleton: + case FbxNodeAttribute::eSkeleton: new_node = LoadSkeleton(parent_node, pFbxScene, pNode); break; - case KFbxNodeAttribute::eCamera: + case FbxNodeAttribute::eCamera: new_node = LoadCamera(parent_node, pNode); break; default: { bool is_locator = false; - if(attribute_type == KFbxNodeAttribute::eNull) { - KFbxNull* pSourceNull = (KFbxNull*) pNode->GetNodeAttribute(); - if(pSourceNull->Look.Get() == KFbxNull::eCross ) { + if(attribute_type == FbxNodeAttribute::eNull) { + FbxNull* pSourceNull = (FbxNull*) pNode->GetNodeAttribute(); + if(pSourceNull->Look.Get() == FbxNull::eCross ) { is_locator = true; } } @@ -1059,7 +1067,7 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { FbxPropertyT lKFbxDouble3; FbxPropertyT lKFbxDouble1; - if (pMaterial->GetClassId().Is(KFbxSurfacePhong::ClassId)) { + if (pMaterial->GetClassId().Is(FbxSurfacePhong::ClassId)) { // We found a Phong material. // Ambient Color @@ -1067,11 +1075,11 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Diffuse Color - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Diffuse; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Diffuse; new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Specular Color (unique to Phong materials) - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Specular; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Specular; new_material->setSpecular(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Emissive Color @@ -1084,7 +1092,7 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { */ // Shininess - lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->Shininess; + lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->Shininess; new_material->setShininess(lKFbxDouble1.Get()); /* @@ -1094,27 +1102,27 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { */ // Transparency Color - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->TransparentColor; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->TransparentColor; new_material->setTransparency( 1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); // Reflection factor - lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->ReflectionFactor; + lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->ReflectionFactor; // Reflection color - lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Reflection; + lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection; // We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken new_material->setReflection(KRVector3(lKFbxDouble3.Get()[0] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[1] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[2] * lKFbxDouble1.Get())); - } else if(pMaterial->GetClassId().Is(KFbxSurfaceLambert::ClassId) ) { + } else if(pMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId) ) { // We found a Lambert material. // Ambient Color - lKFbxDouble3=((KFbxSurfaceLambert *)pMaterial)->Ambient; + lKFbxDouble3=((FbxSurfaceLambert *)pMaterial)->Ambient; new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Diffuse Color - lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Diffuse; + lKFbxDouble3 =((FbxSurfaceLambert *)pMaterial)->Diffuse; new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); // Emissive @@ -1126,7 +1134,7 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { */ // Transparency Color - lKFbxDouble3 =((KFbxSurfaceLambert *) pMaterial)->TransparentColor; + lKFbxDouble3 =((FbxSurfaceLambert *) pMaterial)->TransparentColor; new_material->setTransparency(1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); } else { @@ -1135,31 +1143,31 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { - KFbxProperty pProperty; + FbxProperty pProperty; // Diffuse Map Texture - pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse); - if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) { + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse); + if(pProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId) > 0) { printf("Warning! Layered textures not supported.\n"); } - int texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId); + int texture_count = pProperty.GetSrcObjectCount(FbxTexture::ClassId); if(texture_count > 1) { printf("Error! Multiple diffuse textures not supported.\n"); } else if(texture_count == 1) { - KFbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(KFbxTexture::ClassId,0)); + FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxTexture::ClassId,0)); assert(!pTexture->GetSwapUV()); assert(pTexture->GetCroppingTop() == 0); assert(pTexture->GetCroppingLeft() == 0); assert(pTexture->GetCroppingRight() == 0); assert(pTexture->GetCroppingBottom() == 0); - assert(pTexture->GetWrapModeU() == KFbxTexture::eRepeat); - assert(pTexture->GetWrapModeV() == KFbxTexture::eRepeat); + assert(pTexture->GetWrapModeU() == FbxTexture::eRepeat); + assert(pTexture->GetWrapModeV() == FbxTexture::eRepeat); assert(pTexture->GetRotationU() == 0.0f); assert(pTexture->GetRotationV() == 0.0f); assert(pTexture->GetRotationW() == 0.0f); - KFbxFileTexture *pFileTexture = FbxCast(pTexture); + FbxFileTexture *pFileTexture = FbxCast(pTexture); if(pFileTexture) { new_material->setDiffuseMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } @@ -1167,24 +1175,24 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { // Specular Map Texture - pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sSpecular); - if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) { + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecular); + if(pProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId) > 0) { printf("Warning! Layered textures not supported.\n"); } - texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId); + texture_count = pProperty.GetSrcObjectCount(FbxTexture::ClassId); if(texture_count > 1) { printf("Error! Multiple specular textures not supported.\n"); } else if(texture_count == 1) { - KFbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(KFbxTexture::ClassId,0)); - KFbxFileTexture *pFileTexture = FbxCast(pTexture); + FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxTexture::ClassId,0)); + FbxFileTexture *pFileTexture = FbxCast(pTexture); if(pFileTexture) { new_material->setSpecularMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } } // Normal Map Texture - pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sNormalMap); - if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) { + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap); + if(pProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId) > 0) { printf("Warning! Layered textures not supported.\n"); } @@ -1193,8 +1201,8 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { if(texture_count > 1) { printf("Error! Multiple normal map textures not supported.\n"); } else if(texture_count == 1) { - KFbxTexture* pTexture = pProperty.GetSrcObject(0); - KFbxFileTexture *pFileTexture = FbxCast(pTexture); + FbxTexture* pTexture = pProperty.GetSrcObject(0); + FbxFileTexture *pFileTexture = FbxCast(pTexture); if(pFileTexture) { new_material->setNormalMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } @@ -1211,8 +1219,8 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { -void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) { - KFbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh); +void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxMesh* pSourceMesh) { + FbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh); KRMesh::mesh_info mi; mi.format = KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES; @@ -1223,7 +1231,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG } control_point_weight_info_t; int control_point_count = pMesh->GetControlPointsCount(); - KFbxVector4* control_points = pMesh->GetControlPoints(); + FbxVector4* control_points = pMesh->GetControlPoints(); control_point_weight_info_t *control_point_weights = new control_point_weight_info_t[control_point_count]; for(int control_point=0; control_point < control_point_count; control_point++) { @@ -1346,7 +1354,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG bool need_tangents = false; for(int iMaterial=0; iMaterial < material_count; iMaterial++) { - KFbxSurfaceMaterial *pMaterial = pSourceMesh->GetNode()->GetMaterial(iMaterial); + FbxSurfaceMaterial *pMaterial = pSourceMesh->GetNode()->GetMaterial(iMaterial); KRMaterial *material = context.getMaterialManager()->getMaterial(pMaterial->GetName()); if(material) { @@ -1384,7 +1392,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG for(int iVertex=0; iVertex<3; iVertex++) { // ----====---- Read Vertex Position ----====---- int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex); - KFbxVector4 v = control_points[lControlPointIndex]; + FbxVector4 v = control_points[lControlPointIndex]; mi.vertices.push_back(KRVector3(v[0], v[1], v[2])); if(mi.bone_names.size() > 0) { @@ -1405,12 +1413,14 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG // ----====---- Read UVs ----====---- - KStringList uvNames; + FbxStringList uvNames; pMesh->GetUVSetNames(uvNames); if(uv_count >= 1) { const char *setName = uvNames[0].Buffer(); - KFbxVector2 uv; - if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { + FbxVector2 uv; + bool unmapped = false; + if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { + assert(!unmapped); new_uva = KRVector2(uv[0], uv[1]); } mi.uva.push_back(new_uva); @@ -1418,8 +1428,10 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG if(uv_count >= 2) { const char *setName = uvNames[1].Buffer(); - KFbxVector2 uv; - if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { + FbxVector2 uv; + bool unmapped = false; + if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { + assert(!unmapped); new_uvb = KRVector2(uv[0], uv[1]); } mi.uvb.push_back(new_uvb); @@ -1427,7 +1439,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG // ----====---- Read Normals ----====---- - KFbxVector4 new_normal; + FbxVector4 new_normal; if(pMesh->GetPolygonVertexNormal(iPolygon, iVertex, new_normal)) { mi.normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2])); } @@ -1436,7 +1448,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG // ----====---- Read Tangents ----====---- for(int l = 0; l < tangent_count; ++l) { - KFbxVector4 new_tangent; + FbxVector4 new_tangent; FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l); if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) { @@ -1488,10 +1500,10 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG context.getModelManager()->addModel(new_mesh); } -KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { +KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); - KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute(); + FbxMesh* pSourceMesh = (FbxMesh*) pNode->GetNodeAttribute(); if(KRMesh::GetLODCoverage(pNode->GetName()) == 100) { // If this is the full detail model, add an instance of it to the scene file @@ -1516,7 +1528,7 @@ KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter } -KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { +KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); KRBone *new_bone = new KRBone(parent_node->getScene(), name.c_str()); @@ -1530,7 +1542,7 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) return new_bone; } -KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { +KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str()); @@ -1545,7 +1557,7 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { return new_locator; } -KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) { +KRNode *LoadCamera(KRNode *parent_node, FbxNode* pNode) { FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute(); const char *szName = pNode->GetName(); @@ -1553,7 +1565,7 @@ KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) { return new_camera; } -KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { +KRNode *LoadLight(KRNode *parent_node, FbxNode* pNode) { const GLfloat PI = 3.14159265; const GLfloat d2r = PI * 2 / 360; @@ -1564,7 +1576,7 @@ KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { FbxDouble light_intensity = pLight->Intensity.Get(); FbxDouble light_hotspot = pLight->InnerAngle.Get(); // light inner cone angle (in degrees). Also know as the HotSpot FbxDouble light_coneangle = pLight->OuterAngle.Get(); // light outer cone angle (in degrees). Also known as the Falloff - KFbxLight::EDecayType light_decaytype = pLight->DecayType.Get(); // decay type + FbxLight::EDecayType light_decaytype = pLight->DecayType.Get(); // decay type FbxDouble light_decaystart = pLight->DecayStart.Get(); // decay start distance @@ -1576,20 +1588,20 @@ KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { KRLight *new_light = NULL; switch(pLight->LightType.Get()) { - case KFbxLight::ePoint: + case FbxLight::ePoint: { KRPointLight *l = new KRPointLight(parent_node->getScene(), szName); new_light = l; } break; - case KFbxLight::eDirectional: + case FbxLight::eDirectional: { KRDirectionalLight *l = new KRDirectionalLight(parent_node->getScene(), szName); new_light = l; } break; - case KFbxLight::eSpot: + case FbxLight::eSpot: { KRSpotLight *l = new KRSpotLight(parent_node->getScene(), szName); l->setInnerAngle(light_hotspot * d2r); @@ -1597,8 +1609,8 @@ KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode) { new_light = l; } break; - case KFbxLight::eVolume: - case KFbxLight::eArea: + case FbxLight::eVolume: + case FbxLight::eArea: // Not supported yet break; } diff --git a/KREngine/kraken/KRTextureStreamer.mm b/KREngine/kraken/KRTextureStreamer.mm index 5dc8682..46043cc 100644 --- a/KREngine/kraken/KRTextureStreamer.mm +++ b/KREngine/kraken/KRTextureStreamer.mm @@ -13,8 +13,21 @@ #include + +#if TARGET_OS_IPHONE + EAGLContext *gTextureStreamerContext = nil; +#elif TARGET_OS_MAC + +NSOpenGLContext *gTextureStreamerContext = nil; + +#else + +#error Unsupported Platform +#endif + + KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context) { m_running = false; @@ -25,7 +38,27 @@ void KRTextureStreamer::startStreamer() { if(!m_running) { m_running = true; + +#if TARGET_OS_IPHONE + gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; + + +#elif TARGET_OS_MAC + + NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = + { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + 0 + }; + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; + gTextureStreamerContext = [[[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: [NSOpenGLContext currentContext] ] autorelease]; + +#else + + #error Unsupported Platform +#endif + m_thread = std::thread(&KRTextureStreamer::run, this); } } @@ -43,7 +76,14 @@ void KRTextureStreamer::run() pthread_setname_np("Kraken - Texture Streamer"); std::chrono::microseconds sleep_duration( 100 ); + +#if TARGET_OS_IPHONE [EAGLContext setCurrentContext: gTextureStreamerContext]; +#elif TARGET_OS_MAC + [gTextureStreamerContext makeCurrentContext]; +#else +#error Unsupported Platform +#endif while(!m_stop) { From 61fde7700b91f53fc0279fa1aabce2182df4d372 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 23 Nov 2013 17:02:17 -0800 Subject: [PATCH 28/43] Fixed crash in fbx import pipeline --- KREngine/kraken/KRMesh.cpp | 8 ++--- KREngine/kraken/KRMesh.h | 3 -- KREngine/kraken/KRMeshStreamer.h | 3 ++ KREngine/kraken/KRMeshStreamer.mm | 47 +++++++++++++++++----------- KREngine/kraken/KRTextureStreamer.h | 1 - KREngine/kraken/KRTextureStreamer.mm | 10 +++--- 6 files changed, 40 insertions(+), 32 deletions(-) diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index 5082a07..7e0e88c 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -110,6 +110,8 @@ KRMesh::~KRMesh() { } void KRMesh::releaseData() { + m_hasTransparency = false; + m_submeshes.clear(); if(m_pIndexBaseData) { m_pIndexBaseData->unlock(); delete m_pIndexBaseData; @@ -397,7 +399,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st void KRMesh::LoadData(const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { - clearBuffers(); + releaseData(); // TODO, FINDME - These values should be passed as a parameter and set by GUI flags bool use_short_vertexes = false; @@ -645,10 +647,6 @@ KRVector3 KRMesh::getMaxPoint() const { return m_maxPoint; } -void KRMesh::clearBuffers() { - m_submeshes.clear(); -} - int KRMesh::getLODCoverage() const { return m_lodCoverage; } diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index 602a5a6..eecacc2 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -250,9 +250,6 @@ private: int m_vertex_size; void updateAttributeOffsets(); - - void clearBuffers(); - void setName(const std::string name); diff --git a/KREngine/kraken/KRMeshStreamer.h b/KREngine/kraken/KRMeshStreamer.h index a0c36e9..beb3666 100644 --- a/KREngine/kraken/KRMeshStreamer.h +++ b/KREngine/kraken/KRMeshStreamer.h @@ -45,11 +45,14 @@ public: KRMeshStreamer(KRContext &context); ~KRMeshStreamer(); + void startStreamer(); + private: KRContext &m_context; std::thread m_thread; std::atomic m_stop; + std::atomic m_running; void run(); }; diff --git a/KREngine/kraken/KRMeshStreamer.mm b/KREngine/kraken/KRMeshStreamer.mm index 3067fe3..1fd6560 100644 --- a/KREngine/kraken/KRMeshStreamer.mm +++ b/KREngine/kraken/KRMeshStreamer.mm @@ -28,29 +28,40 @@ NSOpenGLContext *gMeshStreamerContext = nil; KRMeshStreamer::KRMeshStreamer(KRContext &context) : m_context(context) { - -#if TARGET_OS_IPHONE - gMeshStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; -#elif TARGET_OS_MAC - NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = - { - NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, - 0 - }; - NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; - gMeshStreamerContext = [[[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: [NSOpenGLContext currentContext] ] autorelease]; -#else - #error Unsupported Platform -#endif - + m_running = false; m_stop = false; - m_thread = std::thread(&KRMeshStreamer::run, this); +} + +void KRMeshStreamer::startStreamer() +{ + if(!m_running) { + m_running = true; + +#if TARGET_OS_IPHONE + gMeshStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; +#elif TARGET_OS_MAC + NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = + { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + 0 + }; + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; + gMeshStreamerContext = [[[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: [NSOpenGLContext currentContext] ] autorelease]; +#else + #error Unsupported Platform +#endif + + m_thread = std::thread(&KRMeshStreamer::run, this); + } } KRMeshStreamer::~KRMeshStreamer() { - m_stop = true; - m_thread.join(); + if(m_running) { + m_stop = true; + m_thread.join(); + m_running = false; + } [gMeshStreamerContext release]; } diff --git a/KREngine/kraken/KRTextureStreamer.h b/KREngine/kraken/KRTextureStreamer.h index 22dbdb0..39f3705 100644 --- a/KREngine/kraken/KRTextureStreamer.h +++ b/KREngine/kraken/KRTextureStreamer.h @@ -55,7 +55,6 @@ private: std::atomic m_running; void run(); - }; #endif /* defined(KRTEXTURESTREAMER_H) */ diff --git a/KREngine/kraken/KRTextureStreamer.mm b/KREngine/kraken/KRTextureStreamer.mm index 46043cc..5185c22 100644 --- a/KREngine/kraken/KRTextureStreamer.mm +++ b/KREngine/kraken/KRTextureStreamer.mm @@ -27,7 +27,6 @@ NSOpenGLContext *gTextureStreamerContext = nil; #error Unsupported Platform #endif - KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context) { m_running = false; @@ -65,8 +64,11 @@ void KRTextureStreamer::startStreamer() KRTextureStreamer::~KRTextureStreamer() { - m_stop = true; - m_thread.join(); + if(m_running) { + m_stop = true; + m_thread.join(); + m_running = false; + } [gTextureStreamerContext release]; } @@ -92,6 +94,4 @@ void KRTextureStreamer::run() } std::this_thread::sleep_for( sleep_duration ); } - - m_running = false; } From 678cea559cba202f9fbb3fb2231339eb903c5e13 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 23 Nov 2013 18:21:16 -0800 Subject: [PATCH 29/43] KRAnimation::Play() no longer seeks back to the start of the animation automatically. Use KRAnimation::SetTime(0.0f) to seek to the beginning manually if needed. --HG-- branch : nfb --- KREngine/kraken/KRAnimation.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index d8ef8de..7db4273 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -173,7 +173,6 @@ void KRAnimation::update(float deltaTime) void KRAnimation::Play() { - m_local_time = 0.0f; m_playing = true; getContext().getAnimationManager()->updateActiveAnimations(this); } From 58b39a62020f276bb1a57974582985efb5ff69f4 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Wed, 27 Nov 2013 00:10:29 -0800 Subject: [PATCH 30/43] When importing FBX meshes with some unmapped UV's, they are now substituted with (0,0) rather than asserting false and cancelling the import. --HG-- branch : nfb --- KREngine/kraken/KRResource+fbx.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index bb82a8f..e778d03 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -1420,8 +1420,9 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe FbxVector2 uv; bool unmapped = false; if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { - assert(!unmapped); - new_uva = KRVector2(uv[0], uv[1]); + if(!unmapped) { + new_uva = KRVector2(uv[0], uv[1]); + } } mi.uva.push_back(new_uva); } @@ -1431,8 +1432,9 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe FbxVector2 uv; bool unmapped = false; if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { - assert(!unmapped); - new_uvb = KRVector2(uv[0], uv[1]); + if(!unmapped) { + new_uvb = KRVector2(uv[0], uv[1]); + } } mi.uvb.push_back(new_uvb); } From c1551a8a235442ff42890af2ad52498207582d4e Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Wed, 27 Nov 2013 01:39:14 -0800 Subject: [PATCH 31/43] Fixed bug that caused some animations to crash the FBX import pipeline. --HG-- branch : nfb --- KREngine/kraken/KRAnimationCurveManager.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/KREngine/kraken/KRAnimationCurveManager.cpp b/KREngine/kraken/KRAnimationCurveManager.cpp index 548d378..08c6cbe 100644 --- a/KREngine/kraken/KRAnimationCurveManager.cpp +++ b/KREngine/kraken/KRAnimationCurveManager.cpp @@ -50,12 +50,19 @@ void KRAnimationCurveManager::deleteAnimationCurve(KRAnimationCurve *curve) { KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const std::string &name, KRDataBlock *data) { KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data); - m_animationCurves[name] = pAnimationCurve; + if(pAnimationCurve) { + m_animationCurves[name] = pAnimationCurve; + } return pAnimationCurve; } KRAnimationCurve *KRAnimationCurveManager::getAnimationCurve(const std::string &name) { - return m_animationCurves[name]; + unordered_map::iterator itr = m_animationCurves.find(name); + if(itr == m_animationCurves.end()) { + return NULL; // Not found + } else { + return (*itr).second; + } } unordered_map &KRAnimationCurveManager::getAnimationCurves() { @@ -64,6 +71,7 @@ unordered_map &KRAnimationCurveManager::getAnim void KRAnimationCurveManager::addAnimationCurve(KRAnimationCurve *new_animation_curve) { + assert(new_animation_curve != NULL); m_animationCurves[new_animation_curve->getName()] = new_animation_curve; } From a1d93d24b9ce2d281079afafb957589a7ea8bce1 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 30 Nov 2013 02:01:02 -0800 Subject: [PATCH 32/43] Animated textures updated for compatibility with asynchronous texture streamer --HG-- branch : nfb --- KREngine/kraken/KRTextureAnimated.cpp | 20 ++++++++------------ KREngine/kraken/KRTextureAnimated.h | 1 + KREngine/kraken/KRTextureManager.cpp | 16 +++++++++++----- KREngine/kraken/KRTextureManager.h | 1 + 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/KREngine/kraken/KRTextureAnimated.cpp b/KREngine/kraken/KRTextureAnimated.cpp index a38d970..c25028a 100644 --- a/KREngine/kraken/KRTextureAnimated.cpp +++ b/KREngine/kraken/KRTextureAnimated.cpp @@ -47,7 +47,7 @@ KRTextureAnimated::KRTextureAnimated(KRContext &context, std::string name) : KRT int second_comma_pos = name.find(",", first_comma_pos + 1); - m_texture_base_name = name.substr(8, first_comma_pos - 9); + m_texture_base_name = name.substr(8, first_comma_pos - 8); m_frame_count = atoi(name.substr(first_comma_pos+1, second_comma_pos - first_comma_pos -1).c_str()); m_frame_rate = atof(name.substr(second_comma_pos+1).c_str()); @@ -87,17 +87,7 @@ bool KRTextureAnimated::createGLTexture(int lod_max_dim) long KRTextureAnimated::getMemRequiredForSize(int max_dim) { - int target_dim = max_dim; - if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - - long memoryRequired = 0; - for(int i=0; igetMemRequiredForSize(target_dim); - } - } - return memoryRequired; + return 0; // Memory is allocated by individual frame textures } @@ -108,12 +98,14 @@ void KRTextureAnimated::resetPoolExpiry() KRTexture2D *frame_texture = textureForFrame(i); if(frame_texture) { frame_texture->resetPoolExpiry(); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly + getContext().getTextureManager()->primeTexture(frame_texture); } } } void KRTextureAnimated::bind(GLuint texture_unit) { + resetPoolExpiry(); KRTexture::bind(texture_unit); int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count)); KRTexture2D *frame_texture = textureForFrame(frame_number); @@ -154,3 +146,7 @@ bool KRTextureAnimated::save(KRDataBlock &data) return true; // Animated textures are just references; there are no files to output } +void KRTextureAnimated::resize(int max_dim) +{ + // Purposely not calling the superclass method +} \ No newline at end of file diff --git a/KREngine/kraken/KRTextureAnimated.h b/KREngine/kraken/KRTextureAnimated.h index 8e458b9..9e685b6 100644 --- a/KREngine/kraken/KRTextureAnimated.h +++ b/KREngine/kraken/KRTextureAnimated.h @@ -50,6 +50,7 @@ public: virtual long getReferencedMemSize(); virtual bool isAnimated(); + virtual void resize(int max_dim); private: virtual bool createGLTexture(int lod_max_dim); diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index b7b8bfa..74b718f 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -161,7 +161,7 @@ KRTexture *KRTextureManager::getTexture(const std::string &name) { if(itr == m_textures.end()) { if(lowerName.length() <= 8) { return NULL; - } else if(lowerName.substr(8).compare("animate:") == 0) { + } else if(lowerName.compare(0, 8, "animate:", 0, 8) == 0) { // This is an animated texture, create KRTextureAnimated's on-demand KRTextureAnimated *pTexture = new KRTextureAnimated(getContext(), lowerName); m_textures[lowerName] = pTexture; @@ -185,10 +185,8 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { if(m_boundTextures[iTextureUnit] != pTexture || is_animated) { _setActiveTexture(iTextureUnit); if(pTexture != NULL) { - m_poolTextures.erase(pTexture); - if(m_activeTextures.find(pTexture) == m_activeTextures.end()) { - m_activeTextures.insert(pTexture); - } + primeTexture(pTexture); + pTexture->bind(iTextureUnit); } else { @@ -199,6 +197,14 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { } +void KRTextureManager::primeTexture(KRTexture *pTexture) +{ + m_poolTextures.erase(pTexture); + if(m_activeTextures.find(pTexture) == m_activeTextures.end()) { + m_activeTextures.insert(pTexture); + } +} + long KRTextureManager::getMemUsed() { return m_textureMemUsed; } diff --git a/KREngine/kraken/KRTextureManager.h b/KREngine/kraken/KRTextureManager.h index b55a473..cdf8b99 100644 --- a/KREngine/kraken/KRTextureManager.h +++ b/KREngine/kraken/KRTextureManager.h @@ -46,6 +46,7 @@ public: KRTextureManager(KRContext &context); virtual ~KRTextureManager(); + void primeTexture(KRTexture *pTexture); void selectTexture(int iTextureUnit, KRTexture *pTexture); KRTexture *loadTexture(const char *szName, const char *szExtension, KRDataBlock *data); From 37c2eca1bc5cd31d043b8501a12baa0f5886918b Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 30 Nov 2013 12:46:01 -0800 Subject: [PATCH 33/43] Implemented KRMeshQuad, representing a stock quad model Implemented KRSprite --HG-- branch : nfb --- KREngine/Kraken.xcodeproj/project.pbxproj | 24 +++++ KREngine/kraken/KRMeshManager.cpp | 5 +- KREngine/kraken/KRMeshQuad.cpp | 68 ++++++++++++ KREngine/kraken/KRMeshQuad.h | 44 ++++++++ KREngine/kraken/KRNode.cpp | 3 + KREngine/kraken/KRSprite.cpp | 123 ++++++++++++++++++++++ KREngine/kraken/KRSprite.h | 39 +++++++ 7 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 KREngine/kraken/KRMeshQuad.cpp create mode 100644 KREngine/kraken/KRMeshQuad.h create mode 100644 KREngine/kraken/KRSprite.cpp create mode 100644 KREngine/kraken/KRSprite.h diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index e9aabca..f66c598 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -16,6 +16,14 @@ E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; }; E40BA45615EFF79500D7C3DD /* KRAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = E40BA45315EFF79500D7C3DD /* KRAABB.h */; settings = {ATTRIBUTES = (); }; }; E40BA45715EFF79500D7C3DD /* KRAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = E40BA45315EFF79500D7C3DD /* KRAABB.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E40F982C184A7A2700CFA4D8 /* KRMeshQuad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40F982A184A7A2700CFA4D8 /* KRMeshQuad.cpp */; }; + E40F982D184A7A2700CFA4D8 /* KRMeshQuad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40F982A184A7A2700CFA4D8 /* KRMeshQuad.cpp */; }; + E40F982E184A7A2700CFA4D8 /* KRMeshQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = E40F982B184A7A2700CFA4D8 /* KRMeshQuad.h */; }; + E40F982F184A7A2700CFA4D8 /* KRMeshQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = E40F982B184A7A2700CFA4D8 /* KRMeshQuad.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E40F9832184A7BAC00CFA4D8 /* KRSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */; }; + E40F9833184A7BAC00CFA4D8 /* KRSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */; }; + E40F9834184A7BAC00CFA4D8 /* KRSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = E40F9831184A7BAC00CFA4D8 /* KRSprite.h */; }; + E40F9835184A7BAC00CFA4D8 /* KRSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = E40F9831184A7BAC00CFA4D8 /* KRSprite.h */; settings = {ATTRIBUTES = (Public, ); }; }; E414BAE21435557300A668C4 /* KRModel.h in Headers */ = {isa = PBXBuildFile; fileRef = E414BAE11435557300A668C4 /* KRModel.h */; settings = {ATTRIBUTES = (); }; }; E414BAE51435558900A668C4 /* KRModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E414BAE41435558800A668C4 /* KRModel.cpp */; }; E414BAE7143557D200A668C4 /* KRScene.h in Headers */ = {isa = PBXBuildFile; fileRef = E414BAE6143557D200A668C4 /* KRScene.h */; settings = {ATTRIBUTES = (); }; }; @@ -403,6 +411,10 @@ E4030E4B160A3CF000592648 /* KRStockGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRStockGeometry.h; sourceTree = ""; }; E40BA45215EFF79500D7C3DD /* KRAABB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRAABB.cpp; sourceTree = ""; }; E40BA45315EFF79500D7C3DD /* KRAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRAABB.h; sourceTree = ""; }; + E40F982A184A7A2700CFA4D8 /* KRMeshQuad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRMeshQuad.cpp; sourceTree = ""; }; + E40F982B184A7A2700CFA4D8 /* KRMeshQuad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshQuad.h; sourceTree = ""; }; + E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSprite.cpp; sourceTree = ""; }; + E40F9831184A7BAC00CFA4D8 /* KRSprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRSprite.h; sourceTree = ""; }; E414BAE11435557300A668C4 /* KRModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRModel.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E414BAE41435558800A668C4 /* KRModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRModel.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E414BAE6143557D200A668C4 /* KRScene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRScene.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; @@ -921,6 +933,8 @@ E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */, E43F70FD1824E73100136169 /* KRMeshStreamer.mm */, E43F70FE1824E73100136169 /* KRMeshStreamer.h */, + E40F982A184A7A2700CFA4D8 /* KRMeshQuad.cpp */, + E40F982B184A7A2700CFA4D8 /* KRMeshQuad.h */, ); name = Mesh; sourceTree = ""; @@ -1003,6 +1017,8 @@ E468447E17FFDF51001F1FA1 /* KRLocator.h */, E43F70DA181B20E300136169 /* KRLODSet.cpp */, E43F70DB181B20E400136169 /* KRLODSet.h */, + E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */, + E40F9831184A7BAC00CFA4D8 /* KRSprite.h */, ); name = "Scene Graph Nodes"; sourceTree = ""; @@ -1227,6 +1243,7 @@ E414BAE21435557300A668C4 /* KRModel.h in Headers */, E414BAE7143557D200A668C4 /* KRScene.h in Headers */, E48B3CBD14393DF5000C50E2 /* KRCamera.h in Headers */, + E40F982E184A7A2700CFA4D8 /* KRMeshQuad.h in Headers */, E497B94A151BCEE900D3DC67 /* KRResource.h in Headers */, E461A152152E54B500F2044A /* KRLight.h in Headers */, E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */, @@ -1242,6 +1259,7 @@ E4924C2715EE95E800B965C6 /* KROctree.h in Headers */, E4924C2C15EE96AB00B965C6 /* KROctreeNode.h in Headers */, E40BA45615EFF79500D7C3DD /* KRAABB.h in Headers */, + E40F9834184A7BAC00CFA4D8 /* KRSprite.h in Headers */, E488399615F928CA00BD66D5 /* KRBundle.h in Headers */, E488399E15F92BE000BD66D5 /* KRBundleManager.h in Headers */, E4030E4C160A3CF000592648 /* KRStockGeometry.h in Headers */, @@ -1363,6 +1381,8 @@ E45134B91746A4A300443C21 /* KRBehavior.h in Headers */, E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */, E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */, + E40F982F184A7A2700CFA4D8 /* KRMeshQuad.h in Headers */, + E40F9835184A7BAC00CFA4D8 /* KRSprite.h in Headers */, E48CF945173453990005EBBB /* KRFloat.h in Headers */, E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */, E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */, @@ -1621,11 +1641,13 @@ E4C454AF167BB8FC003586CD /* KRMeshCube.cpp in Sources */, E4C454B5167BC05C003586CD /* KRMeshSphere.cpp in Sources */, E4C454BB167BD248003586CD /* KRHitInfo.cpp in Sources */, + E40F9832184A7BAC00CFA4D8 /* KRSprite.cpp in Sources */, E44F38281683B24800399B5D /* KRRenderSettings.cpp in Sources */, E414F9A61694D977000B3D58 /* KRUnknownManager.cpp in Sources */, E414F9AC1694DA37000B3D58 /* KRUnknown.cpp in Sources */, E48B68151697794F00D99917 /* KRAudioSource.cpp in Sources */, E4F027C716979CCD00D4427D /* KRAudioManager.cpp in Sources */, + E40F982C184A7A2700CFA4D8 /* KRMeshQuad.cpp in Sources */, E4F027CE16979CE200D4427D /* KRAudioSample.cpp in Sources */, E4F027DE1697BFFF00D4427D /* KRAudioBuffer.cpp in Sources */, E4943231169E08D200BCB891 /* KRAmbientZone.cpp in Sources */, @@ -1674,6 +1696,7 @@ E46C214C15364DEC009CABF3 /* KRSceneManager.cpp in Sources */, E48C697315374F7E00232E28 /* KRContext.cpp in Sources */, E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */, + E40F982D184A7A2700CFA4D8 /* KRMeshQuad.cpp in Sources */, E46F4A0F155E003000CCF8B8 /* KRDataBlock.cpp in Sources */, E42CB1F1158446AB0066E0D8 /* KRQuaternion.cpp in Sources */, E4AFC6BB15F7C7D600DDB4C8 /* KROctreeNode.cpp in Sources */, @@ -1685,6 +1708,7 @@ E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */, E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, + E40F9833184A7BAC00CFA4D8 /* KRSprite.cpp in Sources */, E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, E4CA10F01637BD58005D9400 /* KRTextureTGA.cpp in Sources */, E4CA11791639CC90005D9400 /* KRViewport.cpp in Sources */, diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index d4905d0..65c7985 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -35,6 +35,7 @@ #include "KRMesh.h" #include "KRMeshCube.h" +#include "KRMeshQuad.h" #include "KRMeshSphere.h" KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_streamer(context) { @@ -45,8 +46,8 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_s m_vboMemUsed = 0; m_memoryTransferredThisFrame = 0; -// addModel(new KRMeshCube(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults - + addModel(new KRMeshCube(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults + addModel(new KRMeshQuad(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults addModel(new KRMeshSphere(context)); m_draw_call_logging_enabled = false; m_draw_call_log_used = false; diff --git a/KREngine/kraken/KRMeshQuad.cpp b/KREngine/kraken/KRMeshQuad.cpp new file mode 100644 index 0000000..6ca1f55 --- /dev/null +++ b/KREngine/kraken/KRMeshQuad.cpp @@ -0,0 +1,68 @@ +// +// KRMeshQuad.cpp +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +#include "KRMeshQuad.h" + + +KRMeshQuad::KRMeshQuad(KRContext &context) : KRMesh(context, "__quad") +{ + KRMesh::mesh_info mi; + + + mi.vertices.push_back(KRVector3(1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(1.0,-1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0,-1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); + mi.vertices.push_back(KRVector3(1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(1.0, 1.0,-1.0)); + mi.vertices.push_back(KRVector3(1.0,-1.0, 1.0)); + mi.vertices.push_back(KRVector3(1.0,-1.0,-1.0)); + mi.vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); + mi.vertices.push_back(KRVector3(1.0, 1.0,-1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); + + + mi.submesh_starts.push_back(0); + mi.submesh_lengths.push_back(mi.vertices.size()); + mi.material_names.push_back(""); + mi.format = KRENGINE_MODEL_FORMAT_STRIP; + + + LoadData(mi, true, true); +} + +KRMeshQuad::~KRMeshQuad() +{ + +} diff --git a/KREngine/kraken/KRMeshQuad.h b/KREngine/kraken/KRMeshQuad.h new file mode 100644 index 0000000..5fa5de2 --- /dev/null +++ b/KREngine/kraken/KRMeshQuad.h @@ -0,0 +1,44 @@ +// +// KRMeshQuad.h +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +#ifndef KRMESHQUAD_H +#define KRMESHQUAD_H + +#include "KRMesh.h" + +class KRMeshQuad : public KRMesh { +public: + KRMeshQuad(KRContext &context); + virtual ~KRMeshQuad(); +private: +}; + +#endif diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index aab2759..b307036 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -24,6 +24,7 @@ #include "KRAudioSource.h" #include "KRAmbientZone.h" #include "KRReverbZone.h" +#include "KRSprite.h" KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getContext()) { @@ -404,6 +405,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { new_node = new KRSpotLight(scene, szName); } else if(strcmp(szElementName, "particles_newtonian") == 0) { new_node = new KRParticleSystemNewtonian(scene, szName); + } else if(strcmp(szElementName, "sprite") == 0) { + new_node = new KRSprite(scene, szName); } else if(strcmp(szElementName, "model") == 0) { float lod_min_coverage = 0.0f; if(e->QueryFloatAttribute("lod_min_coverage", &lod_min_coverage) != tinyxml2::XML_SUCCESS) { diff --git a/KREngine/kraken/KRSprite.cpp b/KREngine/kraken/KRSprite.cpp new file mode 100644 index 0000000..949f433 --- /dev/null +++ b/KREngine/kraken/KRSprite.cpp @@ -0,0 +1,123 @@ +// +// KRSprite.cpp +// KREngine +// +// Created by Kearwood Gilbert on 12-04-05. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + + +#include "KREngine-common.h" +#include "KRSprite.h" + +#include "KRNode.h" +#include "KRMat4.h" +#include "KRVector3.h" +#include "KRCamera.h" +#include "KRContext.h" + +#include "KRShaderManager.h" +#include "KRShader.h" +#include "KRStockGeometry.h" +#include "KRDirectionalLight.h" +#include "KRSpotLight.h" +#include "KRPointLight.h" + + +KRSprite::KRSprite(KRScene &scene, std::string name) : KRNode(scene, name) +{ + m_spriteTexture = ""; + m_pSpriteTexture = NULL; + m_spriteSize = 0.0; +} + +KRSprite::~KRSprite() +{ +} + +std::string KRSprite::getElementName() { + return "sprite"; +} + +tinyxml2::XMLElement *KRSprite::saveXML( tinyxml2::XMLNode *parent) +{ + tinyxml2::XMLElement *e = KRNode::saveXML(parent); + e->SetAttribute("sprite_size", m_spriteSize); + e->SetAttribute("sprite_texture", m_spriteTexture.c_str()); + return e; +} + +void KRSprite::loadXML(tinyxml2::XMLElement *e) { + KRNode::loadXML(e); + + if(e->QueryFloatAttribute("sprite_size", &m_spriteSize) != tinyxml2::XML_SUCCESS) { + m_spriteSize = 0.0; + } + + const char *szSpriteTexture = e->Attribute("sprite_texture"); + if(szSpriteTexture) { + m_spriteTexture = szSpriteTexture; + } else { + m_spriteTexture = ""; + } + m_pSpriteTexture = NULL; +} + +void KRSprite::setSpriteTexture(std::string sprite_texture) { + m_spriteTexture = sprite_texture; + m_pSpriteTexture = NULL; +} + +void KRSprite::setSpriteSize(float sprite_size) { + // TODO - Deprecated - This should come from the localScale + m_spriteSize = sprite_size; +} + +KRAABB KRSprite::getBounds() { + return KRAABB(KRVector3(-m_spriteSize), KRVector3(m_spriteSize), getModelMatrix()); +} + + +void KRSprite::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + + KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); + + + if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { + if(m_spriteTexture.size() && m_spriteSize > 0.0f) { + + + if(!m_pSpriteTexture && m_spriteTexture.size()) { + m_pSpriteTexture = getContext().getTextureManager()->getTexture(m_spriteTexture); + } + + if(m_pSpriteTexture) { + /* + // Enable additive blending + GLDEBUG(glEnable(GL_BLEND)); + GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); + + // Disable z-buffer write + GLDEBUG(glDepthMask(GL_FALSE)); + */ + + // TODO - Sprites are currently additive only. Need to expose this and allow for multiple blending modes + + // Enable z-buffer test + GLDEBUG(glEnable(GL_DEPTH_TEST)); + GLDEBUG(glDepthFunc(GL_LEQUAL)); + GLDEBUG(glDepthRangef(0.0, 1.0)); + + // Render light sprite on transparency pass + KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { + pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_spriteSize); + m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); + } + } + } + + } +} diff --git a/KREngine/kraken/KRSprite.h b/KREngine/kraken/KRSprite.h new file mode 100644 index 0000000..dbe5f2f --- /dev/null +++ b/KREngine/kraken/KRSprite.h @@ -0,0 +1,39 @@ +// +// KRSprite.h +// KREngine +// +// Created by Kearwood Gilbert on 12-04-05. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#ifndef KRSPRITE_H +#define KRSPRITE_H + +#include "KRResource.h" +#include "KRNode.h" +#include "KRTexture.h" + +class KRSprite : public KRNode { +public: + KRSprite(KRScene &scene, std::string name); + + virtual ~KRSprite(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); + virtual void loadXML(tinyxml2::XMLElement *e); + + void setSpriteTexture(std::string sprite_texture); + void setSpriteSize(float sprite_size); + + virtual void render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass); + + virtual KRAABB getBounds(); + +protected: + + std::string m_spriteTexture; + KRTexture *m_pSpriteTexture; + float m_spriteSize; +}; + +#endif From bdb720eb9660810b110ae4c0fd028e9492ce1c26 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 2 Dec 2013 17:44:55 -0800 Subject: [PATCH 34/43] Bug Fix in the animation curve importer + rough test code for pulling metadata out of an FbxNode (a locator in Maya) --HG-- branch : nfb --- KREngine/kraken/KRResource+fbx.cpp | 48 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index e778d03..26179de 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -141,10 +141,14 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) FbxAnimCurve *curve = pFbxScene->GetSrcObject(i); printf(" Animation Curve %i of %i: %s\n", i+1, curve_count, curve->GetName()); KRAnimationCurve *new_curve = LoadAnimationCurve(context, curve); + + //***** curves 1, 2, and 3 are x, y, z translation .. the first point holds the key frame in centimeters + // POSSIBLE UPGRADE .. grab the key frame and output it as the start location to the kranimation file + if(new_curve) { context.getAnimationCurveManager()->addAnimationCurve(new_curve); } - } + } // ----====---- Import Materials ----====---- int material_count = pFbxScene->GetSrcObjectCount(); @@ -389,6 +393,8 @@ KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurv int frame_start = time_span.GetStart().GetSecondDouble() * dest_frame_rate; int frame_count = (time_span.GetStop().GetSecondDouble() * dest_frame_rate) - frame_start; + printf(" animation start %d and frame count %d\n", frame_start, frame_count); + KRAnimationCurve *new_curve = new KRAnimationCurve(context, name); new_curve->setFrameRate(dest_frame_rate); new_curve->setFrameStart(frame_start); @@ -401,8 +407,11 @@ KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurv FbxTime frame_time; frame_time.SetSecondDouble(frame_seconds); float frame_value = pAnimCurve->Evaluate(frame_time, &last_frame); - //printf(" Frame %i / %i: %.6f\n", frame_number, frame_count, frame_value); - new_curve->setValue(frame_number, frame_value); +// printf(" Frame %i / %i: %.6f\n", frame_number, frame_count, frame_value); + if (0 == frame_number) printf("Value at starting key frame = %3.3f\n", frame_value); + new_curve->setValue(frame_number+frame_start, frame_value); + // BUG FIX Dec 2, 2013 .. changed frame_number to frame_number+frame_start + // setValue(frame_number, frame_value) clamps the frame_number range between frame_start : frame_start+frame_count } return new_curve; @@ -974,6 +983,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG switch(attribute_type) { case FbxNodeAttribute::eMesh: new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode); + // KRNode *LoadMesh parses the "collider names" and then alters the attributes (NFB HACK) break; case FbxNodeAttribute::eLight: new_node = LoadLight(parent_node, pNode); @@ -996,6 +1006,27 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG } if(is_locator) { +//**** HACK A BIT TO FIND OUT HOW IT WORKS + printf("IS LOCATOR!\n"); + FbxProperty myprop = pNode->FindProperty("locRadius", true); + if (myprop.IsValid()) { + printf("locRadius found!\n"); + FbxDataType pdt = myprop.GetPropertyDataType(); + EFbxType ptype= pdt.GetType(); + if (eFbxDouble == ptype) { + double radius = myprop.Get(); + printf("The radius is %3.4f\n", radius); + } + } + // FbxProperty p = GetFirstProperty(); + // p = GetNextProperty(p); + // FbxDataType pdt = p->GetPropertyDataType(); + // EFbxType = pdt->GetType(); // this is an enumerated type + // FbxString pname = p->GetName(); + // const char * s = p->GetNameAsCStr(); // owned by the fbx library + // void *datap = p->GetUserDataPtr(); + +//**** END OF HACK new_node = LoadLocator(parent_node, pFbxScene, pNode); } else { if(pNode->GetChildCount() > 0) { @@ -1420,6 +1451,7 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe FbxVector2 uv; bool unmapped = false; if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { + // **** this is where the assert used to happen if(!unmapped) { new_uva = KRVector2(uv[0], uv[1]); } @@ -1512,6 +1544,10 @@ KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter std::string light_map = pNode->GetName(); light_map.append("_lightmap"); +//**** THIS IS WHERE THE collider in house names are parsed and handled .. and then the collider_ names are done +// in CircaViewController.mm postLoadSetup +// + // FINDME, HACK - Until we have a GUI, we're using prefixes to select correct object type const char *node_name = pNode->GetName(); if(strncmp(node_name, "physics_collider_", strlen("physics_collider_")) == 0) { @@ -1547,6 +1583,12 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); +//**** INTERUPT THE NODE STUFF IN HERE +// we can parse the name, look for our special naming conventions, and then route stuff +// either through to the normal locator block within the scene, or we can dump it out +// to another destination .. a script file, an xml file, whatever we need. +//**** + KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str()); //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); From c7948ea314ba23b6b1a81289eee0208c8306ffa4 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Tue, 3 Dec 2013 01:15:17 -0800 Subject: [PATCH 35/43] KRSprite objects now have their own shader, rather than sharing the "Flare" shader. Implemented per-sprite alpha. --HG-- branch : nfb --- KREngine/Kraken.xcodeproj/project.pbxproj | 40 +++++++++++------- KREngine/kraken/KRLight.cpp | 1 + KREngine/kraken/KRMeshQuad.cpp | 22 ++++------ KREngine/kraken/KRNode.cpp | 7 +++- KREngine/kraken/KRNode.h | 11 +++++ KREngine/kraken/KRSprite.cpp | 24 +++++++++-- KREngine/kraken/KRSprite.h | 3 ++ .../Shaders/flare.fsh | 13 +++--- .../Shaders/flare.vsh | 10 ++--- .../Shaders/sprite.fsh | 38 +++++++++++++++++ .../Shaders/sprite.vsh | 42 +++++++++++++++++++ .../Shaders/flare_osx.fsh | 13 +++--- .../Shaders/flare_osx.vsh | 10 ++--- .../Shaders/sprite_osx.fsh | 38 +++++++++++++++++ .../Shaders/sprite_osx.vsh | 42 +++++++++++++++++++ 15 files changed, 257 insertions(+), 57 deletions(-) create mode 100644 KREngine/kraken_standard_assets_ios/Shaders/sprite.fsh create mode 100644 KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh create mode 100644 KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.fsh create mode 100644 KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index f66c598..eef1240 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -291,8 +291,8 @@ E4E6F68716BA5DF700E410F8 /* debug_font.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F64B16BA5D9400E410F8 /* debug_font.vsh */; }; E4E6F68816BA5DF700E410F8 /* dust_particle.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F64C16BA5D9400E410F8 /* dust_particle.fsh */; }; E4E6F68916BA5DF700E410F8 /* dust_particle.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F64D16BA5D9400E410F8 /* dust_particle.vsh */; }; - E4E6F68A16BA5DF700E410F8 /* flare.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F64E16BA5D9400E410F8 /* flare.fsh */; }; - E4E6F68B16BA5DF700E410F8 /* flare.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F64F16BA5D9400E410F8 /* flare.vsh */; }; + E4E6F68A16BA5DF700E410F8 /* sprite.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F64E16BA5D9400E410F8 /* sprite.fsh */; }; + E4E6F68B16BA5DF700E410F8 /* sprite.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F64F16BA5D9400E410F8 /* sprite.vsh */; }; E4E6F68C16BA5DF700E410F8 /* light_directional.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F65016BA5D9400E410F8 /* light_directional.fsh */; }; E4E6F68D16BA5DF700E410F8 /* light_directional.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F65116BA5D9400E410F8 /* light_directional.vsh */; }; E4E6F68E16BA5DF700E410F8 /* light_point_inside.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F65216BA5D9400E410F8 /* light_point_inside.fsh */; }; @@ -323,8 +323,8 @@ E4E6F6A716BA5E0A00E410F8 /* debug_font_osx.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61116BA5D8300E410F8 /* debug_font_osx.vsh */; }; E4E6F6A816BA5E0A00E410F8 /* dust_particle_osx.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61216BA5D8300E410F8 /* dust_particle_osx.fsh */; }; E4E6F6A916BA5E0A00E410F8 /* dust_particle_osx.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61316BA5D8300E410F8 /* dust_particle_osx.vsh */; }; - E4E6F6AA16BA5E0A00E410F8 /* flare_osx.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61416BA5D8300E410F8 /* flare_osx.fsh */; }; - E4E6F6AB16BA5E0A00E410F8 /* flare_osx.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61516BA5D8300E410F8 /* flare_osx.vsh */; }; + E4E6F6AA16BA5E0A00E410F8 /* sprite_osx.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61416BA5D8300E410F8 /* sprite_osx.fsh */; }; + E4E6F6AB16BA5E0A00E410F8 /* sprite_osx.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61516BA5D8300E410F8 /* sprite_osx.vsh */; }; E4E6F6AC16BA5E0A00E410F8 /* light_directional_osx.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61616BA5D8300E410F8 /* light_directional_osx.fsh */; }; E4E6F6AD16BA5E0A00E410F8 /* light_directional_osx.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61716BA5D8300E410F8 /* light_directional_osx.vsh */; }; E4E6F6AE16BA5E0A00E410F8 /* light_point_inside_osx.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F61816BA5D8300E410F8 /* light_point_inside_osx.fsh */; }; @@ -428,6 +428,10 @@ E41AE1DD16B124CA00980428 /* font.tga */ = {isa = PBXFileReference; lastKnownFileType = file; path = font.tga; sourceTree = ""; }; E41B6BA716BE436100B510EB /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; E41B6BA916BE437800B510EB /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = DEVELOPER_DIR; }; + E42559AA184DD4490081BB20 /* flare.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare.fsh; sourceTree = ""; }; + E42559AC184DD45A0081BB20 /* flare.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare.vsh; sourceTree = ""; }; + E42559AE184DD4730081BB20 /* flare_osx.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare_osx.fsh; sourceTree = ""; }; + E42559B0184DD48B0081BB20 /* flare_osx.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare_osx.vsh; sourceTree = ""; }; E428C2F11669610500A16EDF /* KRAnimationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRAnimationManager.h; sourceTree = ""; }; E428C2F41669611600A16EDF /* KRAnimationManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRAnimationManager.cpp; sourceTree = ""; }; E428C2F71669612500A16EDF /* KRAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRAnimation.h; sourceTree = ""; }; @@ -581,8 +585,8 @@ E4E6F61116BA5D8300E410F8 /* debug_font_osx.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = debug_font_osx.vsh; sourceTree = ""; }; E4E6F61216BA5D8300E410F8 /* dust_particle_osx.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = dust_particle_osx.fsh; sourceTree = ""; }; E4E6F61316BA5D8300E410F8 /* dust_particle_osx.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = dust_particle_osx.vsh; sourceTree = ""; }; - E4E6F61416BA5D8300E410F8 /* flare_osx.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare_osx.fsh; sourceTree = ""; }; - E4E6F61516BA5D8300E410F8 /* flare_osx.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare_osx.vsh; sourceTree = ""; }; + E4E6F61416BA5D8300E410F8 /* sprite_osx.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = sprite_osx.fsh; sourceTree = ""; }; + E4E6F61516BA5D8300E410F8 /* sprite_osx.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = sprite_osx.vsh; sourceTree = ""; }; E4E6F61616BA5D8300E410F8 /* light_directional_osx.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = light_directional_osx.fsh; sourceTree = ""; }; E4E6F61716BA5D8300E410F8 /* light_directional_osx.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = light_directional_osx.vsh; sourceTree = ""; }; E4E6F61816BA5D8300E410F8 /* light_point_inside_osx.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = light_point_inside_osx.fsh; sourceTree = ""; }; @@ -609,8 +613,8 @@ E4E6F64B16BA5D9400E410F8 /* debug_font.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = debug_font.vsh; sourceTree = ""; }; E4E6F64C16BA5D9400E410F8 /* dust_particle.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = dust_particle.fsh; sourceTree = ""; }; E4E6F64D16BA5D9400E410F8 /* dust_particle.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = dust_particle.vsh; sourceTree = ""; }; - E4E6F64E16BA5D9400E410F8 /* flare.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare.fsh; sourceTree = ""; }; - E4E6F64F16BA5D9400E410F8 /* flare.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = flare.vsh; sourceTree = ""; }; + E4E6F64E16BA5D9400E410F8 /* sprite.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = sprite.fsh; sourceTree = ""; }; + E4E6F64F16BA5D9400E410F8 /* sprite.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = sprite.vsh; sourceTree = ""; }; E4E6F65016BA5D9400E410F8 /* light_directional.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = light_directional.fsh; sourceTree = ""; }; E4E6F65116BA5D9400E410F8 /* light_directional.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = light_directional.vsh; sourceTree = ""; }; E4E6F65216BA5D9400E410F8 /* light_point_inside.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = light_point_inside.fsh; sourceTree = ""; }; @@ -734,8 +738,8 @@ E4E6F64B16BA5D9400E410F8 /* debug_font.vsh */, E4E6F64C16BA5D9400E410F8 /* dust_particle.fsh */, E4E6F64D16BA5D9400E410F8 /* dust_particle.vsh */, - E4E6F64E16BA5D9400E410F8 /* flare.fsh */, - E4E6F64F16BA5D9400E410F8 /* flare.vsh */, + E4E6F64E16BA5D9400E410F8 /* sprite.fsh */, + E4E6F64F16BA5D9400E410F8 /* sprite.vsh */, E4E6F65016BA5D9400E410F8 /* light_directional.fsh */, E4E6F65116BA5D9400E410F8 /* light_directional.vsh */, E4E6F65216BA5D9400E410F8 /* light_point_inside.fsh */, @@ -759,6 +763,8 @@ E4E6F66416BA5D9400E410F8 /* volumetric_fog_downsampled.vsh */, E4E6F66516BA5D9400E410F8 /* volumetric_fog.fsh */, E4E6F66616BA5D9400E410F8 /* volumetric_fog.vsh */, + E42559AA184DD4490081BB20 /* flare.fsh */, + E42559AC184DD45A0081BB20 /* flare.vsh */, ); path = Shaders; sourceTree = ""; @@ -1153,8 +1159,8 @@ E4E6F61116BA5D8300E410F8 /* debug_font_osx.vsh */, E4E6F61216BA5D8300E410F8 /* dust_particle_osx.fsh */, E4E6F61316BA5D8300E410F8 /* dust_particle_osx.vsh */, - E4E6F61416BA5D8300E410F8 /* flare_osx.fsh */, - E4E6F61516BA5D8300E410F8 /* flare_osx.vsh */, + E4E6F61416BA5D8300E410F8 /* sprite_osx.fsh */, + E4E6F61516BA5D8300E410F8 /* sprite_osx.vsh */, E4E6F61616BA5D8300E410F8 /* light_directional_osx.fsh */, E4E6F61716BA5D8300E410F8 /* light_directional_osx.vsh */, E4E6F61816BA5D8300E410F8 /* light_point_inside_osx.fsh */, @@ -1176,6 +1182,8 @@ E4E6F62816BA5D8300E410F8 /* volumetric_fog_downsampled_osx.vsh */, E4E6F62916BA5D8300E410F8 /* volumetric_fog_osx.fsh */, E4E6F62A16BA5D8300E410F8 /* volumetric_fog_osx.vsh */, + E42559AE184DD4730081BB20 /* flare_osx.fsh */, + E42559B0184DD48B0081BB20 /* flare_osx.vsh */, ); path = Shaders; sourceTree = ""; @@ -1511,8 +1519,8 @@ E4E6F68716BA5DF700E410F8 /* debug_font.vsh in Resources */, E4E6F68816BA5DF700E410F8 /* dust_particle.fsh in Resources */, E4E6F68916BA5DF700E410F8 /* dust_particle.vsh in Resources */, - E4E6F68A16BA5DF700E410F8 /* flare.fsh in Resources */, - E4E6F68B16BA5DF700E410F8 /* flare.vsh in Resources */, + E4E6F68A16BA5DF700E410F8 /* sprite.fsh in Resources */, + E4E6F68B16BA5DF700E410F8 /* sprite.vsh in Resources */, E4E6F68C16BA5DF700E410F8 /* light_directional.fsh in Resources */, E4E6F68D16BA5DF700E410F8 /* light_directional.vsh in Resources */, E4E6F68E16BA5DF700E410F8 /* light_point_inside.fsh in Resources */, @@ -1551,8 +1559,8 @@ E4E6F6A716BA5E0A00E410F8 /* debug_font_osx.vsh in Resources */, E4E6F6A816BA5E0A00E410F8 /* dust_particle_osx.fsh in Resources */, E4E6F6A916BA5E0A00E410F8 /* dust_particle_osx.vsh in Resources */, - E4E6F6AA16BA5E0A00E410F8 /* flare_osx.fsh in Resources */, - E4E6F6AB16BA5E0A00E410F8 /* flare_osx.vsh in Resources */, + E4E6F6AA16BA5E0A00E410F8 /* sprite_osx.fsh in Resources */, + E4E6F6AB16BA5E0A00E410F8 /* sprite_osx.vsh in Resources */, E4E6F6AC16BA5E0A00E410F8 /* light_directional_osx.fsh in Resources */, E4E6F6AD16BA5E0A00E410F8 /* light_directional_osx.vsh in Resources */, E4E6F6AE16BA5E0A00E410F8 /* light_point_inside_osx.fsh in Resources */, diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index d6162f5..80a5e3d 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -333,6 +333,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light // Render light flare on transparency pass KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, 1.0f); pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); diff --git a/KREngine/kraken/KRMeshQuad.cpp b/KREngine/kraken/KRMeshQuad.cpp index 6ca1f55..875f8a7 100644 --- a/KREngine/kraken/KRMeshQuad.cpp +++ b/KREngine/kraken/KRMeshQuad.cpp @@ -36,21 +36,15 @@ KRMeshQuad::KRMeshQuad(KRContext &context) : KRMesh(context, "__quad") { KRMesh::mesh_info mi; + mi.vertices.push_back(KRVector3(-1.0f, -1.0f, 0.0f)); + mi.vertices.push_back(KRVector3(1.0f, -1.0f, 0.0f)); + mi.vertices.push_back(KRVector3(-1.0f, 1.0f, 0.0f)); + mi.vertices.push_back(KRVector3(1.0f, 1.0f, 0.0f)); - mi.vertices.push_back(KRVector3(1.0, 1.0, 1.0)); - mi.vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); - mi.vertices.push_back(KRVector3(1.0,-1.0, 1.0)); - mi.vertices.push_back(KRVector3(-1.0,-1.0, 1.0)); - mi.vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); - mi.vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); - mi.vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); - mi.vertices.push_back(KRVector3(1.0, 1.0, 1.0)); - mi.vertices.push_back(KRVector3(1.0, 1.0,-1.0)); - mi.vertices.push_back(KRVector3(1.0,-1.0, 1.0)); - mi.vertices.push_back(KRVector3(1.0,-1.0,-1.0)); - mi.vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); - mi.vertices.push_back(KRVector3(1.0, 1.0,-1.0)); - mi.vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); + mi.uva.push_back(KRVector2(0.0f, 0.0f)); + mi.uva.push_back(KRVector2(1.0f, 0.0f)); + mi.uva.push_back(KRVector2(0.0f, 1.0f)); + mi.uva.push_back(KRVector2(1.0f, 1.0f)); mi.submesh_starts.push_back(0); diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index b307036..e8ac49e 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -920,4 +920,9 @@ void KRNode::addBehavior(KRBehavior *behavior) m_behaviors.insert(behavior); behavior->__setNode(this); getScene().notify_sceneGraphModify(this); -} \ No newline at end of file +} + +std::set &KRNode::getBehaviors() +{ + return m_behaviors; +} diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index e8d0f9d..eb074fa 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -227,6 +227,17 @@ private: public: void addBehavior(KRBehavior *behavior); + std::set &getBehaviors(); + template T *getBehavior() + { + for(std::set::iterator itr=m_behaviors.begin(); itr != m_behaviors.end(); itr++) { + T *behavior = dynamic_cast(*itr); + if(behavior) { + return behavior; + } + } + return NULL; + } void removeFromOctreeNodes(); void addToOctreeNode(KROctreeNode *octree_node); void childDeleted(KRNode *child_node); diff --git a/KREngine/kraken/KRSprite.cpp b/KREngine/kraken/KRSprite.cpp index 949f433..33807a0 100644 --- a/KREngine/kraken/KRSprite.cpp +++ b/KREngine/kraken/KRSprite.cpp @@ -28,7 +28,8 @@ KRSprite::KRSprite(KRScene &scene, std::string name) : KRNode(scene, name) { m_spriteTexture = ""; m_pSpriteTexture = NULL; - m_spriteSize = 0.0; + m_spriteSize = 0.0f; + m_spriteAlpha = 1.0f; } KRSprite::~KRSprite() @@ -44,6 +45,7 @@ tinyxml2::XMLElement *KRSprite::saveXML( tinyxml2::XMLNode *parent) tinyxml2::XMLElement *e = KRNode::saveXML(parent); e->SetAttribute("sprite_size", m_spriteSize); e->SetAttribute("sprite_texture", m_spriteTexture.c_str()); + e->SetAttribute("sprite_alpha", m_spriteAlpha); return e; } @@ -51,7 +53,10 @@ void KRSprite::loadXML(tinyxml2::XMLElement *e) { KRNode::loadXML(e); if(e->QueryFloatAttribute("sprite_size", &m_spriteSize) != tinyxml2::XML_SUCCESS) { - m_spriteSize = 0.0; + m_spriteSize = 0.0f; + } + if(e->QueryFloatAttribute("sprite_alpha", &m_spriteAlpha) != tinyxml2::XML_SUCCESS) { + m_spriteAlpha = 1.0f; } const char *szSpriteTexture = e->Attribute("sprite_texture"); @@ -73,6 +78,16 @@ void KRSprite::setSpriteSize(float sprite_size) { m_spriteSize = sprite_size; } +void KRSprite::setSpriteAlpha(float alpha) +{ + m_spriteAlpha = alpha; +} + +float KRSprite::getSpriteAlpha() const +{ + return m_spriteAlpha; +} + KRAABB KRSprite::getBounds() { return KRAABB(KRVector3(-m_spriteSize), KRVector3(m_spriteSize), getModelMatrix()); } @@ -84,7 +99,7 @@ void KRSprite::render(KRCamera *pCamera, std::vector &point_ligh if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { - if(m_spriteTexture.size() && m_spriteSize > 0.0f) { + if(m_spriteTexture.size() && m_spriteSize > 0.0f && m_spriteAlpha > 0.0f) { if(!m_pSpriteTexture && m_spriteTexture.size()) { @@ -109,8 +124,9 @@ void KRSprite::render(KRCamera *pCamera, std::vector &point_ligh GLDEBUG(glDepthRangef(0.0, 1.0)); // Render light sprite on transparency pass - KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + KRShader *pShader = getContext().getShaderManager()->getShader("sprite", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_spriteAlpha); pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_spriteSize); m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); diff --git a/KREngine/kraken/KRSprite.h b/KREngine/kraken/KRSprite.h index dbe5f2f..e64be0f 100644 --- a/KREngine/kraken/KRSprite.h +++ b/KREngine/kraken/KRSprite.h @@ -24,6 +24,8 @@ public: void setSpriteTexture(std::string sprite_texture); void setSpriteSize(float sprite_size); + void setSpriteAlpha(float alpha); + float getSpriteAlpha() const; virtual void render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass); @@ -34,6 +36,7 @@ protected: std::string m_spriteTexture; KRTexture *m_pSpriteTexture; float m_spriteSize; + float m_spriteAlpha; }; #endif diff --git a/KREngine/kraken_standard_assets_ios/Shaders/flare.fsh b/KREngine/kraken_standard_assets_ios/Shaders/flare.fsh index aa8d43b..7fce713 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/flare.fsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/flare.fsh @@ -3,17 +3,17 @@ // KREngine // // Copyright 2012 Kearwood Gilbert. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR @@ -23,7 +23,7 @@ // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // The views and conclusions contained in the software and documentation are those of the // authors and should not be interpreted as representing official policies, either expressed // or implied, of Kearwood Gilbert. @@ -31,7 +31,8 @@ varying mediump vec2 texCoord; uniform sampler2D diffuseTexture; +uniform lowp float material_alpha; void main() { - gl_FragColor = vec4(vec3(texture2D(diffuseTexture, texCoord)), 1.0); + gl_FragColor = vec4(vec3(texture2D(diffuseTexture, texCoord)), 1.0) * material_alpha; } \ No newline at end of file diff --git a/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh b/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh index 785bf5e..fc0c4d4 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh @@ -3,17 +3,17 @@ // KREngine // // Copyright 2012 Kearwood Gilbert. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR @@ -23,7 +23,7 @@ // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // The views and conclusions contained in the software and documentation are those of the // authors and should not be interpreted as representing official policies, either expressed // or implied, of Kearwood Gilbert. diff --git a/KREngine/kraken_standard_assets_ios/Shaders/sprite.fsh b/KREngine/kraken_standard_assets_ios/Shaders/sprite.fsh new file mode 100644 index 0000000..4519d5d --- /dev/null +++ b/KREngine/kraken_standard_assets_ios/Shaders/sprite.fsh @@ -0,0 +1,38 @@ +// +// sprite.fsh +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +varying mediump vec2 texCoord; +uniform sampler2D diffuseTexture; +uniform lowp float material_alpha; + +void main() { + gl_FragColor = vec4(vec3(texture2D(diffuseTexture, texCoord)), 1.0) * material_alpha; +} \ No newline at end of file diff --git a/KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh b/KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh new file mode 100644 index 0000000..347191e --- /dev/null +++ b/KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh @@ -0,0 +1,42 @@ +// +// sprite.vsh +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +attribute mediump vec2 vertex_uv; +uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices +uniform mediump vec4 viewport; +uniform mediump float flare_size; + +varying mediump vec2 texCoord; + +void main() { + texCoord = vertex_uv; + gl_Position = mvp_matrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(vertex_uv.x * viewport.w / viewport.z * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 0.0) * flare_size; +} diff --git a/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.fsh b/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.fsh index aa8d43b..7fce713 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.fsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.fsh @@ -3,17 +3,17 @@ // KREngine // // Copyright 2012 Kearwood Gilbert. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR @@ -23,7 +23,7 @@ // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // The views and conclusions contained in the software and documentation are those of the // authors and should not be interpreted as representing official policies, either expressed // or implied, of Kearwood Gilbert. @@ -31,7 +31,8 @@ varying mediump vec2 texCoord; uniform sampler2D diffuseTexture; +uniform lowp float material_alpha; void main() { - gl_FragColor = vec4(vec3(texture2D(diffuseTexture, texCoord)), 1.0); + gl_FragColor = vec4(vec3(texture2D(diffuseTexture, texCoord)), 1.0) * material_alpha; } \ No newline at end of file diff --git a/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.vsh index 785bf5e..fc0c4d4 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.vsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/flare_osx.vsh @@ -3,17 +3,17 @@ // KREngine // // Copyright 2012 Kearwood Gilbert. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR @@ -23,7 +23,7 @@ // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // The views and conclusions contained in the software and documentation are those of the // authors and should not be interpreted as representing official policies, either expressed // or implied, of Kearwood Gilbert. diff --git a/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.fsh b/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.fsh new file mode 100644 index 0000000..4519d5d --- /dev/null +++ b/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.fsh @@ -0,0 +1,38 @@ +// +// sprite.fsh +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +varying mediump vec2 texCoord; +uniform sampler2D diffuseTexture; +uniform lowp float material_alpha; + +void main() { + gl_FragColor = vec4(vec3(texture2D(diffuseTexture, texCoord)), 1.0) * material_alpha; +} \ No newline at end of file diff --git a/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh new file mode 100644 index 0000000..347191e --- /dev/null +++ b/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh @@ -0,0 +1,42 @@ +// +// sprite.vsh +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +attribute mediump vec2 vertex_uv; +uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices +uniform mediump vec4 viewport; +uniform mediump float flare_size; + +varying mediump vec2 texCoord; + +void main() { + texCoord = vertex_uv; + gl_Position = mvp_matrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(vertex_uv.x * viewport.w / viewport.z * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 0.0) * flare_size; +} From 79abdd98d0f4e8340e19f145050cd288c58262b7 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 5 Dec 2013 01:09:31 -0800 Subject: [PATCH 36/43] Implemented rim_light and rim_power shader parameters, enabling outlining of objects on a per-model basis. Will need to later refactor to allow for a more scalable means of adding per-model shader attributes. --HG-- branch : nfb --- KREngine/kraken/KRAmbientZone.cpp | 3 +- KREngine/kraken/KRAudioSource.cpp | 3 +- KREngine/kraken/KRBone.cpp | 3 +- KREngine/kraken/KRCamera.cpp | 14 ++++++---- KREngine/kraken/KRCollider.cpp | 3 +- KREngine/kraken/KRDirectionalLight.cpp | 4 ++- KREngine/kraken/KRLight.cpp | 16 +++++++---- KREngine/kraken/KRMaterial.cpp | 7 ++--- KREngine/kraken/KRMaterial.h | 3 +- KREngine/kraken/KRMesh.cpp | 4 +-- KREngine/kraken/KRMesh.h | 2 +- KREngine/kraken/KRModel.cpp | 28 +++++++++++++++++-- KREngine/kraken/KRModel.h | 11 +++++++- KREngine/kraken/KRNode.cpp | 8 +++++- KREngine/kraken/KRParticleSystemNewtonian.cpp | 3 +- KREngine/kraken/KRPointLight.cpp | 4 +-- KREngine/kraken/KRReverbZone.cpp | 3 +- KREngine/kraken/KRScene.cpp | 7 ++++- KREngine/kraken/KRShader.cpp | 12 ++++++-- KREngine/kraken/KRShader.h | 4 ++- KREngine/kraken/KRShaderManager.cpp | 14 ++++++---- KREngine/kraken/KRShaderManager.h | 6 ++-- KREngine/kraken/KRSprite.cpp | 3 +- .../Shaders/ObjectShader.fsh | 22 ++++++++++++++- .../Shaders/ObjectShader.vsh | 14 ++++++++-- .../Shaders/ObjectShader_osx.fsh | 5 ++++ 26 files changed, 156 insertions(+), 50 deletions(-) diff --git a/KREngine/kraken/KRAmbientZone.cpp b/KREngine/kraken/KRAmbientZone.cpp index 5770fe0..fac94fb 100644 --- a/KREngine/kraken/KRAmbientZone.cpp +++ b/KREngine/kraken/KRAmbientZone.cpp @@ -97,7 +97,8 @@ void KRAmbientZone::render(KRCamera *pCamera, std::vector &point KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { // Enable additive blending GLDEBUG(glEnable(GL_BLEND)); diff --git a/KREngine/kraken/KRAudioSource.cpp b/KREngine/kraken/KRAudioSource.cpp index 094817d..dd1668a 100644 --- a/KREngine/kraken/KRAudioSource.cpp +++ b/KREngine/kraken/KRAudioSource.cpp @@ -209,7 +209,8 @@ void KRAudioSource::render(KRCamera *pCamera, std::vector &point KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_light; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass, rim_light, 0.0f)) { // Enable additive blending GLDEBUG(glEnable(GL_BLEND)); diff --git a/KREngine/kraken/KRBone.cpp b/KREngine/kraken/KRBone.cpp index 1b32c27..18b4a87 100644 --- a/KREngine/kraken/KRBone.cpp +++ b/KREngine/kraken/KRBone.cpp @@ -62,7 +62,8 @@ void KRBone::render(KRCamera *pCamera, std::vector &point_lights KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); if(sphereModels.size()) { for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index b997093..fb205a6 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -305,7 +305,8 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende } if(m_pSkyBoxTexture) { - getContext().getShaderManager()->selectShader("sky_box", *this, std::vector(), std::vector(), std::vector(), 0, m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE); + KRVector3 rim_color; + getContext().getShaderManager()->selectShader("sky_box", *this, std::vector(), std::vector(), std::vector(), 0, m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE, rim_color, 0.0f); getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture); @@ -472,8 +473,8 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende KRMat4 matModel = KRMat4(); matModel.scale((*itr).first.size() * 0.5f); matModel.translate((*itr).first.center()); - - if(getContext().getShaderManager()->selectShader(*this, pVisShader, m_viewport, matModel, std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*this, pVisShader, m_viewport, matModel, std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, rim_color, 0.0f)) { GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14)); } } @@ -682,7 +683,9 @@ void KRCamera::renderPost() GLDEBUG(glDisable(GL_DEPTH_TEST)); KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + + KRVector3 rim_color; + getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, rim_color, 0.0f); m_pContext->getTextureManager()->selectTexture(0, NULL); m_pContext->getTextureManager()->_setActiveTexture(0); @@ -884,7 +887,8 @@ void KRCamera::renderPost() GLDEBUG(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); KRShader *fontShader = m_pContext->getShaderManager()->getShader("debug_font", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - getContext().getShaderManager()->selectShader(*this, fontShader, m_viewport, KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + KRVector3 rim_color; + getContext().getShaderManager()->selectShader(*this, fontShader, m_viewport, KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, rim_color, 0.0f); m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font")); diff --git a/KREngine/kraken/KRCollider.cpp b/KREngine/kraken/KRCollider.cpp index b7dc674..ad7eba5 100644 --- a/KREngine/kraken/KRCollider.cpp +++ b/KREngine/kraken/KRCollider.cpp @@ -171,7 +171,8 @@ void KRCollider::render(KRCamera *pCamera, std::vector &point_li KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { // Enable additive blending GLDEBUG(glEnable(GL_BLEND)); diff --git a/KREngine/kraken/KRDirectionalLight.cpp b/KREngine/kraken/KRDirectionalLight.cpp index db78f9c..8e2e01b 100644 --- a/KREngine/kraken/KRDirectionalLight.cpp +++ b/KREngine/kraken/KRDirectionalLight.cpp @@ -105,8 +105,10 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector & light_direction_view_space = KRMat4::Dot(matModelViewInverseTranspose, light_direction_view_space); light_direction_view_space.normalize(); + KRVector3 rim_color; + KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, std::vector(), this_light, std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), std::vector(), this_light, std::vector(), 0, renderPass)) { + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), std::vector(), this_light, std::vector(), 0, renderPass, rim_color, 0.0f)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE, light_direction_view_space); pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, m_color); diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index 80a5e3d..79a303e 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -220,7 +220,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("dust_particle", pCamera, this_point_light, this_directional_light, this_spot_light, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, particleModelMatrix, this_point_light, this_directional_light, this_spot_light, 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, particleModelMatrix, this_point_light, this_directional_light, this_spot_light, 0, renderPass, rim_color, 0.0f)) { pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, m_color * pCamera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero())); @@ -256,8 +257,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light KRShader *pFogShader = m_pContext->getShaderManager()->getShader(shader_name, pCamera, this_point_light, this_directional_light, this_spot_light, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES); - - if(getContext().getShaderManager()->selectShader(*pCamera, pFogShader, viewport, KRMat4(), this_point_light, this_directional_light, this_spot_light, 0, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pFogShader, viewport, KRMat4(), this_point_light, this_directional_light, this_spot_light, 0, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, rim_color, 0.0f)) { int slice_count = (int)(pCamera->settings.volumetric_environment_quality * 495.0) + 5; float slice_near = -pCamera->settings.getPerspectiveNearZ(); @@ -285,7 +286,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light occlusion_test_sphere_matrix *= m_parentNode->getModelMatrix(); } - if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, point_lights, directional_lights, spot_lights, 0, viewport, occlusion_test_sphere_matrix, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, point_lights, directional_lights, spot_lights, 0, viewport, occlusion_test_sphere_matrix, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass, rim_color, 0.0f)) { GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery)); #if TARGET_OS_IPHONE @@ -332,7 +334,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light // Render light flare on transparency pass KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_light; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, rim_light, 0.0f)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, 1.0f); pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); @@ -449,7 +452,8 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera) // Use shader program KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", pCamera, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - getContext().getShaderManager()->selectShader(*pCamera, shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_SHADOWMAP); + KRVector3 rim_light; + getContext().getShaderManager()->selectShader(*pCamera, shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_SHADOWMAP, rim_light, 0.0f); getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true); diff --git a/KREngine/kraken/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index 3a29612..141f648 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -217,7 +217,7 @@ bool KRMaterial::isTransparent() { return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE; } -bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { +bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power) { bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; if(!m_pAmbientMap && m_ambientMap.size()) { @@ -251,10 +251,9 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_ligh bool bAlphaTest = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_TEST) && bDiffuseMap; bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - - KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, point_lights, directional_lights, spot_lights, bones.size(), bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_normalMapScale != default_scale && bNormalMap, m_reflectionMapScale != default_scale && bReflectionMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_normalMapOffset != default_offset && bNormalMap, m_reflectionMapOffset != default_offset && bReflectionMap, bAlphaTest, bAlphaBlend, renderPass); + KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, point_lights, directional_lights, spot_lights, bones.size(), bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_normalMapScale != default_scale && bNormalMap, m_reflectionMapScale != default_scale && bReflectionMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_normalMapOffset != default_offset && bNormalMap, m_reflectionMapOffset != default_offset && bReflectionMap, bAlphaTest, bAlphaBlend, renderPass, rim_power != 0.0f); - if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, 0, renderPass)) { + if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, rim_power)) { return false; } diff --git a/KREngine/kraken/KRMaterial.h b/KREngine/kraken/KRMaterial.h index 7b88eb8..ef6d9ee 100644 --- a/KREngine/kraken/KRMaterial.h +++ b/KREngine/kraken/KRMaterial.h @@ -37,6 +37,7 @@ #include "KRCamera.h" #include "KRResource.h" #include "KRVector2.h" +#include "KRVector3.h" #include "KRScene.h" #include "KRBone.h" @@ -83,7 +84,7 @@ public: bool isTransparent(); const std::string &getName() const; - bool bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); + bool bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power); bool needsVertexTangents(); diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index 7e0e88c..2cf0c2f 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -160,7 +160,7 @@ void KRMesh::loadPack(KRDataBlock *data) { updateAttributeOffsets(); } -void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones) { +void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones, const KRVector3 &rim_color, float rim_power) { //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); @@ -214,7 +214,7 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect for(int i=0; i < bones.size(); i++) { bone_bind_poses.push_back(getBoneBindPose(i)); } - if(pMaterial->bind(pCamera, point_lights, directional_lights, spot_lights, bones, bone_bind_poses, viewport, matModel, pLightMap, renderPass)) { + if(pMaterial->bind(pCamera, point_lights, directional_lights, spot_lights, bones, bone_bind_poses, viewport, matModel, pLightMap, renderPass, rim_color, rim_power)) { switch(pMaterial->getAlphaMode()) { case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index eecacc2..92e2162 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -109,7 +109,7 @@ public: std::vector > bone_weights; } mesh_info; - void render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones); + void render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones, const KRVector3 &rim_color, float rim_power); std::string m_lodBaseName; diff --git a/KREngine/kraken/KRModel.cpp b/KREngine/kraken/KRModel.cpp index 2c13800..a7bd54e 100644 --- a/KREngine/kraken/KRModel.cpp +++ b/KREngine/kraken/KRModel.cpp @@ -36,13 +36,15 @@ #include "KRMesh.h" #include "KRQuaternion.h" -KRModel::KRModel(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera) : KRNode(scene, instance_name) { +KRModel::KRModel(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera, KRVector3 rim_color, float rim_power) : KRNode(scene, instance_name) { m_lightMap = light_map; m_pLightMap = NULL; m_model_name = model_name; m_min_lod_coverage = lod_min_coverage; m_receivesShadow = receives_shadow; m_faces_camera = faces_camera; + m_rim_color = rim_color; + m_rim_power = rim_power; m_boundsCachedMat.c[0] = -1.0f; m_boundsCachedMat.c[1] = -1.0f; @@ -78,9 +80,31 @@ tinyxml2::XMLElement *KRModel::saveXML( tinyxml2::XMLNode *parent) e->SetAttribute("lod_min_coverage", m_min_lod_coverage); e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false"); e->SetAttribute("faces_camera", m_faces_camera ? "true" : "false"); + m_rim_color.setXMLAttribute("rim_color", e); + e->SetAttribute("rim_power", m_rim_power); return e; } +void KRModel::setRimColor(const const KRVector3 &rim_color) +{ + m_rim_color = rim_color; +} + +void KRModel::setRimPower(float rim_power) +{ + m_rim_power = rim_power; +} + +KRVector3 KRModel::getRimColor() +{ + return m_rim_color; +} + +float KRModel::getRimPower() +{ + return m_rim_power; +} + void KRModel::loadModel() { if(m_models.size() == 0) { std::vector models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first @@ -158,7 +182,7 @@ void KRModel::render(KRCamera *pCamera, std::vector &point_light matModel = KRQuaternion(KRVector3::Forward(), KRVector3::Normalize(camera_pos - model_center)).rotationMatrix() * matModel; } - pModel->render(getName(), pCamera, point_lights, directional_lights, spot_lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel]); + pModel->render(getName(), pCamera, point_lights, directional_lights, spot_lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel], m_rim_color, m_rim_power); } } } diff --git a/KREngine/kraken/KRModel.h b/KREngine/kraken/KRModel.h index c5fff37..25f46e0 100644 --- a/KREngine/kraken/KRModel.h +++ b/KREngine/kraken/KRModel.h @@ -51,7 +51,7 @@ class KRModel : public KRNode { public: - KRModel(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera); + KRModel(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera, KRVector3 rim_color = KRVector3::Zero(), float rim_power = 0.0f); virtual ~KRModel(); virtual std::string getElementName(); @@ -61,6 +61,11 @@ public: virtual KRAABB getBounds(); + void setRimColor(const const KRVector3 &rim_color); + void setRimPower(float rim_power); + KRVector3 getRimColor(); + float getRimPower(); + private: std::vector m_models; unordered_map > m_bones; // Outer std::map connects model to set of bones @@ -78,6 +83,10 @@ private: KRMat4 m_boundsCachedMat; KRAABB m_boundsCached; + + + KRVector3 m_rim_color; + float m_rim_power; }; diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index e8ac49e..ebbbeb2 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -420,7 +420,13 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { if(e->QueryBoolAttribute("faces_camera", &faces_camera) != tinyxml2::XML_SUCCESS) { faces_camera = false; } - new_node = new KRModel(scene, szName, e->Attribute("mesh"), e->Attribute("light_map"), lod_min_coverage, receives_shadow, faces_camera); + float rim_power = 0.0f; + if(e->QueryFloatAttribute("rim_power", &rim_power) != tinyxml2::XML_SUCCESS) { + rim_power = 0.0f; + } + KRVector3 rim_color = KRVector3::Zero(); + rim_color.getXMLAttribute("rim_color", e, KRVector3::Zero()); + new_node = new KRModel(scene, szName, e->Attribute("mesh"), e->Attribute("light_map"), lod_min_coverage, receives_shadow, faces_camera, rim_color, rim_power); } else if(strcmp(szElementName, "collider") == 0) { new_node = new KRCollider(scene, szName, e->Attribute("mesh"), 65535, 1.0f); } else if(strcmp(szElementName, "bone") == 0) { diff --git a/KREngine/kraken/KRParticleSystemNewtonian.cpp b/KREngine/kraken/KRParticleSystemNewtonian.cpp index f6bbdb5..89e9dc5 100644 --- a/KREngine/kraken/KRParticleSystemNewtonian.cpp +++ b/KREngine/kraken/KRParticleSystemNewtonian.cpp @@ -74,7 +74,8 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorgetShaderManager()->getShader("dust_particle", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); //m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); diff --git a/KREngine/kraken/KRPointLight.cpp b/KREngine/kraken/KRPointLight.cpp index db5a3d2..fd7cbce 100644 --- a/KREngine/kraken/KRPointLight.cpp +++ b/KREngine/kraken/KRPointLight.cpp @@ -69,8 +69,8 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &point_ bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->settings.getPerspectiveNearZ()) * (influence_radius + pCamera->settings.getPerspectiveNearZ()); KRShader *pShader = getContext().getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, this_light, std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, std::vector(), std::vector(), 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, std::vector(), std::vector(), 0, renderPass, rim_color, 0.0f)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, m_color); diff --git a/KREngine/kraken/KRReverbZone.cpp b/KREngine/kraken/KRReverbZone.cpp index a9f1ab5..95a4e95 100644 --- a/KREngine/kraken/KRReverbZone.cpp +++ b/KREngine/kraken/KRReverbZone.cpp @@ -96,7 +96,8 @@ void KRReverbZone::render(KRCamera *pCamera, std::vector &point_ KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { // Enable additive blending GLDEBUG(glEnable(GL_BLEND)); diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 4f04ad2..646debc 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -290,7 +290,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map &visi GLDEBUG(glDepthMask(GL_FALSE)); } - if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, point_lights, directional_lights, spot_lights, 0, viewport, matModel, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { + if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, point_lights, directional_lights, spot_lights, 0, viewport, matModel, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, KRVector3::Zero(), 0.0f)) { GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14)); m_pContext->getModelManager()->log_draw_call(renderPass, "octree", "occlusion_test", 14); } @@ -495,6 +495,11 @@ void KRScene::updateOctree(const KRViewport &viewport) if(node->lodIsVisible()) { m_nodeTree.update(node); } + if(node->hasPhysics()) { + m_physicsNodes.insert(node); + } else if(!node->hasPhysics()) { + m_physicsNodes.erase(node); + } } } diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index 210aae4..bdb2cef 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -101,7 +101,9 @@ const char *KRShader::KRENGINE_UNIFORM_NAMES[] = { "fog_density_premultiplied_squared", // KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED "slice_depth_scale", // KRENGINE_UNIFORM_SLICE_DEPTH_SCALE "particle_origin", // KRENGINE_UNIFORM_PARTICLE_ORIGIN - "bone_transforms" // KRENGINE_UNIFORM_BONE_TRANSFORMS + "bone_transforms", // KRENGINE_UNIFORM_BONE_TRANSFORMS + "rim_color", // KRENGINE_UNIFORM_RIM_COLOR + "rim_power" // KRENGINE_UNIFORM_RIM_POWER }; KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource) : KRContextObject(context) @@ -340,7 +342,7 @@ void KRShader::setUniform(int location, const KRMat4 &value) } } -bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass) { +bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass, const KRVector3 &rim_color, float rim_power) { if(m_iProgram == 0) { return false; } @@ -505,11 +507,15 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & ); } + // Rim highlighting parameters + setUniform(KRENGINE_UNIFORM_RIM_COLOR, rim_color); + setUniform(KRENGINE_UNIFORM_RIM_POWER, rim_power); + // Fog parameters setUniform(KRENGINE_UNIFORM_FOG_NEAR, camera.settings.fog_near); setUniform(KRENGINE_UNIFORM_FOG_FAR, camera.settings.fog_far); setUniform(KRENGINE_UNIFORM_FOG_DENSITY, camera.settings.fog_density); - setUniform(KRENGINE_UNIFORM_FOG_COLOR, camera.settings.fog_color); + setUniform(KRENGINE_UNIFORM_FOG_COLOR, camera.settings.fog_color); if(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE] != -1) { setUniform(KRENGINE_UNIFORM_FOG_SCALE, 1.0f / (camera.settings.fog_far - camera.settings.fog_near)); diff --git a/KREngine/kraken/KRShader.h b/KREngine/kraken/KRShader.h index 06e4fe2..f0cdccc 100644 --- a/KREngine/kraken/KRShader.h +++ b/KREngine/kraken/KRShader.h @@ -47,7 +47,7 @@ public: virtual ~KRShader(); const char *getKey() const; - bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass); + bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass, const KRVector3 &rim_color, float rim_power); enum { KRENGINE_UNIFORM_MATERIAL_AMBIENT = 0, @@ -114,6 +114,8 @@ public: KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRENGINE_UNIFORM_BONE_TRANSFORMS, + KRENGINE_UNIFORM_RIM_COLOR, + KRENGINE_UNIFORM_RIM_POWER, KRENGINE_NUM_UNIFORMS }; /* diff --git a/KREngine/kraken/KRShaderManager.cpp b/KREngine/kraken/KRShaderManager.cpp index 570f5ed..0cbe5d2 100644 --- a/KREngine/kraken/KRShaderManager.cpp +++ b/KREngine/kraken/KRShaderManager.cpp @@ -48,7 +48,7 @@ KRShaderManager::~KRShaderManager() { } -KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) { +KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass, bool bRimColor) { int iShadowQuality = 0; // FINDME - HACK - Placeholder code, need to iterate through lights and dynamically build shader @@ -114,6 +114,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p key.second.push_back(pCamera->settings.flash_intensity * 1000.0f); key.second.push_back(pCamera->settings.vignette_radius * 1000.0f); key.second.push_back(pCamera->settings.vignette_falloff * 1000.0f); + key.second.push_back(bRimColor); KRShader *pShader = m_shaders[key]; @@ -180,6 +181,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p stream << "\n#define ENABLE_AMBIENT " << (pCamera->settings.bEnableAmbient ? "1" : "0"); stream << "\n#define ENABLE_DIFFUSE " << (pCamera->settings.bEnableDiffuse ? "1" : "0"); stream << "\n#define ENABLE_SPECULAR " << (pCamera->settings.bEnableSpecular ? "1" : "0"); + stream << "\n#define ENABLE_RIM_COLOR " << (bRimColor ? "1" : "0"); stream << "\n#define FOG_TYPE " << pCamera->settings.fog_type; switch(renderPass) { case KRNode::RENDER_PASS_DEFERRED_GBUFFER: @@ -238,16 +240,16 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p return pShader; } -bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) +bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power) { - KRShader *pShader = getShader(shader_name, &camera, point_lights, directional_lights, spot_lights, bone_count, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bReflectionMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, bReflectionMapOffset, bAlphaTest, bAlphaBlend, renderPass); - return selectShader(camera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, bone_count, renderPass); + KRShader *pShader = getShader(shader_name, &camera, point_lights, directional_lights, spot_lights, bone_count, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bReflectionMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, bReflectionMapOffset, bAlphaTest, bAlphaBlend, renderPass, rim_power != 0.0f); + return selectShader(camera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, bone_count, renderPass, rim_color, rim_power); } -bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass) +bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass, const KRVector3 &rim_color, float rim_power) { if(pShader) { - return pShader->bind(camera, viewport, matModel, point_lights, directional_lights, spot_lights, renderPass); + return pShader->bind(camera, viewport, matModel, point_lights, directional_lights, spot_lights, renderPass, rim_color, rim_power); } else { return false; } diff --git a/KREngine/kraken/KRShaderManager.h b/KREngine/kraken/KRShaderManager.h index 1de85da..2615ecb 100644 --- a/KREngine/kraken/KRShaderManager.h +++ b/KREngine/kraken/KRShaderManager.h @@ -58,11 +58,11 @@ public: const std::string &getVertShaderSource(const std::string &name); - KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); + KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass, bool bRimColor = false); - bool selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass); + bool selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass, const KRVector3 &rim_color, float rim_power); - bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); + bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power); long getShaderHandlesUsed(); diff --git a/KREngine/kraken/KRSprite.cpp b/KREngine/kraken/KRSprite.cpp index 33807a0..3ee9d93 100644 --- a/KREngine/kraken/KRSprite.cpp +++ b/KREngine/kraken/KRSprite.cpp @@ -125,7 +125,8 @@ void KRSprite::render(KRCamera *pCamera, std::vector &point_ligh // Render light sprite on transparency pass KRShader *pShader = getContext().getShaderManager()->getShader("sprite", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { + KRVector3 rim_color; + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_spriteAlpha); pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_spriteSize); m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture); diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh index 71acfbc..3839980 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh @@ -27,6 +27,11 @@ #extension GL_EXT_shadow_samplers : require +#if ENABLE_RIM_COLOR == 1 + uniform lowp vec3 rim_color; + uniform mediump float rim_power; +#endif + #if FOG_TYPE > 0 // FOG_TYPE 1 - Linear // FOG_TYPE 2 - Exponential @@ -111,18 +116,27 @@ uniform sampler2D reflectionTexture; #endif + #if ENABLE_RIM_COLOR == 1 + #define NEED_EYEVEC + #endif + #if HAS_REFLECTION_CUBE_MAP == 1 uniform lowp vec3 material_reflection; uniform samplerCube reflectionCubeTexture; #if HAS_NORMAL_MAP == 1 varying highp mat3 tangent_to_world_matrix; - varying mediump vec3 eyeVec; + #define NEED_EYEVEC + uniform highp mat4 model_matrix; #else varying mediump vec3 reflectionVec; #endif #endif + #ifdef NEED_EYEVEC + varying mediump vec3 eyeVec; + #endif + #if SHADOW_QUALITY >= 1 #ifdef GL_EXT_shadow_samplers @@ -394,6 +408,12 @@ void main() #endif + #if ENABLE_RIM_COLOR == 1 + lowp float rim = 1.0 - clamp(dot(normalize(eyeVec), normal), 0.0, 1.0); + + gl_FragColor += vec4(rim_color, 1.0) * pow(rim, rim_power)); + #endif + #if BONE_COUNT > 0 gl_FragColor.b = 1.0; #endif diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh index 6d2b3fe..904a3a4 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh @@ -138,11 +138,14 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t varying mediump float specularFactor; #endif + #if ENABLE_RIM_COLOR == 1 + #define NEED_EYEVEC + #endif #if HAS_REFLECTION_CUBE_MAP == 1 #if HAS_NORMAL_MAP == 1 + #define NEED_EYEVEC uniform highp mat4 model_inverse_transpose_matrix; - varying mediump vec3 eyeVec; varying highp mat3 tangent_to_world_matrix; #else uniform highp mat4 model_matrix; @@ -150,6 +153,10 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t #endif #endif + #ifdef NEED_EYEVEC + varying mediump vec3 eyeVec; + #endif + #if HAS_DIFFUSE_MAP_SCALE == 1 uniform highp vec2 diffuseTexture_Scale; #endif @@ -246,7 +253,7 @@ void main() #if HAS_REFLECTION_CUBE_MAP == 1 #if HAS_NORMAL_MAP == 1 - eyeVec = normalize(camera_position_model_space - vertex_position_skinned); + #else // Calculate reflection vector as I - 2.0 * dot(N, I) * N mediump vec3 eyeVec = normalize(camera_position_model_space - vertex_position_skinned); @@ -255,6 +262,9 @@ void main() #endif #endif + #ifdef NEED_EYEVEC + eyeVec = normalize(camera_position_model_space - vertex_position_skinned); + #endif #if HAS_LIGHT_MAP == 1 // Pass shadow UV co-ordinates diff --git a/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh b/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh index bf70c98..25972be 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh @@ -27,6 +27,11 @@ // #extension GL_EXT_shadow_samplers : require +#if ENABLE_RIM_COLOR == 1 +uniform lowp vec3 rim_color; +uniform mediump float rim_power; +#endif + #if FOG_TYPE > 0 // FOG_TYPE 1 - Linear // FOG_TYPE 2 - Exponential From e5121e395840e2758186df0192c925df52f7c6b2 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 5 Dec 2013 01:17:30 -0800 Subject: [PATCH 37/43] Fixed syntax error in rim shader --HG-- branch : nfb --- KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh index 3839980..625f602 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh @@ -411,7 +411,7 @@ void main() #if ENABLE_RIM_COLOR == 1 lowp float rim = 1.0 - clamp(dot(normalize(eyeVec), normal), 0.0, 1.0); - gl_FragColor += vec4(rim_color, 1.0) * pow(rim, rim_power)); + gl_FragColor += vec4(rim_color, 1.0) * pow(rim, rim_power); #endif #if BONE_COUNT > 0 From fef872cc6dc37badc3b1e01188bb2d57c7f9a193 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 5 Dec 2013 15:54:28 -0800 Subject: [PATCH 38/43] updates to existing importer (bugs, etc.) and addition of importer audio objects skeleton code --HG-- branch : nfb --- KREngine/Kraken.xcodeproj/project.pbxproj | 32 ++++ KREngine/kraken/ImporterAudioLists.cpp | 212 ++++++++++++++++++++++ KREngine/kraken/ImporterAudioLists.h | 123 +++++++++++++ KREngine/kraken/KRResource+fbx.cpp | 4 + KREngine/kraken/simpleList.cpp | 87 +++++++++ KREngine/kraken/simpleList.h | 35 ++++ 6 files changed, 493 insertions(+) create mode 100644 KREngine/kraken/ImporterAudioLists.cpp create mode 100644 KREngine/kraken/ImporterAudioLists.h create mode 100644 KREngine/kraken/simpleList.cpp create mode 100644 KREngine/kraken/simpleList.h diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index eef1240..6bac602 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -10,6 +10,14 @@ 104A335E1672D31C001C8BA6 /* KRCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 104A335C1672D31B001C8BA6 /* KRCollider.cpp */; }; 104A335F1672D31C001C8BA6 /* KRCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = 104A335D1672D31C001C8BA6 /* KRCollider.h */; settings = {ATTRIBUTES = (); }; }; 10CC33A5168534F000BB9846 /* KRCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48B3CBF14393E2F000C50E2 /* KRCamera.cpp */; }; + 500CB1E5185113DA0097F31B /* simpleList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C531185111C600047FF8 /* simpleList.cpp */; }; + 500CB1E6185113E60097F31B /* ImporterAudioLists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */; }; + 500CB1ED185115280097F31B /* ImporterAudioLists.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EB185115280097F31B /* ImporterAudioLists.h */; }; + 500CB1EE185115280097F31B /* simpleList.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EC185115280097F31B /* simpleList.h */; }; + 500CB1F5185117600097F31B /* simpleList.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EC185115280097F31B /* simpleList.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 500CB1F61851176D0097F31B /* ImporterAudioLists.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EB185115280097F31B /* ImporterAudioLists.h */; }; + 50B6C533185111C600047FF8 /* ImporterAudioLists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */; }; + 50B6C535185111C600047FF8 /* simpleList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C531185111C600047FF8 /* simpleList.cpp */; }; E4030E4C160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (); }; }; E4030E4D160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (Public, ); }; }; E40BA45415EFF79500D7C3DD /* KRAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; }; @@ -408,6 +416,10 @@ 104A335C1672D31B001C8BA6 /* KRCollider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRCollider.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 104A335D1672D31C001C8BA6 /* KRCollider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRCollider.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 10CC33A3168530A300BB9846 /* libPVRTexLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPVRTexLib.a; path = Utilities/PVRTexLib/MacOS/libPVRTexLib.a; sourceTree = PVRSDK; }; + 500CB1EB185115280097F31B /* ImporterAudioLists.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImporterAudioLists.h; sourceTree = ""; }; + 500CB1EC185115280097F31B /* simpleList.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = simpleList.h; sourceTree = ""; }; + 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = ImporterAudioLists.cpp; sourceTree = ""; }; + 50B6C531185111C600047FF8 /* simpleList.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = simpleList.cpp; sourceTree = ""; }; E4030E4B160A3CF000592648 /* KRStockGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRStockGeometry.h; sourceTree = ""; }; E40BA45215EFF79500D7C3DD /* KRAABB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRAABB.cpp; sourceTree = ""; }; E40BA45315EFF79500D7C3DD /* KRAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRAABB.h; sourceTree = ""; }; @@ -708,6 +720,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 50B6C52E1851117A00047FF8 /* Audio Import */ = { + isa = PBXGroup; + children = ( + 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */, + 500CB1EB185115280097F31B /* ImporterAudioLists.h */, + 50B6C531185111C600047FF8 /* simpleList.cpp */, + 500CB1EC185115280097F31B /* simpleList.h */, + ); + name = "Audio Import"; + sourceTree = ""; + }; E414F9A21694D949000B3D58 /* Unknown */ = { isa = PBXGroup; children = ( @@ -1056,6 +1079,7 @@ E491016613C99B9E0098455B /* kraken */ = { isa = PBXGroup; children = ( + 50B6C52E1851117A00047FF8 /* Audio Import */, E4F9753815362A5200FD60B2 /* 3rdparty */, E488399915F92BA300BD66D5 /* Managers */, E461A173152E59DF00F2044A /* Math */, @@ -1259,6 +1283,7 @@ E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */, E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */, E4F975321536220900FD60B2 /* KRNode.h in Headers */, + 500CB1EE185115280097F31B /* simpleList.h in Headers */, E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */, E48C696F15374F5B00232E28 /* KRContext.h in Headers */, E46F4A0B155E002100CCF8B8 /* KRDataBlock.h in Headers */, @@ -1309,6 +1334,7 @@ E48CF944173453990005EBBB /* KRFloat.h in Headers */, E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */, E45134B81746A4A300443C21 /* KRBehavior.h in Headers */, + 500CB1ED185115280097F31B /* ImporterAudioLists.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1351,6 +1377,7 @@ E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */, E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */, + 500CB1F5185117600097F31B /* simpleList.h in Headers */, E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */, E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */, E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */, @@ -1394,6 +1421,7 @@ E48CF945173453990005EBBB /* KRFloat.h in Headers */, E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */, E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */, + 500CB1F61851176D0097F31B /* ImporterAudioLists.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1607,6 +1635,7 @@ E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */, E414BAE51435558900A668C4 /* KRModel.cpp in Sources */, E414BAE91435585A00A668C4 /* KRScene.cpp in Sources */, + 500CB1E5185113DA0097F31B /* simpleList.cpp in Sources */, E48B3CC014393E30000C50E2 /* KRCamera.cpp in Sources */, E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */, @@ -1632,6 +1661,7 @@ E4B175AC161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175B2161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, E4CA10E91637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, + 500CB1E6185113E60097F31B /* ImporterAudioLists.cpp in Sources */, E4CA10EF1637BD58005D9400 /* KRTextureTGA.cpp in Sources */, E4CA11781639CC90005D9400 /* KRViewport.cpp in Sources */, E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, @@ -1706,6 +1736,8 @@ E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */, E40F982D184A7A2700CFA4D8 /* KRMeshQuad.cpp in Sources */, E46F4A0F155E003000CCF8B8 /* KRDataBlock.cpp in Sources */, + 50B6C533185111C600047FF8 /* ImporterAudioLists.cpp in Sources */, + 50B6C535185111C600047FF8 /* simpleList.cpp in Sources */, E42CB1F1158446AB0066E0D8 /* KRQuaternion.cpp in Sources */, E4AFC6BB15F7C7D600DDB4C8 /* KROctreeNode.cpp in Sources */, E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */, diff --git a/KREngine/kraken/ImporterAudioLists.cpp b/KREngine/kraken/ImporterAudioLists.cpp new file mode 100644 index 0000000..5b1917a --- /dev/null +++ b/KREngine/kraken/ImporterAudioLists.cpp @@ -0,0 +1,212 @@ +// +// ImporterAudioLists.cpp +// + +#include "ImporterAudioLists.h" + +// +// (1) UTILITIES +void IMPORTER_AUDIO_UTILITIES() { } + +// +// Utility to convert a file code from a resource file into an object id +// will convert to +// H will convert to << 8 +// A will convert to << 16 +// A result of 0 implies a bad input code +// + +unsigned long codeToID(char *code) +{ + static char decode[64]; + size_t l = strlen(code); + if (l <= 0) return 0; // no code string + if (l > 63) l = 63; + int type = 0; + switch (code[l-1]) { + case 'A' : + case 'a' : + type = 8; + case 'H' : + case 'h' : + type += 8; + strncpy(decode, code, l-1); // (dst, src, maxlength) + decode[l-1] = 0; + break; + default : + strncpy(decode, code, l); + decode[l] = 0; + break; + }; + unsigned long id = strtol(decode, 0, 0); // (str, endptr, base) + id = id << type; + return id; +} + +// +// (2) ZONE CORNERS +void IMPORTER_AUDIO_ZONE_CORNERS() { } + +// +// (2a) A corners list for a given room/space + +void zoneRoomCornersList::addCorner(zoneCorner *c) +{ +} + +void zoneRoomCornersList::generateZones(simpleList *zonelist) +{ +} + +// +// (2b) A list of all the corners lists + +void zoneAllCornersList::addCorner(zoneCorner *c) +{ +} + +void zoneAllCornersList::generateSpheresFor(unsigned long id, simpleList *zonelist) +{ +} + +void zoneAllCornersList::generateSpheres(simpleList *zonelist) +{ +} + +// +// (3) RESOURCES +void IMPORTER_AUDIO_RESOURCES() { } + +bool zoneResourceList::load(char *path1, char *path2) +{ + return true; +} + +// +// (4) ZONE NODE MANAGER +void IMPORTER_AUDIO_MANAGER() { } + +zoneNodeManager::zoneNodeManager() +{ +} + +zoneNodeManager::~zoneNodeManager() +{ +} + +// (1) parse the resource files and create the resource list +bool zoneNodeManager::loadResources(char *path1, char *path2) +{ + return resources.load(path1, path2); +} + +// (2) given a locator add it to the correct list + +// +// insert vector table list into this space! + +bool addLocator_audioNode(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) +{ + return true; +} + +bool addLocator_ambientZone(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) +{ + return true; +} + +bool addLocator_reverbZone(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) +{ + return true; +} + +bool addLocator_ambientCorner(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) +{ + return true; +} + +bool addLocator_reverbCorner(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) +{ + return true; +} + +typedef bool (*addLocatorFunction)(zoneNodeManager *, char *, KRVector3, double); + +typedef struct { + const char *prefix; + unsigned long prefix_length; + addLocatorFunction function; +} addLocatorTableItem; + +addLocatorTableItem addLocatorVectorTable[] = { + { "AN_", 3, addLocator_audioNode }, + { "AZpoint_", 8, addLocator_ambientZone }, + { "RZpoint_", 8, addLocator_reverbZone }, + { "AZcorner_", 9, addLocator_ambientCorner }, + { "RZcorner_", 9, addLocator_reverbCorner }, + { NULL, 0, NULL }, +}; + +addLocatorTableItem *addLocator_findType(char *name) +{ + addLocatorTableItem *result = addLocatorVectorTable; + while (NULL != result->prefix) + { + if (0 == strncmp(result->prefix, name, result->prefix_length)) return result; + result++; + } + return NULL; +} + + +bool zoneNodeManager::addLocatorToAList(char *name, KRVector3 point, double radius) +{ + // (1) parse the name and add it to a list where appropriate + // AN__ is an audio node + // AZpoint__ is an audio zone point with a radius + // RZpoint_

_ is a reverb zone point with a radius + // AZcorner__ is a corner for an ambient zone + // RZcorner_

_ is a corner for a reverb zone + // + + addLocatorTableItem *item = addLocator_findType(name); + if (NULL != item) + { + //**** IN HERE we want to parse the args into the ID arg and the unique/order arg + //**** UPDATE (*addLocatorFunction) to handle the 'order' arg + char arg[AUDIO_IMPORTER_STRLEN]; + strncpy(arg, &name[item->prefix_length], AUDIO_IMPORTER_STRLEN-1); + arg[AUDIO_IMPORTER_STRLEN-1] = 0; + item->function(this, arg, point, radius); + return true; // return true if this is an audio locator that was added to a list + } + + return false; // return false if the FBX importer should handle the locator itself +} + +// (3) turn corner definitions into spheres +void zoneNodeManager::generateSpheresForAllZones() +{ + ambientCornersList.generateSpheres(&ambientZoneList); + reverbCornersList.generateSpheres(&reverbZoneList); +} + +// (4) output ambient zones +// (5) output reverb zones +// (6) output audio nodes (props) +bool zoneNodeManager::outputAmbientZones() +{ + return true; +} + +bool zoneNodeManager::outputReverbZones() +{ + return true; +} + +bool zoneNodeManager::outputAudioNodes() +{ + return true; +} + +// END OF ImporterAudioLists.cpp diff --git a/KREngine/kraken/ImporterAudioLists.h b/KREngine/kraken/ImporterAudioLists.h new file mode 100644 index 0000000..60274e5 --- /dev/null +++ b/KREngine/kraken/ImporterAudioLists.h @@ -0,0 +1,123 @@ +// +// ImporterAudioLists.h +// + +#ifndef _IMPORTER_AUDIO_LISTS_H_ +#define _IMPORTER_AUDIO_LISTS_H_ + +#include "KRVector3.h" +#include "simpleList.h" + +enum { + AUDIO_IMPORTER_STRLEN = 128 +}; + +// +// (1) Nodes and Dummy Props + +// A locator point +// AN__ + +struct audioPoint : public simpleListObject { + KRVector3 point; + char name[AUDIO_IMPORTER_STRLEN]; // this could change to a std::string +}; + +// +// (2) Zone Locators - for ambient zones and reverb zones + +// A zone sphere object +// RZpoint_

_ locRadius and AZpoint__ locRadius + +struct zone : public simpleListObject { + KRVector3 point; + double radius; + unsigned long id; +}; + +// A zone corner object +// RZcorner_

_ and AZcorner__ + +struct zoneCorner : public simpleListObject { + KRVector3 point; + unsigned long id; +}; + +// +// A list of corners for a particular location + +struct zoneRoomCornersList : public simpleListObject { + unsigned long id; + simpleList corners; // the zoneCorner objects for a given id + + void addCorner(zoneCorner *c); + // add it into the list in presorted place/location_number order starting bottom left and going clockwise + void generateZones(simpleList *zonelist); + // create a set of spheres that fill in the space defined by the corners + // and add these spheres to the 'zonelist' +}; + +// +// A master list of lists of corners + +struct zoneAllCornersList : public simpleList { + void addCorner(zoneCorner *c); + // find or create a zoneRoomCornersList for the incoming id, then use that list's addCorner() method + + void generateSpheresFor(unsigned long id, simpleList *zonelist); + void generateSpheres(simpleList *zonelist); + // routines to generate circle points for the geometery of a given place + location_number + // .. and to place these cirlces into a given zone list +}; + +// A resource object +//

or + +struct zoneResource : public simpleListObject { + unsigned long id; + char resource_name[AUDIO_IMPORTER_STRLEN]; +}; + +struct zoneResourceList : public simpleList { + bool load(char *path1, char *path2 = NULL); + // all resources are loaded into the same list from either 1 or 2 input files + // we can either put all the reverb and ambient info in 1 file, or split it across 2 files +}; + +// +// (3) Zone and Node Manager + +struct zoneNodeManager { + zoneResourceList resources; + + simpleList ambientZoneList; // list of 'zone' objects + zoneAllCornersList ambientCornersList; + + simpleList reverbZoneList; // list of 'zone' objects + zoneAllCornersList reverbCornersList; + + simpleList audioNodesList; // a list of 'audioPoint' objects + + zoneNodeManager(); + virtual ~zoneNodeManager(); + + // (1) parse the resource files and create the resource list + bool loadResources(char *path1, char *path2=NULL); // passed through to resources.load() + + // (2) given a locator add it to the correct list + bool addLocatorToAList(char *name, KRVector3 point, double radius); + + // (3) turn corner definitions into spheres + void generateSpheresForAllZones(); + + // (4) output ambient zones + // (5) output reverb zones + // (6) output audio nodes (props) + virtual bool outputAmbientZones(); + virtual bool outputReverbZones(); + virtual bool outputAudioNodes(); +}; + +#endif + +// END OF ImporterAudioLists.h diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index a327e39..36ccf10 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -1613,6 +1613,9 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { //**** HACK A BIT TO FIND OUT HOW IT WORKS const char *node_name = pNode->GetName(); + FbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); + KRVector3 node_translation = KRVector3(local_translation[0], local_translation[1], local_translation[2]); + // if(strncmp(node_name, "physics_collider_", strlen("physics_collider_")) == 0) { // // example hard coded compare // } @@ -1644,6 +1647,7 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { // // create_prop telegraph_radio dummyprop 94.371559 4.400661 31.469673 0.05 // - creates a reference point that the radio sound is 'located at' later in the script + // create_node mitchell_phone 22.7842 18.7481 9.1446 // // TO BE ADDED diff --git a/KREngine/kraken/simpleList.cpp b/KREngine/kraken/simpleList.cpp new file mode 100644 index 0000000..b7c8ee9 --- /dev/null +++ b/KREngine/kraken/simpleList.cpp @@ -0,0 +1,87 @@ +// +// simpleList.cpp +// + +#include "simpleList.h" + +simpleListObject::simpleListObject() { next = previous = NULL; } +simpleListObject::~simpleListObject() { } + +simpleList::simpleList() { + first = last = NULL; + nelements = 0; +}; + +simpleList::~simpleList() { while((first)) remove(first); } + +void simpleList::add(simpleListObject *elem, simpleListObject *after) { + if (NULL == elem) return; + if (NULL == first) { + first = last = elem; + elem->next = elem->previous = NULL; + } + else { + if (NULL == after) { after = last; } + if (last == after) { + elem->next = NULL; + elem->previous = last; + last->next = elem; + last = elem; + } + else { + elem->previous = after; + elem->next = after->next; + after->next->previous = elem; + after->next = elem; + } + } + nelements++; +} + +void simpleList::insert(simpleListObject *elem, simpleListObject *before) { + if (NULL == elem) return; + if (NULL == first) { + first = last = elem; + elem->next = elem->previous = NULL; + } + else { + if (NULL == before) { before = first; } + if (first == before) { + elem->previous = NULL; + elem->next = first; + first->previous = elem; + first = elem; + } + else { + elem->previous = before->previous; + elem->next = before; + before->previous->next = elem; + before->previous = elem; + } + } + nelements++; +} + +void simpleList::remove(simpleListObject *elem) { + if (0 == nelements) return; + if (NULL == elem) return; + if (NULL != elem->previous) elem->previous->next = elem->next; + if (NULL != elem->next) elem->next->previous = elem->previous; + if (elem == last) last = elem->previous; + if (elem == first) first = elem->next; + elem->previous = elem->next = NULL; + nelements--; +} + +simpleListObject *simpleList::findByIndex(unsigned long index) { + simpleListObject *result = NULL; + if (index < nelements) { + simpleListObject *current = first; + for (unsigned long i = 0; (i < index) && (NULL != current); i++) + current = current->next; + result = current; + } + return result; +} + +// END OF simpleList.cpp diff --git a/KREngine/kraken/simpleList.h b/KREngine/kraken/simpleList.h new file mode 100644 index 0000000..91081f6 --- /dev/null +++ b/KREngine/kraken/simpleList.h @@ -0,0 +1,35 @@ +// +// simpleList.h +// + +#ifndef _SIMPLE_LIST_OBJECTS_H_ +#define _SIMPLE_LIST_OBJECTS_H_ + +#include // include for pre c++11 defines + +struct simpleListObject { + simpleListObject *next; + simpleListObject *previous; + + simpleListObject(); + ~simpleListObject(); +}; // end of struct simpleListObject + +struct simpleList { + simpleListObject *first; + simpleListObject *last; + unsigned long nelements; + + simpleList(); + ~simpleList(); + + void add(simpleListObject *elem, simpleListObject *after=NULL); + void insert(simpleListObject *elem, simpleListObject *before=NULL); + void remove(simpleListObject *elem); + simpleListObject *findByIndex(unsigned long index); +}; // end of struct simpleList + +#endif + +// END OF simpleList.h + \ No newline at end of file From c9d489afab5f8c2cba3938e4c92a5d413f23c65c Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 5 Dec 2013 18:20:01 -0800 Subject: [PATCH 39/43] Implemented KRScene::getLocators() --HG-- branch : nfb --- KREngine/kraken/KRScene.cpp | 26 ++++++++++++++++++++------ KREngine/kraken/KRScene.h | 3 +++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 646debc..5e31dce 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -93,6 +93,11 @@ std::set &KRScene::getReverbZones() return m_reverbZoneNodes; } +std::set &KRScene::getLocators() +{ + return m_locatorNodes; +} + void KRScene::render(KRCamera *pCamera, unordered_map &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) { if(new_frame) { // Expire cached occlusion test results. @@ -460,6 +465,10 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode) if(ReverbZoneNode) { m_reverbZoneNodes.erase(ReverbZoneNode); } + KRLocator *locator = dynamic_cast(pNode); + if(locator) { + m_locatorNodes.erase(locator); + } m_modifiedNodes.erase(pNode); if(!m_newNodes.erase(pNode)) { m_nodeTree.remove(pNode); @@ -481,14 +490,19 @@ void KRScene::updateOctree(const KRViewport &viewport) if(node->hasPhysics()) { m_physicsNodes.insert(node); } - KRAmbientZone *AmbientZoneNode = dynamic_cast(node); - if(dynamic_cast(node)) { - m_ambientZoneNodes.insert(AmbientZoneNode); + KRAmbientZone *ambientZoneNode = dynamic_cast(node); + if(ambientZoneNode) { + m_ambientZoneNodes.insert(ambientZoneNode); } - KRReverbZone *ReverbZoneNode = dynamic_cast(node); - if(dynamic_cast(node)) { - m_reverbZoneNodes.insert(ReverbZoneNode); + KRReverbZone *reverbZoneNode = dynamic_cast(node); + if(reverbZoneNode) { + m_reverbZoneNodes.insert(reverbZoneNode); } + KRLocator *locatorNode = dynamic_cast(node); + if(locatorNode) { + m_locatorNodes.insert(locatorNode); + } + } for(std::set::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) { KRNode *node = *itr; diff --git a/KREngine/kraken/KRScene.h b/KREngine/kraken/KRScene.h index b8f5cab..9242a03 100644 --- a/KREngine/kraken/KRScene.h +++ b/KREngine/kraken/KRScene.h @@ -40,6 +40,7 @@ #include "KRCamera.h" #include "KRMeshManager.h" #include "KRNode.h" +#include "KRLocator.h" #include "KRAmbientZone.h" #include "KRReverbZone.h" #include "KROctree.h" @@ -84,6 +85,7 @@ public: std::set &getAmbientZones(); std::set &getReverbZones(); + std::set &getLocators(); private: @@ -98,6 +100,7 @@ private: std::set m_physicsNodes; std::set m_ambientZoneNodes; std::set m_reverbZoneNodes; + std::set m_locatorNodes; KROctree m_nodeTree; From 2a49523fd8e0ed71740807b5f242b259c7e4fdcd Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 5 Dec 2013 18:34:20 -0800 Subject: [PATCH 40/43] =?UTF-8?q?-=20I=20have=20replaced=20the=20lines=20i?= =?UTF-8?q?nserted=20in=20to=20KRResource+Fbx=20that=20look=20for=20?= =?UTF-8?q?=E2=80=9Ccollider=5Fso=5F=E2=80=9D=20with=20logic=20to=20look?= =?UTF-8?q?=20for=20=E2=80=9Ccollider=5F##=5F=E2=80=9D.=20=20This=20means?= =?UTF-8?q?=20that=20Jonny=20will=20need=20to=20name=20the=20flare=20heigh?= =?UTF-8?q?t=20colliders=20with=20a=20prefix=20of=20=E2=80=9Ccollider=5F16?= =?UTF-8?q?=5F=E2=80=9D=20in=20the=20Circa=201948=20project.=20-=20The=20c?= =?UTF-8?q?ode=20block=20starting=20with=20=E2=80=9CINTERRUPT=20THE=20NODE?= =?UTF-8?q?=20STUFF=20IN=20HERE=E2=80=9D=20has=20been=20moved=20to=20KRImp?= =?UTF-8?q?ort=20where=20it=20should=20occur.=20=20I=20have=20added=20an?= =?UTF-8?q?=20example=20in=20there=20on=20-=20Removed=20the=20comments,=20?= =?UTF-8?q?=E2=80=9C*****=20curves=201,=202,=20and=203=20are=20x,=20y,=20z?= =?UTF-8?q?=20translation=20..=20the=20first=20point=20holds=20the=20key?= =?UTF-8?q?=20frame=20in=20centimeters.=20=20POSSIBLE=20UPGRADE=20..=20gra?= =?UTF-8?q?b=20the=20key=20frame=20and=20output=20it=20as=20the=20start=20?= =?UTF-8?q?location=20to=20the=20kranimation=20file=E2=80=9D,=20as=20this?= =?UTF-8?q?=20is=20incorrect=20and=20misleading.=20=20You=20must=20never?= =?UTF-8?q?=20depend=20on=20the=20order=20of=20the=20curves=20in=20the=20F?= =?UTF-8?q?BX=20file.=20=20The=20exporting=20of=20the=20first=20point=20in?= =?UTF-8?q?=20the=20animation=20curve=20should=20be=20done=20in=20KRImport?= =?UTF-8?q?,=20after=20Kraken=20has=20already=20resolved=20the=20animation?= =?UTF-8?q?=20layers=20and=20attribute=20assignments=20using=20proper=20me?= =?UTF-8?q?tadata=20in=20the=20fbx=20file.=20=20You=20can=20do=20this=20us?= =?UTF-8?q?ing=20the=20existing=20Kraken=20API=20rather=20than=20modifying?= =?UTF-8?q?=20Kraken=20itself.=20=20In=20addition,=20we=20can=E2=80=99t=20?= =?UTF-8?q?make=20any=20assumptions=20based=20on=20the=20first=20keyframe?= =?UTF-8?q?=20time=20matching=20the=20animation=20start=20time.=20=20The?= =?UTF-8?q?=20actual=20animation=20start=20time=20is=20imported=20by=20Kra?= =?UTF-8?q?ken=20using=20the=20FBX=20fields=20that=20explicitly=20specify?= =?UTF-8?q?=20it.=20=20The=20reason=20we=20read=20animation=20start=20and?= =?UTF-8?q?=20end=20times=20from=20a=20text=20file=20is=20to=20split=20the?= =?UTF-8?q?=20animation=20into=20multiple=20animations=20from=20a=20single?= =?UTF-8?q?=20fbx=20file.=20=20KRImport=20can=20already=20export=20a=20sin?= =?UTF-8?q?gle=20animation=20from=20an=20fbx=20file=20automatically=20simp?= =?UTF-8?q?ly=20by=20not=20specifying=20an=20animation=20split=20file.=20-?= =?UTF-8?q?=20Removed=20comment,=20=E2=80=9C//=20****=20this=20is=20where?= =?UTF-8?q?=20the=20assert=20used=20to=20happen=E2=80=9D.=20=20This=20comm?= =?UTF-8?q?ent=20adds=20no=20value=20and=20is=20confusing=20to=20other=20K?= =?UTF-8?q?raken=20users,=20as=20the=20assert=20does=20not=20happen=20any?= =?UTF-8?q?=20more=20;-)=20-=20Removed=20comment,=20=E2=80=9C//=20KRNode?= =?UTF-8?q?=20*LoadMesh=20parses=20the=20"collider=20names"=20and=20then?= =?UTF-8?q?=20alters=20the=20attributes=20(NFB=20HACK)=E2=80=9D.=20=20I=20?= =?UTF-8?q?have=20refactored=20this=20code=20so=20this=20is=20no=20longer?= =?UTF-8?q?=20a=20hack.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --HG-- branch : nfb --- KREngine/Kraken.xcodeproj/project.pbxproj | 32 ---- KREngine/kraken/ImporterAudioLists.cpp | 212 ---------------------- KREngine/kraken/ImporterAudioLists.h | 123 ------------- KREngine/kraken/KRCollider.h | 1 - KREngine/kraken/KRResource+fbx.cpp | 121 ++---------- KREngine/kraken/simpleList.cpp | 87 --------- KREngine/kraken/simpleList.h | 35 ---- 7 files changed, 20 insertions(+), 591 deletions(-) delete mode 100644 KREngine/kraken/ImporterAudioLists.cpp delete mode 100644 KREngine/kraken/ImporterAudioLists.h delete mode 100644 KREngine/kraken/simpleList.cpp delete mode 100644 KREngine/kraken/simpleList.h diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index 6bac602..eef1240 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -10,14 +10,6 @@ 104A335E1672D31C001C8BA6 /* KRCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 104A335C1672D31B001C8BA6 /* KRCollider.cpp */; }; 104A335F1672D31C001C8BA6 /* KRCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = 104A335D1672D31C001C8BA6 /* KRCollider.h */; settings = {ATTRIBUTES = (); }; }; 10CC33A5168534F000BB9846 /* KRCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48B3CBF14393E2F000C50E2 /* KRCamera.cpp */; }; - 500CB1E5185113DA0097F31B /* simpleList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C531185111C600047FF8 /* simpleList.cpp */; }; - 500CB1E6185113E60097F31B /* ImporterAudioLists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */; }; - 500CB1ED185115280097F31B /* ImporterAudioLists.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EB185115280097F31B /* ImporterAudioLists.h */; }; - 500CB1EE185115280097F31B /* simpleList.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EC185115280097F31B /* simpleList.h */; }; - 500CB1F5185117600097F31B /* simpleList.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EC185115280097F31B /* simpleList.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 500CB1F61851176D0097F31B /* ImporterAudioLists.h in Headers */ = {isa = PBXBuildFile; fileRef = 500CB1EB185115280097F31B /* ImporterAudioLists.h */; }; - 50B6C533185111C600047FF8 /* ImporterAudioLists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */; }; - 50B6C535185111C600047FF8 /* simpleList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B6C531185111C600047FF8 /* simpleList.cpp */; }; E4030E4C160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (); }; }; E4030E4D160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (Public, ); }; }; E40BA45415EFF79500D7C3DD /* KRAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; }; @@ -416,10 +408,6 @@ 104A335C1672D31B001C8BA6 /* KRCollider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRCollider.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 104A335D1672D31C001C8BA6 /* KRCollider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRCollider.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 10CC33A3168530A300BB9846 /* libPVRTexLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPVRTexLib.a; path = Utilities/PVRTexLib/MacOS/libPVRTexLib.a; sourceTree = PVRSDK; }; - 500CB1EB185115280097F31B /* ImporterAudioLists.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImporterAudioLists.h; sourceTree = ""; }; - 500CB1EC185115280097F31B /* simpleList.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = simpleList.h; sourceTree = ""; }; - 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = ImporterAudioLists.cpp; sourceTree = ""; }; - 50B6C531185111C600047FF8 /* simpleList.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = simpleList.cpp; sourceTree = ""; }; E4030E4B160A3CF000592648 /* KRStockGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRStockGeometry.h; sourceTree = ""; }; E40BA45215EFF79500D7C3DD /* KRAABB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRAABB.cpp; sourceTree = ""; }; E40BA45315EFF79500D7C3DD /* KRAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRAABB.h; sourceTree = ""; }; @@ -720,17 +708,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 50B6C52E1851117A00047FF8 /* Audio Import */ = { - isa = PBXGroup; - children = ( - 50B6C52F185111C600047FF8 /* ImporterAudioLists.cpp */, - 500CB1EB185115280097F31B /* ImporterAudioLists.h */, - 50B6C531185111C600047FF8 /* simpleList.cpp */, - 500CB1EC185115280097F31B /* simpleList.h */, - ); - name = "Audio Import"; - sourceTree = ""; - }; E414F9A21694D949000B3D58 /* Unknown */ = { isa = PBXGroup; children = ( @@ -1079,7 +1056,6 @@ E491016613C99B9E0098455B /* kraken */ = { isa = PBXGroup; children = ( - 50B6C52E1851117A00047FF8 /* Audio Import */, E4F9753815362A5200FD60B2 /* 3rdparty */, E488399915F92BA300BD66D5 /* Managers */, E461A173152E59DF00F2044A /* Math */, @@ -1283,7 +1259,6 @@ E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */, E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */, E4F975321536220900FD60B2 /* KRNode.h in Headers */, - 500CB1EE185115280097F31B /* simpleList.h in Headers */, E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */, E48C696F15374F5B00232E28 /* KRContext.h in Headers */, E46F4A0B155E002100CCF8B8 /* KRDataBlock.h in Headers */, @@ -1334,7 +1309,6 @@ E48CF944173453990005EBBB /* KRFloat.h in Headers */, E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */, E45134B81746A4A300443C21 /* KRBehavior.h in Headers */, - 500CB1ED185115280097F31B /* ImporterAudioLists.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1377,7 +1351,6 @@ E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */, E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */, - 500CB1F5185117600097F31B /* simpleList.h in Headers */, E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */, E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */, E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */, @@ -1421,7 +1394,6 @@ E48CF945173453990005EBBB /* KRFloat.h in Headers */, E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */, E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */, - 500CB1F61851176D0097F31B /* ImporterAudioLists.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1635,7 +1607,6 @@ E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */, E414BAE51435558900A668C4 /* KRModel.cpp in Sources */, E414BAE91435585A00A668C4 /* KRScene.cpp in Sources */, - 500CB1E5185113DA0097F31B /* simpleList.cpp in Sources */, E48B3CC014393E30000C50E2 /* KRCamera.cpp in Sources */, E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */, @@ -1661,7 +1632,6 @@ E4B175AC161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175B2161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, E4CA10E91637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, - 500CB1E6185113E60097F31B /* ImporterAudioLists.cpp in Sources */, E4CA10EF1637BD58005D9400 /* KRTextureTGA.cpp in Sources */, E4CA11781639CC90005D9400 /* KRViewport.cpp in Sources */, E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, @@ -1736,8 +1706,6 @@ E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */, E40F982D184A7A2700CFA4D8 /* KRMeshQuad.cpp in Sources */, E46F4A0F155E003000CCF8B8 /* KRDataBlock.cpp in Sources */, - 50B6C533185111C600047FF8 /* ImporterAudioLists.cpp in Sources */, - 50B6C535185111C600047FF8 /* simpleList.cpp in Sources */, E42CB1F1158446AB0066E0D8 /* KRQuaternion.cpp in Sources */, E4AFC6BB15F7C7D600DDB4C8 /* KROctreeNode.cpp in Sources */, E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */, diff --git a/KREngine/kraken/ImporterAudioLists.cpp b/KREngine/kraken/ImporterAudioLists.cpp deleted file mode 100644 index 5b1917a..0000000 --- a/KREngine/kraken/ImporterAudioLists.cpp +++ /dev/null @@ -1,212 +0,0 @@ -// -// ImporterAudioLists.cpp -// - -#include "ImporterAudioLists.h" - -// -// (1) UTILITIES -void IMPORTER_AUDIO_UTILITIES() { } - -// -// Utility to convert a file code from a resource file into an object id -// will convert to -// H will convert to << 8 -// A will convert to << 16 -// A result of 0 implies a bad input code -// - -unsigned long codeToID(char *code) -{ - static char decode[64]; - size_t l = strlen(code); - if (l <= 0) return 0; // no code string - if (l > 63) l = 63; - int type = 0; - switch (code[l-1]) { - case 'A' : - case 'a' : - type = 8; - case 'H' : - case 'h' : - type += 8; - strncpy(decode, code, l-1); // (dst, src, maxlength) - decode[l-1] = 0; - break; - default : - strncpy(decode, code, l); - decode[l] = 0; - break; - }; - unsigned long id = strtol(decode, 0, 0); // (str, endptr, base) - id = id << type; - return id; -} - -// -// (2) ZONE CORNERS -void IMPORTER_AUDIO_ZONE_CORNERS() { } - -// -// (2a) A corners list for a given room/space - -void zoneRoomCornersList::addCorner(zoneCorner *c) -{ -} - -void zoneRoomCornersList::generateZones(simpleList *zonelist) -{ -} - -// -// (2b) A list of all the corners lists - -void zoneAllCornersList::addCorner(zoneCorner *c) -{ -} - -void zoneAllCornersList::generateSpheresFor(unsigned long id, simpleList *zonelist) -{ -} - -void zoneAllCornersList::generateSpheres(simpleList *zonelist) -{ -} - -// -// (3) RESOURCES -void IMPORTER_AUDIO_RESOURCES() { } - -bool zoneResourceList::load(char *path1, char *path2) -{ - return true; -} - -// -// (4) ZONE NODE MANAGER -void IMPORTER_AUDIO_MANAGER() { } - -zoneNodeManager::zoneNodeManager() -{ -} - -zoneNodeManager::~zoneNodeManager() -{ -} - -// (1) parse the resource files and create the resource list -bool zoneNodeManager::loadResources(char *path1, char *path2) -{ - return resources.load(path1, path2); -} - -// (2) given a locator add it to the correct list - -// -// insert vector table list into this space! - -bool addLocator_audioNode(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) -{ - return true; -} - -bool addLocator_ambientZone(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) -{ - return true; -} - -bool addLocator_reverbZone(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) -{ - return true; -} - -bool addLocator_ambientCorner(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) -{ - return true; -} - -bool addLocator_reverbCorner(zoneNodeManager *manager, char *idstring, KRVector3 where, double radius) -{ - return true; -} - -typedef bool (*addLocatorFunction)(zoneNodeManager *, char *, KRVector3, double); - -typedef struct { - const char *prefix; - unsigned long prefix_length; - addLocatorFunction function; -} addLocatorTableItem; - -addLocatorTableItem addLocatorVectorTable[] = { - { "AN_", 3, addLocator_audioNode }, - { "AZpoint_", 8, addLocator_ambientZone }, - { "RZpoint_", 8, addLocator_reverbZone }, - { "AZcorner_", 9, addLocator_ambientCorner }, - { "RZcorner_", 9, addLocator_reverbCorner }, - { NULL, 0, NULL }, -}; - -addLocatorTableItem *addLocator_findType(char *name) -{ - addLocatorTableItem *result = addLocatorVectorTable; - while (NULL != result->prefix) - { - if (0 == strncmp(result->prefix, name, result->prefix_length)) return result; - result++; - } - return NULL; -} - - -bool zoneNodeManager::addLocatorToAList(char *name, KRVector3 point, double radius) -{ - // (1) parse the name and add it to a list where appropriate - // AN__ is an audio node - // AZpoint__ is an audio zone point with a radius - // RZpoint_

_ is a reverb zone point with a radius - // AZcorner__ is a corner for an ambient zone - // RZcorner_

_ is a corner for a reverb zone - // - - addLocatorTableItem *item = addLocator_findType(name); - if (NULL != item) - { - //**** IN HERE we want to parse the args into the ID arg and the unique/order arg - //**** UPDATE (*addLocatorFunction) to handle the 'order' arg - char arg[AUDIO_IMPORTER_STRLEN]; - strncpy(arg, &name[item->prefix_length], AUDIO_IMPORTER_STRLEN-1); - arg[AUDIO_IMPORTER_STRLEN-1] = 0; - item->function(this, arg, point, radius); - return true; // return true if this is an audio locator that was added to a list - } - - return false; // return false if the FBX importer should handle the locator itself -} - -// (3) turn corner definitions into spheres -void zoneNodeManager::generateSpheresForAllZones() -{ - ambientCornersList.generateSpheres(&ambientZoneList); - reverbCornersList.generateSpheres(&reverbZoneList); -} - -// (4) output ambient zones -// (5) output reverb zones -// (6) output audio nodes (props) -bool zoneNodeManager::outputAmbientZones() -{ - return true; -} - -bool zoneNodeManager::outputReverbZones() -{ - return true; -} - -bool zoneNodeManager::outputAudioNodes() -{ - return true; -} - -// END OF ImporterAudioLists.cpp diff --git a/KREngine/kraken/ImporterAudioLists.h b/KREngine/kraken/ImporterAudioLists.h deleted file mode 100644 index 60274e5..0000000 --- a/KREngine/kraken/ImporterAudioLists.h +++ /dev/null @@ -1,123 +0,0 @@ -// -// ImporterAudioLists.h -// - -#ifndef _IMPORTER_AUDIO_LISTS_H_ -#define _IMPORTER_AUDIO_LISTS_H_ - -#include "KRVector3.h" -#include "simpleList.h" - -enum { - AUDIO_IMPORTER_STRLEN = 128 -}; - -// -// (1) Nodes and Dummy Props - -// A locator point -// AN__ - -struct audioPoint : public simpleListObject { - KRVector3 point; - char name[AUDIO_IMPORTER_STRLEN]; // this could change to a std::string -}; - -// -// (2) Zone Locators - for ambient zones and reverb zones - -// A zone sphere object -// RZpoint_

_ locRadius and AZpoint__ locRadius - -struct zone : public simpleListObject { - KRVector3 point; - double radius; - unsigned long id; -}; - -// A zone corner object -// RZcorner_

_ and AZcorner__ - -struct zoneCorner : public simpleListObject { - KRVector3 point; - unsigned long id; -}; - -// -// A list of corners for a particular location - -struct zoneRoomCornersList : public simpleListObject { - unsigned long id; - simpleList corners; // the zoneCorner objects for a given id - - void addCorner(zoneCorner *c); - // add it into the list in presorted place/location_number order starting bottom left and going clockwise - void generateZones(simpleList *zonelist); - // create a set of spheres that fill in the space defined by the corners - // and add these spheres to the 'zonelist' -}; - -// -// A master list of lists of corners - -struct zoneAllCornersList : public simpleList { - void addCorner(zoneCorner *c); - // find or create a zoneRoomCornersList for the incoming id, then use that list's addCorner() method - - void generateSpheresFor(unsigned long id, simpleList *zonelist); - void generateSpheres(simpleList *zonelist); - // routines to generate circle points for the geometery of a given place + location_number - // .. and to place these cirlces into a given zone list -}; - -// A resource object -//

or - -struct zoneResource : public simpleListObject { - unsigned long id; - char resource_name[AUDIO_IMPORTER_STRLEN]; -}; - -struct zoneResourceList : public simpleList { - bool load(char *path1, char *path2 = NULL); - // all resources are loaded into the same list from either 1 or 2 input files - // we can either put all the reverb and ambient info in 1 file, or split it across 2 files -}; - -// -// (3) Zone and Node Manager - -struct zoneNodeManager { - zoneResourceList resources; - - simpleList ambientZoneList; // list of 'zone' objects - zoneAllCornersList ambientCornersList; - - simpleList reverbZoneList; // list of 'zone' objects - zoneAllCornersList reverbCornersList; - - simpleList audioNodesList; // a list of 'audioPoint' objects - - zoneNodeManager(); - virtual ~zoneNodeManager(); - - // (1) parse the resource files and create the resource list - bool loadResources(char *path1, char *path2=NULL); // passed through to resources.load() - - // (2) given a locator add it to the correct list - bool addLocatorToAList(char *name, KRVector3 point, double radius); - - // (3) turn corner definitions into spheres - void generateSpheresForAllZones(); - - // (4) output ambient zones - // (5) output reverb zones - // (6) output audio nodes (props) - virtual bool outputAmbientZones(); - virtual bool outputReverbZones(); - virtual bool outputAudioNodes(); -}; - -#endif - -// END OF ImporterAudioLists.h diff --git a/KREngine/kraken/KRCollider.h b/KREngine/kraken/KRCollider.h index 5c68693..cabf368 100644 --- a/KREngine/kraken/KRCollider.h +++ b/KREngine/kraken/KRCollider.h @@ -36,7 +36,6 @@ #define KRAKEN_COLLIDER_PHYSICS 1 #define KRAKEN_COLLIDER_AUDIO 2 -#define KRAKEN_COLLIDER_INTERACTABLE 16 // ADDED Dec 3, 2013 by Peter for collider_so layer mask type #include "KRMesh.h" #include "KRMat4.h" diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 36ccf10..002a48a 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -141,15 +141,12 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) FbxAnimCurve *curve = pFbxScene->GetSrcObject(i); printf(" Animation Curve %i of %i: %s\n", i+1, curve_count, curve->GetName()); KRAnimationCurve *new_curve = LoadAnimationCurve(context, curve); - - //***** curves 1, 2, and 3 are x, y, z translation .. the first point holds the key frame in centimeters - // POSSIBLE UPGRADE .. grab the key frame and output it as the start location to the kranimation file - + if(new_curve) { printf("Adding a curve\n"); context.getAnimationCurveManager()->addAnimationCurve(new_curve); } - } + } // ----====---- Import Materials ----====---- int material_count = pFbxScene->GetSrcObjectCount(); @@ -601,11 +598,12 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG FbxAnimStack* pAnimStack = pFbxScene->GetSrcObject(i); KRAnimation *pAnimation = parent_node->getContext().getAnimationManager()->getAnimation(pAnimStack->GetName()); if(pAnimation) { - int cLayers = pAnimStack->GetMemberCount(); + int cLayers = pAnimStack->GetMemberCount(); for(int iLayer=0; iLayer < cLayers; iLayer++) { FbxAnimLayer *pFbxAnimLayer = pAnimStack->GetMember(iLayer); // float weight = pFbxAnimLayer->Weight.Get(); KRAnimationLayer *pAnimationLayer = pAnimation->getLayer(pFbxAnimLayer->GetName()); + FbxAnimCurve *pAnimCurve = pNode->LclRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); if(pAnimCurve) { KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); @@ -1023,7 +1021,6 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG switch(attribute_type) { case FbxNodeAttribute::eMesh: new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode); - // KRNode *LoadMesh parses the "collider names" and then alters the attributes (NFB HACK) break; case FbxNodeAttribute::eLight: new_node = LoadLight(parent_node, pNode); @@ -1470,7 +1467,6 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe FbxVector2 uv; bool unmapped = false; if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { - // **** this is where the assert used to happen if(!unmapped) { new_uva = KRVector2(uv[0], uv[1]); } @@ -1563,22 +1559,29 @@ KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter std::string light_map = pNode->GetName(); light_map.append("_lightmap"); -//FINDME - THIS IS WHERE THE collider in house names are parsed and handled .. and then the collider_ names are done -// in CircaViewController.mm postLoadSetup .. with the addition of KRAKEN_COLLIDER_INTERACTABLE the postLoadSetup is redundant. -// - // FINDME, HACK - Until we have a GUI, we're using prefixes to select correct object type const char *node_name = pNode->GetName(); if(strncmp(node_name, "physics_collider_", strlen("physics_collider_")) == 0) { return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_PHYSICS, 0.0f); } else if(strncmp(node_name, "audio_collider_", strlen("audio_collider_")) == 0) { return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_AUDIO, 1.0f); - } else if(0 == strncmp(node_name, "collider_so_", strlen("collider_so_"))) { - // ADDED Dec 3, 2013 by Peter to handle the scene object colliders that are layerMask 'Interactable' (16) - return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_INTERACTABLE, 1.0f); - } else if(strncmp(node_name, "collider_", strlen("collider_")) == 0) { + } else if(strncmp(node_name, "collider_", 9) == 0) { // 9 == strlen("collider_") + // Colliders can have a prefix of collider_##_, where ## indicates the layer mask + // Colliders with a prefix of only collider_ will have a default layer mask of KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO - return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO, 1.0f); + // Scan through the characters of the name until we no longer see digit characters (or see a '\0' indicating the end of the string) + unsigned int layer = 0; + char *szNodeName = node_name.c_str() + 9; // 9 == strlen("collider_") + char *source_char = szNodeName; + while(*source_char >= '0' && *source_char <= '9') { + layer = layer * 10 + (*source_char++ - '0'); + } + + if(layer == 0) { + // No layer mask number was found, use the default + layer = KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO; + } + return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), layer, 1.0f); } else { return new KRModel(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), light_map, 0.0f, true, false); } @@ -1605,90 +1608,6 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { std::string name = GetFbxObjectName(pNode); -//**** INTERUPT THE NODE STUFF IN HERE -// we can parse the name, look for our special naming conventions, and then route stuff -// either through to the normal locator block within the scene, or we can dump it out -// to another destination .. a script file, an xml file, whatever we need. -//**** - - //**** HACK A BIT TO FIND OUT HOW IT WORKS - const char *node_name = pNode->GetName(); - FbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); - KRVector3 node_translation = KRVector3(local_translation[0], local_translation[1], local_translation[2]); - -// if(strncmp(node_name, "physics_collider_", strlen("physics_collider_")) == 0) { -// // example hard coded compare -// } - // - // Place all the zone markers at listening (head) height - // - // is a number with the letter 'H' (hotel) or 'A' (alley) at the end of it - // - // KRReverbZone .. see CircaActorStep_CreateReverbZone::execute - // RZcorner_ .. with no meta data - // RZpoint_ .. with meta data locRadius - // - // KRAmbientZone .. see CircaActorStep_CreateAmbientZone::execute - // AZcorner_ .. all ambient sounds will be numbered somewhere in a master sound list file - // AZpoint_ .. with meta data locRadius - // - // KRModel .. see CircaActorStep_CreateDummyProp::execute - // AN_ .. an audio prop location that can be referenced by name in a trigger script - // - // QUESTION - should we do AN__ - // and then trigger the sound by activating the prop point (i.e. the sound file is already associated with the point) - // but the dummy prop doesn't have anywhere to store the sound file name - // - - // This is how it's done in the actor files .. - // - // create_ambient_zone entrance_ambient_zone entrance 99.0728 2.9885 -35.3381 10.0 10.0 10.0 0.25 p1_s1.0_1_traffic_general_loop 1.0 - // create_reverb_zone telegraph_office_reverb_zone telegraph_office -53.3345 3.58721 58.2977 20.0 20.0 20.0 0.25 reverb_telegraph 1.0 - // - // create_prop telegraph_radio dummyprop 94.371559 4.400661 31.469673 0.05 - // - creates a reference point that the radio sound is 'located at' later in the script - // create_node mitchell_phone 22.7842 18.7481 9.1446 - // - - // TO BE ADDED - // - // bool GetDoubleProperty(const char **match_list, double &value); - // pass in a c-string array of case insensitive property names that are all treated as identical - // return true if the property is found - // i.e. if(GetDoubleProperty({"locradius","radius",NULL}, value)) .. - // - - // TO BE ADDED - // - // bool ParseLocator(FbxNode* pNode); - // returns true is we should add the locator to the scene and false otherwise - // parses the locator and either returns it to be added to the scene or sends it somewhere else - // somewhere else would be: ambient_zone, reverb_zone, dummy_prop - // - - FbxProperty myprop = pNode->FindProperty("locRadius", true); // (name, is_case_sensitive) - if (myprop.IsValid()) { - printf("locRadius found!\n"); - FbxDataType pdt = myprop.GetPropertyDataType(); - EFbxType ptype= pdt.GetType(); - if (eFbxDouble == ptype) { - double radius = myprop.Get(); - printf("The radius is %3.4f\n", radius); - } - } - - // FbxProperty p = GetFirstProperty(); - // p = GetNextProperty(p); - // if (p.IsValid()) .. - // FbxDataType pdt = p.GetPropertyDataType(); - // EFbxType = pdt.GetType(); // this is an enumerated type - // FbxString pname = p.GetName(); - // const char * s = p.GetNameAsCStr(); // owned by the fbx library - - - - //**** END OF HACK - KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str()); //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); diff --git a/KREngine/kraken/simpleList.cpp b/KREngine/kraken/simpleList.cpp deleted file mode 100644 index b7c8ee9..0000000 --- a/KREngine/kraken/simpleList.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// simpleList.cpp -// - -#include "simpleList.h" - -simpleListObject::simpleListObject() { next = previous = NULL; } -simpleListObject::~simpleListObject() { } - -simpleList::simpleList() { - first = last = NULL; - nelements = 0; -}; - -simpleList::~simpleList() { while((first)) remove(first); } - -void simpleList::add(simpleListObject *elem, simpleListObject *after) { - if (NULL == elem) return; - if (NULL == first) { - first = last = elem; - elem->next = elem->previous = NULL; - } - else { - if (NULL == after) { after = last; } - if (last == after) { - elem->next = NULL; - elem->previous = last; - last->next = elem; - last = elem; - } - else { - elem->previous = after; - elem->next = after->next; - after->next->previous = elem; - after->next = elem; - } - } - nelements++; -} - -void simpleList::insert(simpleListObject *elem, simpleListObject *before) { - if (NULL == elem) return; - if (NULL == first) { - first = last = elem; - elem->next = elem->previous = NULL; - } - else { - if (NULL == before) { before = first; } - if (first == before) { - elem->previous = NULL; - elem->next = first; - first->previous = elem; - first = elem; - } - else { - elem->previous = before->previous; - elem->next = before; - before->previous->next = elem; - before->previous = elem; - } - } - nelements++; -} - -void simpleList::remove(simpleListObject *elem) { - if (0 == nelements) return; - if (NULL == elem) return; - if (NULL != elem->previous) elem->previous->next = elem->next; - if (NULL != elem->next) elem->next->previous = elem->previous; - if (elem == last) last = elem->previous; - if (elem == first) first = elem->next; - elem->previous = elem->next = NULL; - nelements--; -} - -simpleListObject *simpleList::findByIndex(unsigned long index) { - simpleListObject *result = NULL; - if (index < nelements) { - simpleListObject *current = first; - for (unsigned long i = 0; (i < index) && (NULL != current); i++) - current = current->next; - result = current; - } - return result; -} - -// END OF simpleList.cpp diff --git a/KREngine/kraken/simpleList.h b/KREngine/kraken/simpleList.h deleted file mode 100644 index 91081f6..0000000 --- a/KREngine/kraken/simpleList.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// simpleList.h -// - -#ifndef _SIMPLE_LIST_OBJECTS_H_ -#define _SIMPLE_LIST_OBJECTS_H_ - -#include // include for pre c++11 defines - -struct simpleListObject { - simpleListObject *next; - simpleListObject *previous; - - simpleListObject(); - ~simpleListObject(); -}; // end of struct simpleListObject - -struct simpleList { - simpleListObject *first; - simpleListObject *last; - unsigned long nelements; - - simpleList(); - ~simpleList(); - - void add(simpleListObject *elem, simpleListObject *after=NULL); - void insert(simpleListObject *elem, simpleListObject *before=NULL); - void remove(simpleListObject *elem); - simpleListObject *findByIndex(unsigned long index); -}; // end of struct simpleList - -#endif - -// END OF simpleList.h - \ No newline at end of file From f1d23de23f24eb82766d43418356af816fa9b109 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 5 Dec 2013 18:46:48 -0800 Subject: [PATCH 41/43] Fixed compilation failure of fbx importer pipeline. --HG-- branch : nfb --- KREngine/kraken/KRResource+fbx.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 002a48a..98cecab 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -1571,8 +1571,8 @@ KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter // Scan through the characters of the name until we no longer see digit characters (or see a '\0' indicating the end of the string) unsigned int layer = 0; - char *szNodeName = node_name.c_str() + 9; // 9 == strlen("collider_") - char *source_char = szNodeName; + const char *szNodeName = node_name + 9; // 9 == strlen("collider_") + const char *source_char = szNodeName; while(*source_char >= '0' && *source_char <= '9') { layer = layer * 10 + (*source_char++ - '0'); } From 5b708fa1cd2023f2498767adc9251e0465b2b73d Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 5 Dec 2013 19:44:58 -0800 Subject: [PATCH 42/43] Implemented KRLocator::getUserAttributes(), which returns a list of additional properties enumerated from fbx files so client code can convert locators into application-specific objects --HG-- branch : nfb --- KREngine/kraken/KRLocator.cpp | 5 +++++ KREngine/kraken/KRLocator.h | 7 +++++- KREngine/kraken/KRResource+fbx.cpp | 35 ++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/KREngine/kraken/KRLocator.cpp b/KREngine/kraken/KRLocator.cpp index 1794062..694cbe2 100644 --- a/KREngine/kraken/KRLocator.cpp +++ b/KREngine/kraken/KRLocator.cpp @@ -33,3 +33,8 @@ void KRLocator::loadXML(tinyxml2::XMLElement *e) { KRNode::loadXML(e); } + +unordered_map > &KRLocator::getUserAttributes() +{ + return m_userAttributes; +} \ No newline at end of file diff --git a/KREngine/kraken/KRLocator.h b/KREngine/kraken/KRLocator.h index 19e6f22..b2c0a64 100644 --- a/KREngine/kraken/KRLocator.h +++ b/KREngine/kraken/KRLocator.h @@ -13,6 +13,8 @@ #include "KRNode.h" #include "KRTexture.h" +#include "boost/variant.hpp" + class KRLocator : public KRNode { public: KRLocator(KRScene &scene, std::string name); @@ -20,7 +22,10 @@ public: virtual std::string getElementName(); virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual void loadXML(tinyxml2::XMLElement *e); - + unordered_map > &getUserAttributes(); + +private: + unordered_map > m_userAttributes; }; diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 98cecab..ed68086 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -9,6 +9,7 @@ #include "KREngine-common.h" #include #include +#include #include @@ -1610,6 +1611,40 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str()); + // Enumerate fbx properties so client code can convert locators into application-specific objects + FbxProperty fbx_property = pNode->GetFirstProperty(); + while(fbx_property.IsValid()) { + std::string property_name = fbx_property.GetNameAsCStr(); + boost::variant property_value = ""; + switch(fbx_property.GetPropertyDataType().GetType()) { + case eFbxInt: + property_value = fbx_property.Get(); + break; + case eFbxDouble: + property_value = fbx_property.Get(); + break; + case eFbxBool: + property_value = fbx_property.Get(); + break; + case eFbxFloat: + property_value = fbx_property.Get(); + break; + case eFbxString: + property_value = std::string(fbx_property.Get().Buffer()); + break; + default: + { + fprintf(stderr, "FBX property not imported due to unsupported data type: %s.%s\n", name.c_str(), property_name.c_str()); + } + break; + } + + std::transform(property_name.begin(), property_name.end(), property_name.begin(), ::tolower); + + new_locator->getUserAttributes()[property_name] = property_value; + } + + //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); // PoseList pose_list; // FbxArray pose_indices; From d4f16439fc524040c4b7864bf18651b4fc88bfc7 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 5 Dec 2013 20:15:32 -0800 Subject: [PATCH 43/43] No longer filling KRLocator::m_userAttributes with fbx properties that had unsupported data types --HG-- branch : nfb --- KREngine/kraken/KRResource+fbx.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index ed68086..798794b 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -1615,22 +1615,24 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { FbxProperty fbx_property = pNode->GetFirstProperty(); while(fbx_property.IsValid()) { std::string property_name = fbx_property.GetNameAsCStr(); + std::transform(property_name.begin(), property_name.end(), property_name.begin(), ::tolower); + boost::variant property_value = ""; switch(fbx_property.GetPropertyDataType().GetType()) { case eFbxInt: - property_value = fbx_property.Get(); + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); break; case eFbxDouble: - property_value = fbx_property.Get(); + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); break; case eFbxBool: - property_value = fbx_property.Get(); + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); break; case eFbxFloat: - property_value = fbx_property.Get(); + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); break; case eFbxString: - property_value = std::string(fbx_property.Get().Buffer()); + new_locator->getUserAttributes()[property_name] = std::string(fbx_property.Get().Buffer()); break; default: { @@ -1639,9 +1641,7 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { break; } - std::transform(property_name.begin(), property_name.end(), property_name.begin(), ::tolower); - - new_locator->getUserAttributes()[property_name] = property_value; + fbx_property = pNode->GetNextProperty(fbx_property); }