diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index dca0ea4..2ee541a 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -79,7 +79,7 @@ void KRCamera::loadXML(tinyxml2::XMLElement *e) void KRCamera::flushSkybox() { - m_pSkyBoxTexture = NULL; // NOTE: the streamer manages the loading and unloading of the skybox textures + m_pSkyBoxTexture = NULL; // NOTE: the texture manager manages the loading and unloading of the skybox textures } void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight) @@ -183,10 +183,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glDepthMask(GL_FALSE)); // Set source to buffers from pass 1 - m_pContext->getTextureManager()->selectTexture(6, NULL); + m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(6); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture)); - m_pContext->getTextureManager()->selectTexture(7, NULL); + m_pContext->getTextureManager()->selectTexture(7, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(7); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); @@ -211,7 +211,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); // Set source to buffers from pass 2 - m_pContext->getTextureManager()->selectTexture(6, NULL); + m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(6); GLDEBUG(glBindTexture(GL_TEXTURE_2D, lightAccumulationTexture)); @@ -232,10 +232,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, false); // Deactivate source buffer texture units - m_pContext->getTextureManager()->selectTexture(6, NULL); + m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(6); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - m_pContext->getTextureManager()->selectTexture(7, NULL); + m_pContext->getTextureManager()->selectTexture(7, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(7); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); @@ -313,7 +313,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende 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); + getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE); // Render a full screen quad 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); @@ -425,7 +425,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Disable z-buffer test GLDEBUG(glDisable(GL_DEPTH_TEST)); - m_pContext->getTextureManager()->selectTexture(0, NULL); + m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(0); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); @@ -692,16 +692,16 @@ void KRCamera::renderPost() 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()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(0); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); - m_pContext->getTextureManager()->selectTexture(1, NULL); + m_pContext->getTextureManager()->selectTexture(1, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(1); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture)); if(settings.volumetric_environment_enable) { - m_pContext->getTextureManager()->selectTexture(2, NULL); + m_pContext->getTextureManager()->selectTexture(2, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(2); GLDEBUG(glBindTexture(GL_TEXTURE_2D, volumetricLightAccumulationTexture)); } @@ -711,11 +711,11 @@ void KRCamera::renderPost() GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - m_pContext->getTextureManager()->selectTexture(0, NULL); + m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(0); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - m_pContext->getTextureManager()->selectTexture(1, NULL); + m_pContext->getTextureManager()->selectTexture(1, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(1); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); @@ -895,7 +895,7 @@ void KRCamera::renderPost() 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")); + m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"), 0.0f, KRTexture::TEXTURE_USAGE_UI); 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); @@ -983,8 +983,7 @@ std::string KRCamera::getDebugText() // ---- GPU Memory ---- int texture_count_active = m_pContext->getTextureManager()->getActiveTextures().size(); - int texture_count_pooled = m_pContext->getTextureManager()->getPoolTextures().size(); - int texture_count = texture_count_active + texture_count_pooled; + int texture_count = texture_count_active; long texture_mem_active = m_pContext->getTextureManager()->getMemActive(); long texture_mem_used = m_pContext->getTextureManager()->getMemUsed(); long texture_mem_throughput = m_pContext->getTextureManager()->getMemoryTransferedThisFrame(); diff --git a/KREngine/kraken/KRLODSet.cpp b/KREngine/kraken/KRLODSet.cpp index 01a7cd0..80e288f 100644 --- a/KREngine/kraken/KRLODSet.cpp +++ b/KREngine/kraken/KRLODSet.cpp @@ -55,7 +55,7 @@ void KRLODSet::updateLODVisibility(const KRViewport &viewport) } 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) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { + if(new_active_lod_group->getStreamLevel(true, viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { // 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 { @@ -104,10 +104,10 @@ void KRLODSet::showLOD() } } -kraken_stream_level KRLODSet::getStreamLevel(bool prime) +kraken_stream_level KRLODSet::getStreamLevel(bool prime, const KRViewport &viewport) { if(m_activeLODGroup) { - return m_activeLODGroup->getStreamLevel(prime); + return m_activeLODGroup->getStreamLevel(prime, viewport); } else { return kraken_stream_level::STREAM_LEVEL_IN_HQ; } diff --git a/KREngine/kraken/KRLODSet.h b/KREngine/kraken/KRLODSet.h index a66544f..3e3c433 100644 --- a/KREngine/kraken/KRLODSet.h +++ b/KREngine/kraken/KRLODSet.h @@ -30,7 +30,7 @@ public: virtual void hideLOD(); virtual void childDeleted(KRNode *child_node); - virtual kraken_stream_level getStreamLevel(bool prime = true); + virtual kraken_stream_level getStreamLevel(bool prime, const KRViewport &viewport); private: KRLODGroup *m_activeLODGroup; diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index 79a303e..6f44976 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -338,7 +338,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, 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); + m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture, 0.0f, KRTexture::TEXTURE_USAGE_LIGHT_FLARE); 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/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index bbe4730..f938e02 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -217,34 +217,34 @@ 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) +kraken_stream_level KRMaterial::getStreamLevel(bool prime, float lodCoverage) { 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)); + stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_AMBIENT_MAP)); } if(m_pDiffuseMap) { - stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP)); } if(m_pNormalMap) { - stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP)); } if(m_pSpecularMap) { - stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP)); } if(m_pReflectionMap) { - stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP)); } if(m_pReflectionCube) { - stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(prime, lodCoverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE)); } return stream_level; @@ -272,7 +272,7 @@ void KRMaterial::getTextures() } } -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 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, float lod_coverage) { bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; getTextures(); @@ -359,24 +359,24 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_ligh pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_tr); if(bDiffuseMap) { - m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap); + m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap, lod_coverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP); } if(bSpecMap) { - m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap); + m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap, lod_coverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP); } if(bNormalMap) { - m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap); + m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap, lod_coverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP); } if(bReflectionCubeMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { - m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube); + m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube, lod_coverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE); } if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { // GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering - m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap); + m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap, lod_coverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP); } diff --git a/KREngine/kraken/KRMaterial.h b/KREngine/kraken/KRMaterial.h index 503a045..31a09a5 100644 --- a/KREngine/kraken/KRMaterial.h +++ b/KREngine/kraken/KRMaterial.h @@ -84,11 +84,11 @@ 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, const KRVector3 &rim_color, float rim_power); + 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, float lod_coverage = 0.0f); bool needsVertexTangents(); - kraken_stream_level getStreamLevel(bool prime = true); + kraken_stream_level getStreamLevel(bool prime, float lodCoverage); private: std::string m_name; diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index b6ba1b3..c180b3c 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -186,20 +186,20 @@ void KRMesh::getMaterials() } } -kraken_stream_level KRMesh::getStreamLevel(bool prime) +kraken_stream_level KRMesh::getStreamLevel(bool prime, float lodCoverage) { kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; getSubmeshes(); getMaterials(); for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel(prime, lodCoverage)); } return stream_level; } -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) { +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, float lod_coverage) { //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); @@ -233,7 +233,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, rim_color, rim_power)) { + if(pMaterial->bind(pCamera, point_lights, directional_lights, spot_lights, bones, bone_bind_poses, viewport, matModel, pLightMap, renderPass, rim_color, rim_power, lod_coverage)) { 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 891ddeb..c2ab5ea 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -67,7 +67,7 @@ public: KRMesh(KRContext &context, std::string name); virtual ~KRMesh(); - kraken_stream_level getStreamLevel(bool prime = true); + kraken_stream_level getStreamLevel(bool prime, float lodCoverage); bool hasTransparency(); @@ -112,7 +112,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, const KRVector3 &rim_color, float rim_power); + 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, float lod_coverage = 0.0f); std::string m_lodBaseName; diff --git a/KREngine/kraken/KRModel.cpp b/KREngine/kraken/KRModel.cpp index eb01799..731baea 100644 --- a/KREngine/kraken/KRModel.cpp +++ b/KREngine/kraken/KRModel.cpp @@ -157,13 +157,17 @@ void KRModel::render(KRCamera *pCamera, std::vector &point_light if(m_models.size() > 0) { // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied - + + /* float lod_coverage = 0.0f; if(m_models.size() > 1) { lod_coverage = viewport.coverage(getBounds()); // This also checks the view frustrum culling } else if(viewport.visible(getBounds())) { lod_coverage = 1.0f; } + */ + + float lod_coverage = viewport.coverage(getBounds()); // This also checks the view frustrum culling if(lod_coverage > m_min_lod_coverage) { @@ -185,7 +189,7 @@ void KRModel::render(KRCamera *pCamera, std::vector &point_light } if(m_pLightMap && pCamera->settings.bEnableLightMap && renderPass != RENDER_PASS_SHADOWMAP && renderPass != RENDER_PASS_GENERATE_SHADOWMAPS) { - m_pContext->getTextureManager()->selectTexture(5, m_pLightMap); + m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP); } KRMat4 matModel = getModelMatrix(); @@ -195,21 +199,25 @@ 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], m_rim_color, m_rim_power); + pModel->render(getName(), pCamera, point_lights, directional_lights, spot_lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel], m_rim_color, m_rim_power, lod_coverage); } } } } -kraken_stream_level KRModel::getStreamLevel(bool prime) +kraken_stream_level KRModel::getStreamLevel(bool prime, const KRViewport &viewport) { - kraken_stream_level stream_level = KRNode::getStreamLevel(prime); + 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 + } for(auto itr = m_models.begin(); itr != m_models.end(); itr++) { - stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime, lod_coverage)); } return stream_level; diff --git a/KREngine/kraken/KRModel.h b/KREngine/kraken/KRModel.h index a048071..f771a4b 100644 --- a/KREngine/kraken/KRModel.h +++ b/KREngine/kraken/KRModel.h @@ -69,7 +69,7 @@ public: void setLightMap(const std::string &name); std::string getLightMap(); - virtual kraken_stream_level getStreamLevel(bool prime = true); + virtual kraken_stream_level getStreamLevel(bool prime, const KRViewport &viewport); private: std::vector m_models; diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index 868cc87..4f5b07f 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -944,12 +944,12 @@ std::set &KRNode::getBehaviors() return m_behaviors; } -kraken_stream_level KRNode::getStreamLevel(bool prime) +kraken_stream_level KRNode::getStreamLevel(bool prime, const KRViewport &viewport) { kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime)); + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime, viewport)); } return stream_level; diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index f9503b6..f542d1a 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -167,7 +167,7 @@ public: bool getAnimationEnabled(node_attribute_type attrib) const; - virtual kraken_stream_level getStreamLevel(bool prime = true); + virtual kraken_stream_level getStreamLevel(bool prime, const KRViewport &viewport); virtual void hideLOD(); virtual void showLOD(); diff --git a/KREngine/kraken/KRParticleSystemNewtonian.cpp b/KREngine/kraken/KRParticleSystemNewtonian.cpp index 89e9dc5..7431e75 100644 --- a/KREngine/kraken/KRParticleSystemNewtonian.cpp +++ b/KREngine/kraken/KRParticleSystemNewtonian.cpp @@ -68,7 +68,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorgetTextureManager()->getTexture("flare"); - m_pContext->getTextureManager()->selectTexture(0, pParticleTexture); + m_pContext->getTextureManager()->selectTexture(0, pParticleTexture, 0.0f, KRTexture::TEXTURE_USAGE_PARTICLE); int particle_count = 10000; diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 8cd20f4..576d8a8 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -599,12 +599,13 @@ bool KRScene::sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, } -kraken_stream_level KRScene::getStreamLevel(bool prime) +kraken_stream_level KRScene::getStreamLevel() { kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; if(m_pRootNode) { - stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(prime)); + KRViewport viewport; // This isn't used when prime is false + stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(false, viewport)); } return stream_level; diff --git a/KREngine/kraken/KRScene.h b/KREngine/kraken/KRScene.h index 799eab2..0ba470c 100644 --- a/KREngine/kraken/KRScene.h +++ b/KREngine/kraken/KRScene.h @@ -64,7 +64,7 @@ public: KRNode *getRootNode(); KRLight *getFirstLight(); - kraken_stream_level getStreamLevel(bool prime = true); + kraken_stream_level getStreamLevel(); bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo, unsigned int layer_mask); diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index b1423e0..a2fd09a 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -372,7 +372,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & if(light_directional_count == 0) { int cShadowBuffers = directional_light->getShadowBufferCount(); if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) { - m_pContext->getTextureManager()->selectTexture(3, NULL); + m_pContext->getTextureManager()->selectTexture(3, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); m_pContext->getTextureManager()->_setActiveTexture(3); GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[0])); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -383,7 +383,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1 && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { - m_pContext->getTextureManager()->selectTexture(4, NULL); + m_pContext->getTextureManager()->selectTexture(4, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); m_pContext->getTextureManager()->_setActiveTexture(4); GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[1])); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -393,7 +393,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1 && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { - m_pContext->getTextureManager()->selectTexture(5, NULL); + m_pContext->getTextureManager()->selectTexture(5, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); m_pContext->getTextureManager()->_setActiveTexture(5); GLDEBUG(glActiveTexture(GL_TEXTURE5)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[2])); diff --git a/KREngine/kraken/KRSprite.cpp b/KREngine/kraken/KRSprite.cpp index c9f63c6..62fbe5f 100644 --- a/KREngine/kraken/KRSprite.cpp +++ b/KREngine/kraken/KRSprite.cpp @@ -118,7 +118,7 @@ void KRSprite::render(KRCamera *pCamera, std::vector &point_ligh 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); - m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture); + m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture, 0.0f, KRTexture::TEXTURE_USAGE_SPRITE); 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/KRTexture.cpp b/KREngine/kraken/KRTexture.cpp index f0207aa..0789815 100644 --- a/KREngine/kraken/KRTexture.cpp +++ b/KREngine/kraken/KRTexture.cpp @@ -20,6 +20,8 @@ KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, 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(); } @@ -90,31 +92,71 @@ void KRTexture::resize(int max_dim) } GLuint KRTexture::getHandle() { - resetPoolExpiry(); + resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // TODO - Pass through getHandle() arguements to replace extraneous resetPoolExpiry calls? return m_iHandle; } -void KRTexture::resetPoolExpiry() +void KRTexture::resetPoolExpiry(float lodCoverage, KRTexture::texture_usage_t textureUsage) { - m_last_frame_used = getContext().getCurrentFrame(); + long current_frame = getContext().getCurrentFrame(); + if(current_frame != m_last_frame_used) { + m_last_frame_used = current_frame; + m_last_frame_max_lod_coverage = 0.0f; + m_last_frame_usage = TEXTURE_USAGE_NONE; + + getContext().getTextureManager()->primeTexture(this); + } + m_last_frame_max_lod_coverage = KRMAX(lodCoverage, m_last_frame_max_lod_coverage); + m_last_frame_usage = static_cast(static_cast(m_last_frame_usage) | static_cast(textureUsage)); } - -kraken_stream_level KRTexture::getStreamLevel(bool prime) +kraken_stream_level KRTexture::getStreamLevel(bool prime, float lodCoverage, KRTexture::texture_usage_t textureUsage) { if(prime) { - resetPoolExpiry(); + resetPoolExpiry(lodCoverage, textureUsage); } if(m_current_lod_max_dim == 0) { return kraken_stream_level::STREAM_LEVEL_OUT; - } else if(m_current_lod_max_dim == m_max_lod_max_dim) { + } else if(m_current_lod_max_dim == KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, m_max_lod_max_dim)) { return kraken_stream_level::STREAM_LEVEL_IN_HQ; } else { return kraken_stream_level::STREAM_LEVEL_IN_LQ; } } +float KRTexture::getStreamPriority() +{ + long current_frame = getContext().getCurrentFrame(); + if(current_frame > m_last_frame_used + 5) { + return 1.0f - KRCLAMP((float)(current_frame - m_last_frame_used) / 60.0f, 0.0f, 1.0f); + } else { + float priority = 100.0f; + if(m_last_frame_usage & (TEXTURE_USAGE_UI | TEXTURE_USAGE_SHADOW_DEPTH)) { + priority += 10000000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_SKY_CUBE | TEXTURE_USAGE_PARTICLE | TEXTURE_USAGE_SPRITE | TEXTURE_USAGE_LIGHT_FLARE)) { + priority += 1000000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_DIFFUSE_MAP | TEXTURE_USAGE_AMBIENT_MAP | TEXTURE_USAGE_SPECULAR_MAP | TEXTURE_USAGE_NORMAL_MAP | TEXTURE_USAGE_REFLECTION_MAP)) { + priority += 100000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_LIGHT_MAP)) { + priority += 100000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_REFECTION_CUBE)) { + priority += 1000.0f; + } + priority += m_last_frame_max_lod_coverage * 10.0f; + return priority; + } +} + +float KRTexture::getLastFrameLodCoverage() const +{ + return m_last_frame_max_lod_coverage; +} + long KRTexture::getLastFrameUsed() { return m_last_frame_used; diff --git a/KREngine/kraken/KRTexture.h b/KREngine/kraken/KRTexture.h index dde342f..cc741fb 100644 --- a/KREngine/kraken/KRTexture.h +++ b/KREngine/kraken/KRTexture.h @@ -56,7 +56,26 @@ public: long getLastFrameUsed(); - virtual void resetPoolExpiry(); + typedef enum { + TEXTURE_USAGE_NONE = 0x00, + TEXTURE_USAGE_UI = 0x01, + TEXTURE_USAGE_SKY_CUBE = 0x02, + TEXTURE_USAGE_LIGHT_MAP = 0x04, + TEXTURE_USAGE_DIFFUSE_MAP = 0x08, + TEXTURE_USAGE_AMBIENT_MAP = 0x10, + TEXTURE_USAGE_SPECULAR_MAP = 0x20, + TEXTURE_USAGE_NORMAL_MAP = 0x40, + TEXTURE_USAGE_REFLECTION_MAP = 0x80, + TEXTURE_USAGE_REFECTION_CUBE = 0x100, + TEXTURE_USAGE_LIGHT_FLARE = 0x200, + TEXTURE_USAGE_SHADOW_DEPTH = 0x400, + TEXTURE_USAGE_PARTICLE = 0x800, + TEXTURE_USAGE_SPRITE = 0x1000 + } texture_usage_t; + + float getStreamPriority(); + + virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); virtual bool isAnimated(); virtual KRTexture *compress(bool premultiply_alpha = false); @@ -66,9 +85,11 @@ public: bool hasMipmaps(); bool canStreamOut() const; - kraken_stream_level getStreamLevel(bool prime = true); + kraken_stream_level getStreamLevel(bool prime, float lodCoverage, KRTexture::texture_usage_t textureUsage); + float getLastFrameLodCoverage() const; void _swapHandles(); + protected: virtual bool createGLTexture(int lod_max_dim) = 0; GLuint getHandle(); @@ -85,6 +106,8 @@ protected: long m_last_frame_used; long m_last_frame_bound; + float m_last_frame_max_lod_coverage; + texture_usage_t m_last_frame_usage; private: std::atomic m_textureMemUsed; diff --git a/KREngine/kraken/KRTextureAnimated.cpp b/KREngine/kraken/KRTextureAnimated.cpp index c25028a..f3e80c8 100644 --- a/KREngine/kraken/KRTextureAnimated.cpp +++ b/KREngine/kraken/KRTextureAnimated.cpp @@ -91,21 +91,20 @@ long KRTextureAnimated::getMemRequiredForSize(int max_dim) } -void KRTextureAnimated::resetPoolExpiry() +void KRTextureAnimated::resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage) { - KRTexture::resetPoolExpiry(); + KRTexture::resetPoolExpiry(lodCoverage, textureUsage); for(int i=0; iresetPoolExpiry(); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly - getContext().getTextureManager()->primeTexture(frame_texture); + frame_texture->resetPoolExpiry(lodCoverage, textureUsage); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly } } } void KRTextureAnimated::bind(GLuint texture_unit) { - resetPoolExpiry(); + resetPoolExpiry(0.0f, TEXTURE_USAGE_NONE); // TODO - Need to set parameters here for streaming priority? KRTexture::bind(texture_unit); int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count)); KRTexture2D *frame_texture = textureForFrame(frame_number); diff --git a/KREngine/kraken/KRTextureAnimated.h b/KREngine/kraken/KRTextureAnimated.h index 9e685b6..94ae16c 100644 --- a/KREngine/kraken/KRTextureAnimated.h +++ b/KREngine/kraken/KRTextureAnimated.h @@ -45,7 +45,7 @@ public: virtual void bind(GLuint texture_unit); virtual long getMemRequiredForSize(int max_dim); - virtual void resetPoolExpiry(); + virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); virtual long getReferencedMemSize(); diff --git a/KREngine/kraken/KRTextureCube.cpp b/KREngine/kraken/KRTextureCube.cpp index 982e6bb..3021265 100644 --- a/KREngine/kraken/KRTextureCube.cpp +++ b/KREngine/kraken/KRTextureCube.cpp @@ -115,14 +115,14 @@ long KRTextureCube::getMemRequiredForSize(int max_dim) } -void KRTextureCube::resetPoolExpiry() +void KRTextureCube::resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage) { - KRTexture::resetPoolExpiry(); + KRTexture::resetPoolExpiry(lodCoverage, textureUsage); for(int i=0; i<6; i++) { std::string faceName = getName() + SUFFIXES[i]; KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); if(faceTexture) { - faceTexture->resetPoolExpiry(); // Ensure that side of cube maps do not expire from the texture pool prematurely, as they are referenced indirectly + faceTexture->resetPoolExpiry(lodCoverage, textureUsage); // Ensure that side of cube maps do not expire from the texture pool prematurely, as they are referenced indirectly } } } diff --git a/KREngine/kraken/KRTextureCube.h b/KREngine/kraken/KRTextureCube.h index e242147..8a0edc1 100644 --- a/KREngine/kraken/KRTextureCube.h +++ b/KREngine/kraken/KRTextureCube.h @@ -44,7 +44,7 @@ public: virtual void bind(GLuint texture_unit); virtual long getMemRequiredForSize(int max_dim); - virtual void resetPoolExpiry(); + virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); private: virtual bool createGLTexture(int lod_max_dim); diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 878d254..0b1df0f 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -64,7 +64,7 @@ void KRTextureManager::_clearGLState() m_wrapModeS[i] = 0; m_wrapModeT[i] = 0; m_maxAnisotropy[i] = -1.0f; - selectTexture(i, NULL); + selectTexture(i, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); } m_iActiveTexture = -1; @@ -179,19 +179,17 @@ KRTexture *KRTextureManager::getTexture(const std::string &name) { } } -void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { +void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage) { bool is_animated = false; if(pTexture) { + pTexture->resetPoolExpiry(lod_coverage, textureUsage); if(pTexture->isAnimated()) is_animated = true; } if(m_boundTextures[iTextureUnit] != pTexture || is_animated) { _setActiveTexture(iTextureUnit); if(pTexture != NULL) { - primeTexture(pTexture); - pTexture->bind(iTextureUnit); - } else { GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); } @@ -200,14 +198,6 @@ 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; } @@ -234,7 +224,6 @@ void KRTextureManager::startFrame(float deltaTime) // 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; @@ -245,7 +234,7 @@ void KRTextureManager::endFrame(float deltaTime) { for(int iTexture=0; iTexture < KRENGINE_MAX_TEXTURE_UNITS; iTexture++) { if(m_boundTextures[iTexture]) { - m_boundTextures[iTexture]->resetPoolExpiry(); // Even if the same texture is bound, ensure that they don't expire from the texture pool while in use + m_boundTextures[iTexture]->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // Even if the same texture is bound, ensure that they don't expire from the texture pool while in use } } } @@ -255,7 +244,6 @@ 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(); @@ -269,8 +257,7 @@ void KRTextureManager::balanceTextureMemory() /* NEW ALGORITHM: - The “fixed” textures will be assigned to the skybox and the animated character flares - The rest of the textures are assigned a “weight” by tuneable criteria: + Textures are assigned a “weight” by tuneable criteria: - Area of screen coverage taken by objects containing material (more accurate and generic than distance) - Type of texture (separate weight for normal, diffuse, spec maps) - Last used time (to keep textures loaded for recently seen objects that are outside of the view frustum) @@ -280,6 +267,69 @@ void KRTextureManager::balanceTextureMemory() */ + // --------------- + + // TODO - Would this be faster with int's for weights? + std::vector> sortedTextures; + for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { + KRTexture *texture = *itr; + float priority = texture->getStreamPriority(); + sortedTextures.push_back(std::pair(priority, texture)); + } + + std::sort(sortedTextures.begin(), sortedTextures.end(), std::greater>()); + + long memoryRemaining = getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX; + long memoryRemainingThisFrame = KRMIN(getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - getMemUsed(), getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX); + + for(auto itr=sortedTextures.begin(); itr != sortedTextures.end(); itr++) { + KRTexture *texture = (*itr).second; + int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); + long minLodMem = texture->getMemRequiredForSize(min_mip_level); + memoryRemaining -= minLodMem; + + if(memoryRemainingThisFrame > minLodMem && texture->getCurrentLodMaxDim() < min_mip_level) { + memoryRemainingThisFrame -= minLodMem; + texture->resize(min_mip_level); + } + } + + std::vector mipPercents = {75, 75, 50, 50, 50}; + int mip_drop = -1; + auto mip_itr = mipPercents.begin(); + long memoryRemainingThisMip = 0; + + for(auto itr=sortedTextures.begin(); itr != sortedTextures.end(); itr++) { + if(memoryRemainingThisMip <= 0) { + if(mip_itr == mipPercents.end()) { + break; + } else { + memoryRemainingThisMip = memoryRemaining * (*mip_itr) / 100; + mip_drop++; + mip_itr++; + } + } + + KRTexture *texture = (*itr).second; + int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); + int max_mip_level = KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, texture->getMaxMipMap()); + int target_mip_level = (max_mip_level >> mip_drop); + long targetMem = texture->getMemRequiredForSize(target_mip_level); + long additionalMemRequired = targetMem - texture->getMemRequiredForSize(min_mip_level); + memoryRemainingThisMip -= additionalMemRequired; + memoryRemaining -= additionalMemRequired; + if(memoryRemainingThisMip > 0 && memoryRemainingThisFrame > targetMem) { + if(texture->getCurrentLodMaxDim() != target_mip_level) { + memoryRemainingThisFrame -= targetMem; + texture->resize(target_mip_level); + } + } + } + + + + // --------------- + /* // Determine the additional amount of memory required in order to resize all active textures to the maximum size long wantedTextureMem = 0; @@ -356,8 +406,7 @@ void KRTextureManager::balanceTextureMemory() } } } - - //fprintf(stderr, "Active mipmap size: %i Inactive mapmap size: %i\n", (int)maxDimActive, (int)maxDimInactive); + */ } void KRTextureManager::rotateBuffers() @@ -366,21 +415,16 @@ void KRTextureManager::rotateBuffers() // ----====---- Expire textures that haven't been used in a long time ----====---- std::set expiredTextures; - for(std::set::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { - KRTexture *poolTexture = *itr; - if(poolTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { - expiredTextures.insert(poolTexture); - poolTexture->releaseHandles(); + for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { + KRTexture *activeTexture = *itr; + if(activeTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { + expiredTextures.insert(activeTexture); + activeTexture->releaseHandles(); } } for(std::set::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) { - m_poolTextures.erase(*itr); + m_activeTextures.erase(*itr); } - - // ----====---- Swap the buffers ----====---- - - m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end()); - m_activeTextures.clear(); } long KRTextureManager::getMemoryTransferedThisFrame() @@ -444,8 +488,10 @@ std::set &KRTextureManager::getActiveTextures() return m_activeTextures; } -std::set &KRTextureManager::getPoolTextures() +void KRTextureManager::primeTexture(KRTexture *texture) { - return m_poolTextures; + if(m_activeTextures.find(texture) == m_activeTextures.end()) { + m_activeTextures.insert(texture); + } } diff --git a/KREngine/kraken/KRTextureManager.h b/KREngine/kraken/KRTextureManager.h index 41b4b21..46ab085 100644 --- a/KREngine/kraken/KRTextureManager.h +++ b/KREngine/kraken/KRTextureManager.h @@ -46,8 +46,7 @@ public: KRTextureManager(KRContext &context); virtual ~KRTextureManager(); - void primeTexture(KRTexture *pTexture); - void selectTexture(int iTextureUnit, KRTexture *pTexture); + void selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage); KRTexture *loadTexture(const char *szName, const char *szExtension, KRDataBlock *data); KRTexture *getTextureCube(const char *szName); @@ -69,7 +68,6 @@ public: void compress(bool premultiply_alpha = false); std::set &getActiveTextures(); - std::set &getPoolTextures(); void _setActiveTexture(int i); void _setWrapModeS(GLuint i, GLuint wrap_mode); @@ -80,6 +78,7 @@ public: void setMaxAnisotropy(float max_anisotropy); void doStreaming(); + void primeTexture(KRTexture *texture); private: int m_iActiveTexture; @@ -95,12 +94,9 @@ private: 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; std::atomic m_textureMemUsed; diff --git a/KREngine/kraken/KRViewport.cpp b/KREngine/kraken/KRViewport.cpp index 6dbd0e9..9feab68 100644 --- a/KREngine/kraken/KRViewport.cpp +++ b/KREngine/kraken/KRViewport.cpp @@ -182,10 +182,8 @@ float KRViewport::coverage(const KRAABB &b) const for(int i=0; i<8; i++) { KRVector3 screen_pos = KRMat4::DotWDiv(m_matViewProjection, KRVector3(i & 1 ? b.min.x : b.max.x, i & 2 ? b.min.y : b.max.y, i & 4 ? b.min.z : b.max.z)); if(i==0) { - screen_min.x = screen_pos.x; - screen_min.y = screen_pos.y; - screen_max.x = screen_pos.x; - screen_max.y = screen_pos.y; + screen_min = screen_pos.xy(); + screen_max = screen_pos.xy(); } else { if(screen_pos.x < screen_min.x) screen_min.x = screen_pos.x; if(screen_pos.y < screen_min.y) screen_min.y = screen_pos.y; @@ -194,7 +192,13 @@ float KRViewport::coverage(const KRAABB &b) const } } - return (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y); + screen_min.x = KRCLAMP(screen_min.x, 0.0f, 1.0f); + screen_min.y = KRCLAMP(screen_min.y, 0.0f, 1.0f); + screen_max.x = KRCLAMP(screen_max.x, 0.0f, 1.0f); + screen_max.y = KRCLAMP(screen_max.y, 0.0f, 1.0f); + + float c = (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y); + return KRCLAMP(c, 0.01f, 1.0f); } }