More optimizations to reduce CPU utilization.
Fixed bug that caused cube maps to prematurely expire from the texture pool. --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40161
This commit is contained in:
@@ -628,11 +628,14 @@
|
||||
E491016E13C99BAE0098455B /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F9753815362A5200FD60B2 /* 3rdparty */,
|
||||
E488399915F92BA300BD66D5 /* Managers */,
|
||||
E461A173152E59DF00F2044A /* Math */,
|
||||
E461A170152E598200F2044A /* Resources */,
|
||||
E4924C2415EE95E700B965C6 /* KROctree.cpp */,
|
||||
E4924C2515EE95E800B965C6 /* KROctree.h */,
|
||||
E4924C2915EE96AA00B965C6 /* KROctreeNode.cpp */,
|
||||
E4924C2A15EE96AA00B965C6 /* KROctreeNode.h */,
|
||||
E4F9753815362A5200FD60B2 /* 3rdparty */,
|
||||
E48B3CBF14393E2F000C50E2 /* KRCamera.cpp */,
|
||||
E48B3CBC14393DF5000C50E2 /* KRCamera.h */,
|
||||
E48C697115374F7E00232E28 /* KRContext.cpp */,
|
||||
@@ -646,9 +649,6 @@
|
||||
E491016F13C99BDC0098455B /* KREngine.mm */,
|
||||
E46F4A03155DF47C00CCF8B8 /* KRWorld.cpp */,
|
||||
E46F49FF155DF46700CCF8B8 /* KRWorld.h */,
|
||||
E488399915F92BA300BD66D5 /* Managers */,
|
||||
E461A173152E59DF00F2044A /* Math */,
|
||||
E461A170152E598200F2044A /* Resources */,
|
||||
E4030E4B160A3CF000592648 /* KRStockGeometry.h */,
|
||||
E4CA11731639CBD1005D9400 /* KRViewport.h */,
|
||||
E4CA11771639CC8E005D9400 /* KRViewport.cpp */,
|
||||
|
||||
@@ -207,10 +207,10 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
GLDEBUG(glDisable(GL_BLEND));
|
||||
|
||||
// Render the geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, true);
|
||||
|
||||
// ----====---- Generate Shadowmaps for Lights ----====----
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, false);
|
||||
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
||||
|
||||
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
|
||||
@@ -237,7 +237,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
|
||||
|
||||
// Render the geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, false);
|
||||
|
||||
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
|
||||
// Set render target
|
||||
@@ -269,7 +269,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
|
||||
// Render the geometry
|
||||
// TODO: At this point, we only want to render octree nodes that produced fragments during the 1st pass into the GBuffer
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE);
|
||||
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);
|
||||
@@ -280,7 +280,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
} else {
|
||||
// ----====---- Generate Shadowmaps for Lights ----====----
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, true);
|
||||
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
||||
|
||||
// ----====---- Opaque Geometry, Forward Rendering ----====----
|
||||
@@ -311,7 +311,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
|
||||
|
||||
// Render the geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, false);
|
||||
}
|
||||
|
||||
// ----====---- Sky Box ----====----
|
||||
@@ -370,7 +370,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
// Render all transparent geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, false);
|
||||
|
||||
|
||||
// ----====---- Flares ----====----
|
||||
@@ -394,7 +394,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||
|
||||
// Render all flares
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, false);
|
||||
|
||||
// ----====---- Volumetric Lighting ----====----
|
||||
|
||||
@@ -422,7 +422,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||
}
|
||||
|
||||
scene.render(this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, false);
|
||||
|
||||
if(volumetric_environment_downsample != 0) {
|
||||
// Set render target
|
||||
|
||||
@@ -300,7 +300,7 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera)
|
||||
getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
|
||||
|
||||
|
||||
getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP);
|
||||
getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,22 @@ KRScene::~KRScene() {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRScene::render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass) {
|
||||
void KRScene::render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) {
|
||||
if(new_frame) {
|
||||
// Expire cached occlusion test results.
|
||||
// Cached "failed" results are expired on the next frame (marked with .second of -1)
|
||||
// Cached "success" results are expired after KRENGINE_OCCLUSION_TEST_EXPIRY frames (marked with .second of the last frame
|
||||
std::set<KRAABB> expired_visible_bounds;
|
||||
for(std::map<KRAABB, int>::iterator visible_bounds_itr = visibleBounds.begin(); visible_bounds_itr != visibleBounds.end(); visible_bounds_itr++) {
|
||||
if((*visible_bounds_itr).second == -1 || (*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < getContext().getCurrentFrame()) {
|
||||
expired_visible_bounds.insert((*visible_bounds_itr).first);
|
||||
}
|
||||
}
|
||||
for(std::set<KRAABB>::iterator expired_visible_bounds_itr = expired_visible_bounds.begin(); expired_visible_bounds_itr != expired_visible_bounds.end(); expired_visible_bounds_itr++) {
|
||||
visibleBounds.erase(*expired_visible_bounds_itr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<KRLight *> lights;
|
||||
|
||||
@@ -112,18 +127,6 @@ void KRScene::render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, co
|
||||
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
|
||||
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, true);
|
||||
}
|
||||
|
||||
|
||||
// Expire cached occlusion test results
|
||||
std::set<KRAABB> expired_visible_bounds;
|
||||
for(std::map<KRAABB, int>::iterator visible_bounds_itr = visibleBounds.begin(); visible_bounds_itr != visibleBounds.end(); visible_bounds_itr++) {
|
||||
if((*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < getContext().getCurrentFrame()) {
|
||||
expired_visible_bounds.insert((*visible_bounds_itr).first);
|
||||
}
|
||||
}
|
||||
for(std::set<KRAABB>::iterator expired_visible_bounds_itr = expired_visible_bounds.begin(); expired_visible_bounds_itr != expired_visible_bounds.end(); expired_visible_bounds_itr++) {
|
||||
visibleBounds.erase(*expired_visible_bounds_itr);
|
||||
}
|
||||
}
|
||||
|
||||
void KRScene::render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
|
||||
@@ -145,6 +148,9 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBo
|
||||
// Schedule a pass to perform the rendering
|
||||
remainingOctrees.push_back(pOctreeNode);
|
||||
}
|
||||
} else {
|
||||
// Record -1 to indicate that the visibility test had failed
|
||||
visibleBounds[octreeBounds] = -1;
|
||||
}
|
||||
|
||||
GLDEBUG(glDeleteQueriesEXT(1, &pOctreeNode->m_occlusionQuery));
|
||||
@@ -180,15 +186,20 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBo
|
||||
// If the previous frame rendered this octree, then attempt to render it in this frame without performing a pre-occlusion test
|
||||
std::map<KRAABB, int>::iterator match_itr = visibleBounds.find(octreeBounds);
|
||||
if(match_itr != visibleBounds.end()) {
|
||||
bVisible = true;
|
||||
|
||||
// We set bNeedOcclusionTest to false only when the previous occlusion test is old and we need to perform an occlusion test to record if this octree node was visible for the next frame
|
||||
bNeedOcclusionTest = false;
|
||||
if((*match_itr).second == -1) {
|
||||
// We have already tested these bounds with a negative result
|
||||
bNeedOcclusionTest = false;
|
||||
} else {
|
||||
bVisible = true;
|
||||
|
||||
// We set bNeedOcclusionTest to false only when the previous occlusion test is old and we need to perform an occlusion test to record if this octree node was visible for the next frame
|
||||
bNeedOcclusionTest = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!bVisible) {
|
||||
if(!bVisible && bNeedOcclusionTest) {
|
||||
// Optimization: If this is an empty octree node with only a single child node, then immediately try to render the child node without an occlusion test for this higher level, as it would be more expensive than the occlusion test for the child
|
||||
if(pOctreeNode->getSceneNodes().empty()) {
|
||||
int child_count = 0;
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||
void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame);
|
||||
|
||||
void render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
|
||||
|
||||
|
||||
@@ -43,8 +43,10 @@ void KRTexture::resize(int max_dim)
|
||||
if(max_dim == 0) {
|
||||
releaseHandle();
|
||||
} else {
|
||||
int requiredMemoryTransfer = getThroughputRequiredForResize(max_dim);
|
||||
int requiredMemoryDelta = getMemRequiredForSize(max_dim) - getMemSize();
|
||||
int target_dim = max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
|
||||
int requiredMemoryTransfer = getThroughputRequiredForResize(target_dim);
|
||||
int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize();
|
||||
|
||||
if(requiredMemoryDelta) {
|
||||
// Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory)
|
||||
@@ -59,11 +61,11 @@ void KRTexture::resize(int max_dim)
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_current_lod_max_dim != max_dim || m_iHandle == 0) {
|
||||
if(m_current_lod_max_dim != target_dim || m_iHandle == 0) {
|
||||
releaseHandle();
|
||||
}
|
||||
if(m_iHandle == 0) {
|
||||
if(!createGLTexture(max_dim)) {
|
||||
if(!createGLTexture(target_dim)) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -74,30 +76,43 @@ void KRTexture::resize(int max_dim)
|
||||
|
||||
GLuint KRTexture::getHandle() {
|
||||
if(m_iHandle == 0) {
|
||||
resize(getContext().KRENGINE_MIN_TEXTURE_DIM);
|
||||
//resize(getContext().KRENGINE_MIN_TEXTURE_DIM);
|
||||
resize(m_min_lod_max_dim);
|
||||
}
|
||||
|
||||
m_last_frame_used = getContext().getCurrentFrame();
|
||||
|
||||
resetPoolExpiry();
|
||||
return m_iHandle;
|
||||
}
|
||||
|
||||
void KRTexture::resetPoolExpiry()
|
||||
{
|
||||
m_last_frame_used = getContext().getCurrentFrame();
|
||||
}
|
||||
|
||||
long KRTexture::getThroughputRequiredForResize(int max_dim)
|
||||
{
|
||||
// Calculate the throughput required for GPU texture upload if the texture is resized to max_dim.
|
||||
// This default behaviour assumes that the texture will need to be deleted and regenerated to change the maximum mip-map level.
|
||||
// If an OpenGL extension is present that allows a texture to be resized incrementally, then this method should be overridden
|
||||
if(max_dim != m_current_lod_max_dim && max_dim != 0) {
|
||||
int requiredMemory = getMemRequiredForSize(max_dim);
|
||||
int requiredMemoryDelta = requiredMemory - getMemSize();
|
||||
|
||||
if(max_dim == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
int target_dim = max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = target_dim;
|
||||
|
||||
if(requiredMemoryDelta == 0) {
|
||||
// Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory)
|
||||
|
||||
if(target_dim != m_current_lod_max_dim) {
|
||||
int requiredMemory = getMemRequiredForSize(target_dim);
|
||||
int requiredMemoryDelta = requiredMemory - getMemSize();
|
||||
|
||||
if(requiredMemoryDelta == 0) {
|
||||
// Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory)
|
||||
return 0;
|
||||
}
|
||||
return requiredMemory;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return requiredMemory;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ public:
|
||||
|
||||
long getLastFrameUsed();
|
||||
|
||||
virtual void resetPoolExpiry();
|
||||
|
||||
protected:
|
||||
virtual bool createGLTexture(int lod_max_dim) = 0;
|
||||
GLuint getHandle();
|
||||
|
||||
@@ -75,7 +75,7 @@ bool KRTexture2D::createGLTexture(int lod_max_dim) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void KRTexture2D::bind() {
|
||||
void KRTexture2D::bind() {
|
||||
GLuint handle = getHandle();
|
||||
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle));
|
||||
|
||||
@@ -88,18 +88,33 @@ bool KRTextureCube::createGLTexture(int lod_max_dim)
|
||||
|
||||
long KRTextureCube::getMemRequiredForSize(int max_dim)
|
||||
{
|
||||
int target_dim = max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
|
||||
|
||||
long memoryRequired = 0;
|
||||
for(int i=0; i<6; i++) {
|
||||
std::string faceName = m_name + SUFFIXES[i];
|
||||
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str());
|
||||
if(faceTexture) {
|
||||
memoryRequired += faceTexture->getMemRequiredForSize(max_dim);
|
||||
memoryRequired += faceTexture->getMemRequiredForSize(target_dim);
|
||||
}
|
||||
}
|
||||
return memoryRequired;
|
||||
}
|
||||
|
||||
|
||||
void KRTextureCube::resetPoolExpiry()
|
||||
{
|
||||
KRTexture::resetPoolExpiry();
|
||||
for(int i=0; i<6; i++) {
|
||||
std::string faceName = m_name + SUFFIXES[i];
|
||||
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str());
|
||||
if(faceTexture) {
|
||||
faceTexture->resetPoolExpiry(); // Ensure that side of cube maps do not expire from the texture pool prematurely, as they are referenced indirectly
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KRTextureCube::bind()
|
||||
{
|
||||
GLuint handle = getHandle();
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
virtual void bind();
|
||||
virtual long getMemRequiredForSize(int max_dim);
|
||||
|
||||
virtual void resetPoolExpiry();
|
||||
|
||||
private:
|
||||
virtual bool createGLTexture(int lod_max_dim);
|
||||
|
||||
@@ -140,7 +140,11 @@ void KRTextureManager::startFrame()
|
||||
|
||||
void KRTextureManager::endFrame()
|
||||
{
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KRTextureManager::balanceTextureMemory()
|
||||
|
||||
@@ -152,6 +152,9 @@ KRTexturePVR::~KRTexturePVR() {
|
||||
|
||||
long KRTexturePVR::getMemRequiredForSize(int max_dim)
|
||||
{
|
||||
int target_dim = max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = target_dim;
|
||||
|
||||
// Determine how much memory will be consumed
|
||||
int width = m_iWidth;
|
||||
int height = m_iHeight;
|
||||
@@ -159,7 +162,7 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
|
||||
|
||||
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
|
||||
dataBlockStruct block = *itr;
|
||||
if(width <= max_dim && height <= max_dim) {
|
||||
if(width <= target_dim && height <= target_dim) {
|
||||
memoryRequired += block.length;
|
||||
}
|
||||
|
||||
@@ -177,8 +180,10 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
|
||||
}
|
||||
|
||||
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed)
|
||||
{
|
||||
|
||||
{
|
||||
int target_dim = lod_max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = target_dim;
|
||||
|
||||
GLenum err;
|
||||
|
||||
if(m_blocks.size() == 0) {
|
||||
@@ -195,7 +200,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
int i=0;
|
||||
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
|
||||
dataBlockStruct block = *itr;
|
||||
if(width <= lod_max_dim && height <= lod_max_dim) {
|
||||
if(width <= target_dim && height <= target_dim) {
|
||||
memoryRequired += block.length;
|
||||
if(width > current_lod_max_dim) {
|
||||
current_lod_max_dim = width;
|
||||
|
||||
Reference in New Issue
Block a user