Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Graphics/decaltextures.cpp')
-rw-r--r--Source/Graphics/decaltextures.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/Source/Graphics/decaltextures.cpp b/Source/Graphics/decaltextures.cpp
new file mode 100644
index 00000000..89636eb3
--- /dev/null
+++ b/Source/Graphics/decaltextures.cpp
@@ -0,0 +1,194 @@
+//-----------------------------------------------------------------------------
+// Name: decaltextures.cpp
+// Developer: Wolfire Games LLC
+// Description:
+// License: Read below
+//-----------------------------------------------------------------------------
+//
+//
+// Copyright 2022 Wolfire Games LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-----------------------------------------------------------------------------
+#include "decaltextures.h"
+
+#include <Internal/config.h>
+#include <Internal/hardware_specs.h>
+#include <Internal/profiler.h>
+
+#include <Main/engine.h>
+#include <Math/ivec2math.h>
+#include <Logging/logdata.h>
+
+#include <cmath>
+
+bool kUseDecalNormals = false;
+
+//We define this because windows is missing log2
+double Log2( double n )
+{
+ // log(n)/log(2) is log2.
+ return log( n ) / log( 2 );
+}
+
+
+DecalTexture::DecalTexture()
+{
+
+}
+
+DecalTexture::~DecalTexture()
+{
+ DecalTextures* dt = DecalTextures::Instance();
+
+ if( dt->initialized )
+ {
+ if(colornode_ref.valid())
+ dt->colornodetree->FreeNode( colornode_ref );
+ if(normalnode_ref.valid())
+ dt->normalnodetree->FreeNode( normalnode_ref );
+ }
+}
+
+DecalTextures::DecalTextures() :
+colornodetree(NULL),
+normalnodetree(NULL),
+coloratlas(NULL),
+normalatlas(NULL),
+initialized(false)
+{
+
+}
+
+DecalTextures::~DecalTextures()
+{
+ delete colornodetree;
+ colornodetree = NULL;
+ delete normalnodetree;
+ normalnodetree = NULL;
+ delete coloratlas;
+ coloratlas = NULL;
+ delete normalatlas;
+ normalatlas = NULL;
+ initialized = false;
+}
+
+void DecalTextures::Init()
+{
+ kUseDecalNormals = config["decal_normals"].toNumber<bool>();
+ int s = GetGLMaxTextureSize();
+ s = (int)std::pow(2.0,(int)std::min((int)Log2(s),13));
+
+ s = s/Graphics::Instance()->config_.texture_reduction_factor();
+
+ ivec2 dim(s,s);
+ PROFILER_ENTER(g_profiler_ctx, "Create AtlasNodeTrees");
+ colornodetree = new AtlasNodeTree(dim,32);
+ normalnodetree = new AtlasNodeTree(dim,32);
+ PROFILER_LEAVE(g_profiler_ctx);
+ PROFILER_ENTER(g_profiler_ctx, "Create Texture Atlases");
+ coloratlas = new TextureAtlas(*colornodetree, TextureData::sRGB);
+ Textures::Instance()->SetTextureName(coloratlas->atlas_texture, "Decal Color Atlas");
+ normalatlas = new TextureAtlas(*normalnodetree, TextureData::Linear);
+ Textures::Instance()->SetTextureName(normalatlas->atlas_texture, "Decal Normal Atlas");
+ PROFILER_LEAVE(g_profiler_ctx);
+ initialized = true;
+}
+
+void DecalTextures::Draw()
+{
+ coloratlas->Draw();
+ if (kUseDecalNormals) {
+ normalatlas->Draw();
+ }
+}
+
+static DecalTextures* instance = NULL;
+
+DecalTextures* DecalTextures::Instance()
+{
+ if( instance == NULL )
+ {
+ instance = new DecalTextures();
+ }
+
+ return instance;
+}
+
+void DecalTextures::Dispose()
+{
+ delete instance;
+ instance = NULL;
+}
+
+void DecalTextures::Clear()
+{
+ colornodetree->Clear();
+ normalnodetree->Clear();
+}
+
+RC_DecalTexture DecalTextures::allocateTexture( std::string color, std::string norm )
+{
+ //This will, thankfully, not go straight into VRAM.
+ RC_DecalTexture rc_dt;
+
+ TextureAssetRef color_tex = Engine::Instance()->GetAssetManager()->LoadSync<TextureAsset>( color );
+ TextureAssetRef normal_tex = Engine::Instance()->GetAssetManager()->LoadSync<TextureAsset>( norm );
+
+ // we put these in a compressed atlas so they must be compressed
+ if (!Textures::Instance()->IsCompressed(color_tex)) {
+ LOGW << "Reloading a texture as compressed, this is unexpected" << std::endl;
+ if (!Textures::Instance()->ReloadAsCompressed(color_tex)) {
+ LOGE << "Failed to re-save color texture " << color << " as compressed" << std::endl;
+ }
+ }
+ if (!Textures::Instance()->IsCompressed(normal_tex)) {
+ LOGW << "Reloading a texture as compressed, this is unexpected" << std::endl;
+ if (!Textures::Instance()->ReloadAsCompressed(normal_tex)) {
+ LOGE << "Failed to re-save normal texture " << norm << " as compressed" << std::endl;
+ }
+ }
+
+ int reduction_factor = Graphics::Instance()->config_.texture_reduction_factor();
+ ivec2 color_tex_dim = ivec2(Textures::Instance()->getWidth(color_tex),Textures::Instance()->getWidth(color_tex)) / reduction_factor;
+ ivec2 normal_tex_dim = ivec2(Textures::Instance()->getHeight(normal_tex),Textures::Instance()->getHeight(normal_tex)) / reduction_factor;
+
+ {
+ rc_dt->colornode_ref = colornodetree->RetrieveNode(color_tex_dim);
+
+ if( rc_dt->colornode_ref.valid() )
+ {
+ rc_dt->color_texture_ref = coloratlas->SetTextureToNode(color,rc_dt->colornode_ref);
+ }
+ else
+ {
+ LOGE << "Unable to allocate atlas space for decal color." << std::endl;
+ }
+ }
+
+ {
+ rc_dt->normalnode_ref = normalnodetree->RetrieveNode(normal_tex_dim);
+
+ if( rc_dt->normalnode_ref.valid() )
+ {
+ rc_dt->normal_texture_ref = normalatlas->SetTextureToNode(norm, rc_dt->normalnode_ref);
+ }
+ else
+ {
+ LOGE << "Unable to allocate atlas space for decal normals." << std::endl;
+ }
+ }
+
+ return rc_dt;
+}