Implemented texture pre-streaming for lod swaps

--HG--
branch : nfb
This commit is contained in:
2014-04-23 01:43:00 -07:00
parent 7194d39f7d
commit e9c17df900
29 changed files with 202 additions and 139 deletions

View File

@@ -87,6 +87,7 @@ void KRAmbientZone::setZone(const std::string &zone)
void KRAmbientZone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);

View File

@@ -200,6 +200,8 @@ void KRAudioSource::queueBuffer()
void KRAudioSource::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);
bool bVisualize = false;

View File

@@ -41,6 +41,7 @@ KRAABB KRBone::getBounds() {
void KRBone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);

View File

@@ -115,11 +115,14 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
scene.updateOctree(m_viewport);
// ----====---- Pre-stream resources ----====----
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_PRESTREAM, true);
// ----====---- Generate Shadowmaps for Lights ----====----
if(settings.m_cShadowBuffers > 0) {
GL_PUSH_GROUP_MARKER("Generate Shadowmaps");
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, settings.bEnableDeferredLighting);
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, false /*settings.bEnableDeferredLighting*/);
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
GL_POP_GROUP_MARKER;
}
@@ -158,7 +161,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
GLDEBUG(glDisable(GL_BLEND));
// Render the geometry
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, true);
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, false);
GL_POP_GROUP_MARKER;
@@ -280,7 +283,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
// Render the geometry
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, true);
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, false);
GL_POP_GROUP_MARKER;
}

View File

@@ -187,6 +187,7 @@ void KRCollider::setAudioOcclusion(float audio_occlusion)
void KRCollider::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);

View File

@@ -20,6 +20,7 @@ int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX;
int KRContext::KRENGINE_MAX_TEXTURE_DIM;
int KRContext::KRENGINE_MIN_TEXTURE_DIM;
int KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT;
int KRContext::KRENGINE_PRESTREAM_DISTANCE;
const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = {
"GL_EXT_texture_storage"

View File

@@ -32,6 +32,7 @@ public:
static int KRENGINE_MAX_TEXTURE_DIM;
static int KRENGINE_MIN_TEXTURE_DIM;
static int KRENGINE_MAX_TEXTURE_THROUGHPUT;
static int KRENGINE_PRESTREAM_DISTANCE;
KRContext();

View File

@@ -89,6 +89,8 @@ int KRDirectionalLight::configureShadowBufferViewports(const KRViewport &viewpor
void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRLight::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);
if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) {

View File

@@ -94,6 +94,7 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_PRESTREAM_DISTANCE = 1000.0f;
KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 4000000;
@@ -139,6 +140,7 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_TEXTURE_DIM = 8192;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000;
KRContext::KRENGINE_PRESTREAM_DISTANCE = 1000.0f;
#endif
_context = NULL;

View File

@@ -102,15 +102,17 @@ void KRLODGroup::setReference(const KRAABB &reference)
m_reference = reference;
}
bool KRLODGroup::getLODVisibility(const KRViewport &viewport)
KRNode::LodVisibility KRLODGroup::calcLODVisibility(const KRViewport &viewport)
{
if(m_min_distance == 0 && m_max_distance == 0) {
return true;
return LOD_VISIBILITY_VISIBLE;
} else {
float lod_bias = viewport.getLODBias();
lod_bias = pow(2.0f, -lod_bias);
float sqr_distance; // Compare using squared distances as sqrt is expensive
// Compare using squared distances as sqrt is expensive
float sqr_distance;
float sqr_prestream_distance;
KRVector3 world_camera_position = viewport.getCameraPosition();
KRVector3 local_camera_position = worldToLocal(world_camera_position);
@@ -119,13 +121,24 @@ bool KRLODGroup::getLODVisibility(const KRViewport &viewport)
if(m_use_world_units) {
KRVector3 world_reference_point = localToWorld(local_reference_point);
sqr_distance = (world_camera_position - world_reference_point).sqrMagnitude() * (lod_bias * lod_bias);
sqr_prestream_distance = getContext().KRENGINE_PRESTREAM_DISTANCE * getContext().KRENGINE_PRESTREAM_DISTANCE;
} else {
sqr_distance = (local_camera_position - local_reference_point).sqrMagnitude() * (lod_bias * lod_bias);
KRVector3 world_reference_point = localToWorld(local_reference_point);
sqr_prestream_distance = worldToLocal(KRVector3::Normalize(world_reference_point - world_camera_position) * getContext().KRENGINE_PRESTREAM_DISTANCE).sqrMagnitude(); // TODO, FINDME - Optimize with precalc?
}
float sqr_min_distance = m_min_distance * m_min_distance;
float sqr_max_distance = m_max_distance * m_max_distance;
return ((sqr_distance >= sqr_min_distance || m_min_distance == 0) && (sqr_distance < sqr_max_distance || m_max_distance == 0));
float sqr_min_visible_distance = m_min_distance * m_min_distance;
float sqr_max_visible_distance = m_max_distance * m_max_distance;
if((sqr_distance >= sqr_min_visible_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance || m_max_distance == 0)) {
return LOD_VISIBILITY_VISIBLE;
} else if((sqr_distance >= sqr_min_visible_distance - sqr_prestream_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance + sqr_prestream_distance || m_max_distance == 0)) {
return LOD_VISIBILITY_PRESTREAM;
} else {
return LOD_VISIBILITY_HIDDEN;
}
}
}

View File

@@ -30,7 +30,7 @@ public:
void setUseWorldUnits(bool use_world_units);
bool getUseWorldUnits() const;
bool getLODVisibility(const KRViewport &viewport);
LodVisibility calcLODVisibility(const KRViewport &viewport);
private:
float m_min_distance;

View File

@@ -12,7 +12,7 @@
KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name)
{
m_activeLODGroup = NULL;
}
KRLODSet::~KRLODSet()
@@ -38,37 +38,38 @@ void KRLODSet::loadXML(tinyxml2::XMLElement *e)
void KRLODSet::updateLODVisibility(const KRViewport &viewport)
{
if(m_lod_visible) {
if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM) {
KRLODGroup *new_active_lod_group = NULL;
// Upgrade and downgrade LOD groups as needed
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*itr);
assert(lod_group != NULL);
if(lod_group->getLODVisibility(viewport)) {
LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible);
if(group_lod_visibility == LOD_VISIBILITY_VISIBLE) {
new_active_lod_group = lod_group;
}
lod_group->setLODVisibility(group_lod_visibility);
}
/*
// FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues:
bool streamer_ready = false;
if(new_active_lod_group == NULL) {
m_activeLODGroup = NULL;
} else if(m_activeLODGroup == NULL) {
m_activeLODGroup = new_active_lod_group;
} else if(new_active_lod_group != m_activeLODGroup) {
if(true || new_active_lod_group->getStreamLevel(true, viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { // FINDME, HACK! Disabled due to performance issues.
// fprintf(stderr, "LOD %s -> %s\n", m_activeLODGroup->getName().c_str(), new_active_lod_group->getName().c_str());
m_activeLODGroup = new_active_lod_group;
} else {
// fprintf(stderr, "LOD %s -> %s - waiting for streaming...\n", m_activeLODGroup->getName().c_str(), new_active_lod_group->getName().c_str());
}
streamer_ready = true;
} else if(new_active_lod_group->getStreamLevel(viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) {
streamer_ready = true;
}
*/
bool streamer_ready = true;
if(streamer_ready) {
// Upgrade and downgrade LOD groups as needed
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRNode *child = *itr;
if(child == m_activeLODGroup) {
child->showLOD();
} else {
child->hideLOD();
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*itr);
assert(lod_group != NULL);
LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible);
lod_group->setLODVisibility(group_lod_visibility);
}
}
@@ -76,35 +77,20 @@ void KRLODSet::updateLODVisibility(const KRViewport &viewport)
}
}
KRLODGroup *KRLODSet::getActiveLODGroup() const
{
return m_activeLODGroup;
}
void KRLODSet::childDeleted(KRNode *child_node)
{
KRNode::childDeleted(child_node);
if(m_activeLODGroup == child_node) {
m_activeLODGroup = NULL;
}
}
void KRLODSet::hideLOD()
{
KRNode::hideLOD();
m_activeLODGroup = NULL; // Ensure that the streamer will wait for the group to load in next time
}
void KRLODSet::showLOD()
void KRLODSet::setLODVisibility(KRNode::LodVisibility lod_visibility)
{
if(lod_visibility == LOD_VISIBILITY_HIDDEN) {
KRNode::setLODVisibility(lod_visibility);
} else if(m_lod_visible != lod_visibility) {
// Don't automatically recurse into our children, as only one of those will be activated, by updateLODVisibility
if(!m_lod_visible) {
if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) {
getScene().notify_sceneGraphCreate(this);
m_lod_visible = true;
}
m_lod_visible = lod_visibility;
}
}
kraken_stream_level KRLODSet::getStreamLevel(bool prime, const KRViewport &viewport)
kraken_stream_level KRLODSet::getStreamLevel(const KRViewport &viewport)
{
KRLODGroup *new_active_lod_group = NULL;
@@ -112,13 +98,13 @@ kraken_stream_level KRLODSet::getStreamLevel(bool prime, const KRViewport &viewp
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*itr);
assert(lod_group != NULL);
if(lod_group->getLODVisibility(viewport)) {
if(lod_group->calcLODVisibility(viewport) == LOD_VISIBILITY_VISIBLE) {
new_active_lod_group = lod_group;
}
}
if(new_active_lod_group) {
return new_active_lod_group->getStreamLevel(prime, viewport);
return new_active_lod_group->getStreamLevel(viewport);
} else {
return kraken_stream_level::STREAM_LEVEL_IN_HQ;
}

View File

@@ -24,16 +24,9 @@ public:
virtual void updateLODVisibility(const KRViewport &viewport);
KRLODGroup *getActiveLODGroup() const;
virtual void setLODVisibility(LodVisibility lod_visibility);
virtual void showLOD();
virtual void hideLOD();
virtual void childDeleted(KRNode *child_node);
virtual kraken_stream_level getStreamLevel(bool prime, const KRViewport &viewport);
private:
KRLODGroup *m_activeLODGroup;
virtual kraken_stream_level getStreamLevel(const KRViewport &viewport);
};

View File

@@ -176,6 +176,8 @@ float KRLight::getDecayStart() {
void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);
if(renderPass == KRNode::RENDER_PASS_GENERATE_SHADOWMAPS && (pCamera->settings.volumetric_environment_enable || pCamera->settings.dust_particle_enable || (pCamera->settings.m_cShadowBuffers > 0 && m_casts_shadow))) {

View File

@@ -217,34 +217,64 @@ bool KRMaterial::isTransparent() {
return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE;
}
kraken_stream_level KRMaterial::getStreamLevel(bool prime, float lodCoverage)
void KRMaterial::preStream(float lodCoverage)
{
getTextures();
if(m_pAmbientMap) {
m_pAmbientMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_AMBIENT_MAP);
}
if(m_pDiffuseMap) {
m_pDiffuseMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP);
}
if(m_pNormalMap) {
m_pNormalMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP);
}
if(m_pSpecularMap) {
m_pSpecularMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP);
}
if(m_pReflectionMap) {
m_pReflectionMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP);
}
if(m_pReflectionCube) {
m_pReflectionCube->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE);
}
}
kraken_stream_level KRMaterial::getStreamLevel()
{
kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ;
getTextures();
if(m_pAmbientMap) {
stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_AMBIENT_MAP));
stream_level = KRMIN(stream_level, m_pAmbientMap->getStreamLevel(KRTexture::TEXTURE_USAGE_AMBIENT_MAP));
}
if(m_pDiffuseMap) {
stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP));
stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(KRTexture::TEXTURE_USAGE_DIFFUSE_MAP));
}
if(m_pNormalMap) {
stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP));
stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(KRTexture::TEXTURE_USAGE_NORMAL_MAP));
}
if(m_pSpecularMap) {
stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP));
stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(KRTexture::TEXTURE_USAGE_SPECULAR_MAP));
}
if(m_pReflectionMap) {
stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP));
stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(KRTexture::TEXTURE_USAGE_REFLECTION_MAP));
}
if(m_pReflectionCube) {
stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE));
stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(KRTexture::TEXTURE_USAGE_REFECTION_CUBE));
}
return stream_level;

View File

@@ -88,7 +88,8 @@ public:
bool needsVertexTangents();
kraken_stream_level getStreamLevel(bool prime, float lodCoverage);
kraken_stream_level getStreamLevel();
void preStream(float lodCoverage);
private:
std::string m_name;

View File

@@ -186,14 +186,24 @@ void KRMesh::getMaterials()
}
}
kraken_stream_level KRMesh::getStreamLevel(bool prime, float lodCoverage)
void KRMesh::preStream(float lodCoverage)
{
getSubmeshes();
getMaterials();
for(std::set<KRMaterial *>::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) {
(*mat_itr)->preStream(lodCoverage);
}
}
kraken_stream_level KRMesh::getStreamLevel()
{
kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ;
getSubmeshes();
getMaterials();
for(std::set<KRMaterial *>::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) {
stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel(prime, lodCoverage));
stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel());
}
return stream_level;
@@ -201,7 +211,6 @@ kraken_stream_level KRMesh::getStreamLevel(bool prime, float lodCoverage)
void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones, const KRVector3 &rim_color, float rim_power, float lod_coverage) {
//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();

View File

@@ -67,7 +67,8 @@ public:
KRMesh(KRContext &context, std::string name);
virtual ~KRMesh();
kraken_stream_level getStreamLevel(bool prime, float lodCoverage);
kraken_stream_level getStreamLevel();
void preStream(float lodCoverage);
bool hasTransparency();

View File

@@ -149,10 +149,15 @@ void KRModel::loadModel() {
void KRModel::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
if(m_lod_visible == LOD_VISIBILITY_PRESTREAM && renderPass == KRNode::RENDER_PASS_PRESTREAM) {
preStream(viewport);
}
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) {
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS && renderPass != KRNode::RENDER_PASS_PRESTREAM) {
loadModel();
if(m_models.size() > 0) {
@@ -205,19 +210,33 @@ void KRModel::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
}
}
kraken_stream_level KRModel::getStreamLevel(bool prime, const KRViewport &viewport)
void KRModel::preStream(const KRViewport &viewport)
{
kraken_stream_level stream_level = KRNode::getStreamLevel(prime, viewport);
loadModel();
float lod_coverage = 0.0f;
if(prime) {
lod_coverage = viewport.coverage(getBounds()); // This is only used when prime is true
}
float lod_coverage = viewport.coverage(getBounds());
for(auto itr = m_models.begin(); itr != m_models.end(); itr++) {
stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime, lod_coverage));
(*itr)->preStream(lod_coverage);
}
if(m_pLightMap == NULL && m_lightMap.size()) {
m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap);
}
if(m_pLightMap) {
m_pLightMap->resetPoolExpiry(lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP);
}
}
kraken_stream_level KRModel::getStreamLevel(const KRViewport &viewport)
{
kraken_stream_level stream_level = KRNode::getStreamLevel(viewport);
loadModel();
for(auto itr = m_models.begin(); itr != m_models.end(); itr++) {
stream_level = KRMIN(stream_level, (*itr)->getStreamLevel());
}
return stream_level;

View File

@@ -69,9 +69,11 @@ public:
void setLightMap(const std::string &name);
std::string getLightMap();
virtual kraken_stream_level getStreamLevel(bool prime, const KRViewport &viewport);
virtual kraken_stream_level getStreamLevel(const KRViewport &viewport);
private:
void preStream(const KRViewport &viewport);
std::vector<KRMesh *> m_models;
unordered_map<KRMesh *, std::vector<KRBone *> > m_bones; // Outer std::map connects model to set of bones
KRTexture *m_pLightMap;

View File

@@ -63,7 +63,7 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_modelMatrix = KRMat4();
m_bindPoseMatrix = KRMat4();
m_activePoseMatrix = KRMat4();
m_lod_visible = false;
m_lod_visible = LOD_VISIBILITY_HIDDEN;
m_scale_compensation = false;
m_boundsValid = false;
@@ -117,10 +117,7 @@ void KRNode::addChild(KRNode *child) {
assert(child->m_parentNode == NULL);
child->m_parentNode = this;
m_childNodes.insert(child);
if(m_lod_visible) {
// Child node inherits LOD visibility status from parent
child->showLOD();
}
child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent
}
tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) {
@@ -456,6 +453,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
void KRNode::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
m_lastRenderFrame = getContext().getCurrentFrame();
}
@@ -887,37 +886,31 @@ void KRNode::addToOctreeNode(KROctreeNode *octree_node)
void KRNode::updateLODVisibility(const KRViewport &viewport)
{
if(m_lod_visible) {
if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM) {
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->updateLODVisibility(viewport);
}
}
}
void KRNode::hideLOD()
void KRNode::setLODVisibility(KRNode::LodVisibility lod_visibility)
{
if(m_lod_visible) {
m_lod_visible = false;
getScene().notify_sceneGraphDelete(this);
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->hideLOD();
}
}
}
void KRNode::showLOD()
{
if(!m_lod_visible) {
if(m_lod_visible != lod_visibility) {
if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) {
getScene().notify_sceneGraphCreate(this);
m_lod_visible = true;
} else if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM && lod_visibility == LOD_VISIBILITY_HIDDEN) {
getScene().notify_sceneGraphDelete(this);
}
m_lod_visible = lod_visibility;
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->showLOD();
(*itr)->setLODVisibility(lod_visibility);
}
}
}
bool KRNode::lodIsVisible()
KRNode::LodVisibility KRNode::getLODVisibility()
{
return m_lod_visible;
}
@@ -944,12 +937,12 @@ std::set<KRBehavior *> &KRNode::getBehaviors()
return m_behaviors;
}
kraken_stream_level KRNode::getStreamLevel(bool prime, const KRViewport &viewport)
kraken_stream_level KRNode::getStreamLevel(const KRViewport &viewport)
{
kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ;
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime, viewport));
stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(viewport));
}
return stream_level;

View File

@@ -43,7 +43,14 @@ public:
RENDER_PASS_ADDITIVE_PARTICLES,
RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE,
RENDER_PASS_GENERATE_SHADOWMAPS,
RENDER_PASS_SHADOWMAP
RENDER_PASS_SHADOWMAP,
RENDER_PASS_PRESTREAM
};
enum LodVisibility {
LOD_VISIBILITY_HIDDEN,
LOD_VISIBILITY_PRESTREAM,
LOD_VISIBILITY_VISIBLE
};
KRNode(KRScene &scene, std::string name);
@@ -159,7 +166,7 @@ public:
virtual bool hasPhysics();
virtual void updateLODVisibility(const KRViewport &viewport);
bool lodIsVisible();
LodVisibility getLODVisibility();
void setScaleCompensation(bool scale_compensation);
bool getScaleCompensation();
@@ -167,10 +174,9 @@ public:
bool getAnimationEnabled(node_attribute_type attrib) const;
virtual kraken_stream_level getStreamLevel(bool prime, const KRViewport &viewport);
virtual kraken_stream_level getStreamLevel(const KRViewport &viewport);
virtual void hideLOD();
virtual void showLOD();
virtual void setLODVisibility(LodVisibility lod_visibility);
protected:
KRVector3 m_localTranslation;
@@ -195,7 +201,7 @@ protected:
KRVector3 m_initialPreRotation;
KRVector3 m_initialPostRotation;
bool m_lod_visible;
LodVisibility m_lod_visible;
KRNode *m_parentNode;
std::set<KRNode *> m_childNodes;
@@ -246,7 +252,7 @@ public:
}
void removeFromOctreeNodes();
void addToOctreeNode(KROctreeNode *octree_node);
virtual void childDeleted(KRNode *child_node);
void childDeleted(KRNode *child_node);
template <class T> T *find()
{

View File

@@ -56,6 +56,7 @@ bool KRParticleSystemNewtonian::hasPhysics()
void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);

View File

@@ -43,6 +43,7 @@ KRAABB KRPointLight::getBounds() {
void KRPointLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRLight::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);

View File

@@ -86,6 +86,7 @@ void KRReverbZone::setZone(const std::string &zone)
void KRReverbZone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);

View File

@@ -485,7 +485,7 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode)
void KRScene::updateOctree(const KRViewport &viewport)
{
m_pRootNode->showLOD();
m_pRootNode->setLODVisibility(KRNode::LOD_VISIBILITY_VISIBLE);
m_pRootNode->updateLODVisibility(viewport);
std::set<KRNode *> newNodes = std::move(m_newNodes);
@@ -518,7 +518,7 @@ void KRScene::updateOctree(const KRViewport &viewport)
}
for(std::set<KRNode *>::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) {
KRNode *node = *itr;
if(node->lodIsVisible()) {
if(node->getLODVisibility() >= KRNode::LOD_VISIBILITY_PRESTREAM) {
m_nodeTree.update(node);
}
if(node->hasPhysics()) {
@@ -605,7 +605,7 @@ kraken_stream_level KRScene::getStreamLevel()
if(m_pRootNode) {
KRViewport viewport; // This isn't used when prime is false
stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(false, viewport));
stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(viewport));
}
return stream_level;

View File

@@ -85,6 +85,8 @@ KRAABB KRSprite::getBounds() {
void KRSprite::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);

View File

@@ -21,7 +21,6 @@ KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context,
m_textureMemUsed = 0;
m_newTextureMemUsed = 0;
m_last_frame_used = 0;
m_last_frame_bound = 0;
m_last_frame_max_lod_coverage = 0.0f;
m_last_frame_usage = TEXTURE_USAGE_NONE;
m_handle_lock.clear();
@@ -114,12 +113,8 @@ void KRTexture::resetPoolExpiry(float lodCoverage, KRTexture::texture_usage_t te
m_last_frame_usage = static_cast<texture_usage_t>(static_cast<int>(m_last_frame_usage) | static_cast<int>(textureUsage));
}
kraken_stream_level KRTexture::getStreamLevel(bool prime, float lodCoverage, KRTexture::texture_usage_t textureUsage)
kraken_stream_level KRTexture::getStreamLevel(KRTexture::texture_usage_t textureUsage)
{
if(prime) {
resetPoolExpiry(lodCoverage, textureUsage);
}
if(m_current_lod_max_dim == 0) {
return kraken_stream_level::STREAM_LEVEL_OUT;
} else if(m_current_lod_max_dim == KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, m_max_lod_max_dim)) {
@@ -198,11 +193,7 @@ bool KRTexture::hasMipmaps() {
}
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()

View File

@@ -85,8 +85,7 @@ public:
int getMinMipMap();
bool hasMipmaps();
bool canStreamOut() const;
kraken_stream_level getStreamLevel(bool prime, float lodCoverage, KRTexture::texture_usage_t textureUsage);
kraken_stream_level getStreamLevel(KRTexture::texture_usage_t textureUsage);
float getLastFrameLodCoverage() const;
void _swapHandles();
@@ -107,7 +106,6 @@ protected:
uint32_t m_min_lod_max_dim;
long m_last_frame_used;
long m_last_frame_bound;
float m_last_frame_max_lod_coverage;
texture_usage_t m_last_frame_usage;