Skip to content

Commit 8f3e655

Browse files
committed
Load textures directly via stb_image instead of SOIL2
1 parent 99bfcf9 commit 8f3e655

2 files changed

Lines changed: 46 additions & 32 deletions

File tree

src/libprojectM/Renderer/TextureManager.cpp

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
#include "Renderer/MilkdropNoise.hpp"
66
#include "Renderer/Texture.hpp"
77

8+
#include <Logging.hpp>
89
#include <Utils.hpp>
910

10-
#include <Logging.hpp>
11-
#include <SOIL2/SOIL2.h>
11+
#include <SOIL2/stb_image.h>
1212

1313
#include <algorithm>
14+
#include <cstdlib>
1415
#include <memory>
1516
#include <random>
1617
#include <vector>
@@ -70,24 +71,27 @@ void TextureManager::Preload()
7071

7172
int width{};
7273
int height{};
74+
int channels{};
7375

74-
unsigned int tex = SOIL_load_OGL_texture_from_memory(
75-
M_data,
76-
M_bytes,
77-
SOIL_LOAD_AUTO,
78-
SOIL_CREATE_NEW_ID,
79-
SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MULTIPLY_ALPHA);
76+
{
77+
std::unique_ptr<stbi_uc, decltype(&free)> const imageData(stbi_load_from_memory(M_data, M_bytes, &width, &height, &channels, 4), free);
8078

81-
m_textures["idlem"] = std::make_shared<Texture>("idlem", tex, GL_TEXTURE_2D, width, height, false);;
79+
if (imageData.get() != nullptr)
80+
{
81+
auto format = TextureFormatFromChannels(channels);
82+
m_textures["idlem"] = std::make_shared<Texture>("idlem", reinterpret_cast<const void*>(imageData.get()), GL_TEXTURE_2D, width, height, 0, format, format, GL_UNSIGNED_BYTE, false);
83+
}
84+
}
8285

83-
tex = SOIL_load_OGL_texture_from_memory(
84-
headphones_data,
85-
headphones_bytes,
86-
SOIL_LOAD_AUTO,
87-
SOIL_CREATE_NEW_ID,
88-
SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MULTIPLY_ALPHA);
86+
{
87+
std::unique_ptr<stbi_uc, decltype(&free)> const imageData(stbi_load_from_memory(headphones_data, headphones_bytes, &width, &height, &channels, 4), free);
8988

90-
m_textures["idleheadphones"] = std::make_shared<Texture>("idleheadphones", tex, GL_TEXTURE_2D, width, height, false);;
89+
if (imageData.get() != nullptr)
90+
{
91+
auto format = TextureFormatFromChannels(channels);
92+
m_textures["idleheadphones"] = std::make_shared<Texture>("idleheadphones", reinterpret_cast<const void*>(imageData.get()), GL_TEXTURE_2D, width, height, 0, format, format, GL_UNSIGNED_BYTE, false);
93+
}
94+
}
9195

9296
// Noise textures
9397
m_textures["noise_lq_lite"] = MilkdropNoise::LowQualityLite();
@@ -184,7 +188,8 @@ auto TextureManager::TryLoadingTexture(const std::string& name) -> TextureSample
184188
if (texture)
185189
{
186190
LOG_DEBUG("[TextureManager] Loaded texture \"" + unqualifiedName + "\" from file: " + file.filePath);
187-
return {texture, m_samplers.at({wrapMode, filterMode}), name, unqualifiedName};;
191+
return {texture, m_samplers.at({wrapMode, filterMode}), name, unqualifiedName};
192+
;
188193
}
189194
}
190195

@@ -207,30 +212,20 @@ auto TextureManager::LoadTexture(const ScannedFile& file) -> std::shared_ptr<Tex
207212
int height{};
208213
int channels{};
209214

210-
std::unique_ptr<unsigned char, decltype(&SOIL_free_image_data)> imageData(SOIL_load_image(file.filePath.c_str(), &width, &height, &channels, SOIL_LOAD_RGBA), SOIL_free_image_data);
215+
std::unique_ptr<stbi_uc, decltype(&free)> imageData(stbi_load(file.filePath.c_str(), &width, &height, &channels, 4), free);
211216

212-
if (imageData == nullptr)
217+
if (imageData.get() == nullptr)
213218
{
214219
LOG_DEBUG("[TextureManager] Failed to decode image data.");
215220
return {};
216221
}
217222

218-
unsigned int const tex = SOIL_create_OGL_texture(
219-
imageData.get(),
220-
&width, &height, SOIL_LOAD_RGBA,
221-
SOIL_CREATE_NEW_ID,
222-
SOIL_FLAG_MULTIPLY_ALPHA);
223+
auto format = TextureFormatFromChannels(channels);
224+
auto newTexture = std::make_shared<Texture>(unqualifiedName, reinterpret_cast<const void*>(imageData.get()), GL_TEXTURE_2D, width, height, 0, format, format, GL_UNSIGNED_BYTE, true);
223225

224226
imageData.reset();
225227

226-
if (tex == 0)
227-
{
228-
LOG_DEBUG("[TextureManager] Failed to create GPU texture from image data.");
229-
return {};
230-
}
231-
232-
uint32_t memoryBytes = width * height * 4; // RGBA, unsigned byte color channels.
233-
auto newTexture = std::make_shared<Texture>(unqualifiedName, tex, GL_TEXTURE_2D, width, height, true);
228+
uint32_t const memoryBytes = width * height * 4; // RGBA, unsigned byte color channels.
234229
m_textures[file.lowerCaseBaseName] = newTexture;
235230
m_textureStats.insert({file.lowerCaseBaseName, {memoryBytes}});
236231

@@ -369,5 +364,22 @@ void TextureManager::ScanTextures()
369364
}
370365
}
371366

367+
uint32_t TextureManager::TextureFormatFromChannels(int channels)
368+
{
369+
switch (channels)
370+
{
371+
case 1:
372+
return GL_RED;
373+
case 2:
374+
return GL_RG;
375+
case 3:
376+
return GL_RGB;
377+
case 4:
378+
return GL_RGBA;
379+
default:
380+
return 0;
381+
}
382+
}
383+
372384
} // namespace Renderer
373385
} // namespace libprojectM

src/libprojectM/Renderer/TextureManager.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class TextureManager
9090

9191
void ScanTextures();
9292

93+
static uint32_t TextureFormatFromChannels(int channels);
94+
9395
std::vector<std::string> m_textureSearchPaths; //!< Search paths to scan for textures.
9496
std::string m_currentPresetDir; //!< Path of the current preset to add to the search list.
9597
std::vector<ScannedFile> m_scannedTextureFiles; //!< The cached list with scanned texture files.

0 commit comments

Comments
 (0)