Implemented texture pre-streaming for lod swaps
--HG-- branch : nfb
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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();
|
||||
*/
|
||||
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) {
|
||||
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
|
||||
void KRLODSet::setLODVisibility(KRNode::LodVisibility lod_visibility)
|
||||
{
|
||||
return m_activeLODGroup;
|
||||
}
|
||||
|
||||
void KRLODSet::childDeleted(KRNode *child_node)
|
||||
{
|
||||
KRNode::childDeleted(child_node);
|
||||
if(m_activeLODGroup == child_node) {
|
||||
m_activeLODGroup = NULL;
|
||||
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 == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) {
|
||||
getScene().notify_sceneGraphCreate(this);
|
||||
}
|
||||
m_lod_visible = lod_visibility;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// Don't automatically recurse into our children, as only one of those will be activated, by updateLODVisibility
|
||||
if(!m_lod_visible) {
|
||||
getScene().notify_sceneGraphCreate(this);
|
||||
m_lod_visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -186,21 +186,30 @@ 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
if(m_lod_visible != lod_visibility) {
|
||||
if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) {
|
||||
getScene().notify_sceneGraphCreate(this);
|
||||
} 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)->hideLOD();
|
||||
(*itr)->setLODVisibility(lod_visibility);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KRNode::showLOD()
|
||||
{
|
||||
if(!m_lod_visible) {
|
||||
getScene().notify_sceneGraphCreate(this);
|
||||
m_lod_visible = true;
|
||||
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
||||
(*itr)->showLOD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user