Skip to content
This repository was archived by the owner on Apr 29, 2024. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class StormEngine(ConanFile):

# dependencies used in deploy binaries
# conan-center
requires = ["zlib/1.2.13", "spdlog/1.9.2", "fast_float/3.4.0", "mimalloc/2.0.3", "sentry-native/0.5.0",
requires = ["zlib/1.2.13", "spdlog/1.9.2", "fast_float/3.4.0", "mimalloc/2.0.3", "freeimage/3.18.0", "sentry-native/0.5.0",
# storm.jfrog.io
"directx/9.0@storm/prebuilt", "fmod/2.02.05@storm/prebuilt"]
# aux dependencies (e.g. for tests)
Expand All @@ -37,6 +37,15 @@ def requirements(self):
self.requires("steamworks/1.5.1@storm/prebuilt")
if self.options.conan_sdl:
self.requires("sdl/2.0.18")
self.options["freeimage"].with_jpeg = "libjpeg-turbo"
self.options["freeimage"].with_png = True
self.options["freeimage"].with_tiff = False
self.options["freeimage"].with_jpeg2000 = False
self.options["freeimage"].with_openexr = False
self.options["freeimage"].with_eigen = False
self.options["freeimage"].with_webp = False
self.options["freeimage"].with_raw = False
self.options["freeimage"].with_jxr = False

generators = "cmake_multi"

Expand Down
2 changes: 1 addition & 1 deletion src/libs/renderer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ endif()
STORM_SETUP(
TARGET_NAME renderer
TYPE storm_module
DEPENDENCIES core directx util ${SYSTEM_DEPS}
DEPENDENCIES core directx util freeimage ${SYSTEM_DEPS}
)
16 changes: 16 additions & 0 deletions src/libs/renderer/include/storm/renderer/image.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

namespace storm::renderer
{

class Image {
public:
size_t width{};
size_t height{};
size_t pitch{};
uint32_t type{};
uint32_t bpp{};
uint8_t *data{};
};

} // namespace storm::renderer
27 changes: 27 additions & 0 deletions src/libs/renderer/include/storm/renderer/image_loader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <istring.hpp>

#include "image.hpp"

#include <memory>

namespace storm::renderer
{

class ImageLoader final
{
public:
ImageLoader();
~ImageLoader();

std::unique_ptr<Image> LoadImageFromFile(const istring &path);

static void CopyImageToBuffer(const Image& image, uint8_t *destination);

private:
class Impl;
std::unique_ptr<Impl> impl_;
};

} // namespace storm::renderer
61 changes: 39 additions & 22 deletions src/libs/renderer/src/s_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1461,7 +1461,7 @@ bool DX9RENDER::TextureLoad(int32_t t)
path_to_tex.replace_extension();
if (exists(path_to_tex))
{
return TextureLoadUsingD3DX(path_to_tex.string().c_str(), t);
return TextureLoadFromFile(path_to_tex.string().c_str(), t);
}
if (bTrace)
{
Expand Down Expand Up @@ -1768,32 +1768,49 @@ bool DX9RENDER::TextureLoad(int32_t t)
return true;
}

bool DX9RENDER::TextureLoadUsingD3DX(const char* path, int32_t t)
bool DX9RENDER::TextureLoadFromFile(const char* path, int32_t t)
{
#ifdef _WIN32 // TextureLoadUsingD3DX - used only for loading raw Targa
// TODO: reimplement the whole thing in a tidy way
IDirect3DTexture9 *pTex;
if(CHECKD3DERR(D3DXCreateTextureFromFileA(d3d9, path, &pTex)))
{
auto image = imageLoader_.LoadImageFromFile(path);

if (image) {
IDirect3DTexture9 *texture;
const auto d3d_format = image->bpp == 24 ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
if (CHECKD3DERR(d3d9->CreateTexture(image->width, image->height, 0, 0, d3d_format, D3DPOOL_MANAGED, &texture,
NULL))) {
delete Textures[t].name;
Textures[t].name = nullptr;
return false;
}

IDirect3DSurface9 *surface = nullptr;
texture->GetSurfaceLevel(0, &surface);
D3DLOCKED_RECT rect;
if (CHECKD3DERR(surface->LockRect(&rect, nullptr, 0))) {
delete Textures[t].name;
Textures[t].name = nullptr;
return {};
}
imageLoader_.CopyImageToBuffer(*image, static_cast<uint8_t *>(rect.pBits));
surface->UnlockRect();
surface->Release();

D3DSURFACE_DESC desc;
texture->GetLevelDesc(0, &desc);

Textures[t].hash = 0;
Textures[t].ref = 1;
Textures[t].d3dtex = texture;
Textures[t].isCubeMap = false;
Textures[t].dwSize = desc.Height * desc.Width * 4;
Textures[t].loaded = true;

return true;
}
else {
delete Textures[t].name;
Textures[t].name = nullptr;
return false;
}

D3DSURFACE_DESC desc;
pTex->GetLevelDesc(0, &desc);

Textures[t].hash = 0;
Textures[t].ref = 1;
Textures[t].d3dtex = pTex;
Textures[t].isCubeMap = false;
Textures[t].dwSize = desc.Height * desc.Width * 4;
Textures[t].loaded = true;

return true;
#else
return false;
#endif
}

IDirect3DBaseTexture9 *DX9RENDER::GetBaseTexture(int32_t iTexture)
Expand Down
5 changes: 4 additions & 1 deletion src/libs/renderer/src/s_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "d3d9types.h"
#include "script_libriary.h"
#include "storm/renderer/image_loader.hpp"

#include <stack>
#include <vector>
Expand Down Expand Up @@ -462,6 +463,8 @@ class DX9RENDER : public VDX9RENDER
IDirect3D9 *d3d;
HWND hwnd;

storm::renderer::ImageLoader imageLoader_;

CVECTOR Pos, Ang;
float Fov;

Expand Down Expand Up @@ -599,5 +602,5 @@ class DX9RENDER : public VDX9RENDER
std::string screenshotExt;

bool TextureLoad(int32_t texid);
bool TextureLoadUsingD3DX(const char *path, int32_t texid);
bool TextureLoadFromFile(const char *path, int32_t t);
};
118 changes: 118 additions & 0 deletions src/libs/renderer/src/storm/renderer/image_loader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include "storm/renderer/image_loader.hpp"

#include <FreeImage.h>

namespace storm::renderer
{

namespace {

class FreeImage final {
public:
FreeImage();
~FreeImage();
};

FreeImage::FreeImage()
{
FreeImage_Initialise(false);
}

FreeImage::~FreeImage()
{
FreeImage_DeInitialise();
}

} // namespace

class ImageLoader::Impl
{
public:
Impl();

std::shared_ptr<FreeImage> freeImage_;

static std::weak_ptr<FreeImage> FreeImageInstance;

static std::shared_ptr<FreeImage> getGlobalFreeImageInstance();

friend ImageLoader;
};

std::weak_ptr<FreeImage> ImageLoader::Impl::FreeImageInstance{};

ImageLoader::ImageLoader()
: impl_(std::make_unique<Impl>())
{

}

ImageLoader::~ImageLoader() = default;

std::unique_ptr<Image> ImageLoader::LoadImageFromFile(const istring &path)
{
const auto image_type = FreeImage_GetFileType(path.c_str(), 0);

if (image_type != FIF_UNKNOWN)
{
FIBITMAP *image = FreeImage_Load(image_type, path.c_str(), 0);
auto result = std::make_unique<Image>();
result->width = FreeImage_GetWidth(image);
result->height = FreeImage_GetHeight(image);
result->pitch = FreeImage_GetPitch(image);
result->type = FreeImage_GetImageType(image);
result->bpp = FreeImage_GetBPP(image);
result->data = FreeImage_GetBits(image);
return result;
}
else {
return {};
}
}

void ImageLoader::CopyImageToBuffer(const Image& image, uint8_t *destination)
{
if (image.bpp == 24) {
for(size_t y = image.height; y > 0; y--) {
BYTE *pixel = image.data + (y - 1) * image.pitch;
for(size_t x = 0; x < image.width; x++) {https://www.piratesahoy.net/threads/build-14-gamma-version-last-update-6th-april-2023.33573/
destination[0] = pixel[FI_RGBA_BLUE];
destination[1] = pixel[FI_RGBA_GREEN];
destination[2] = pixel[FI_RGBA_RED];
destination[3] = 255;
destination += 4;
pixel += 3;
}
}
}
else {
for(size_t y = image.height; y > 0; y--) {
BYTE *pixel = image.data + (y - 1) * image.pitch;
for(size_t x = 0; x < image.width; x++) {
destination[0] = pixel[FI_RGBA_BLUE];
destination[1] = pixel[FI_RGBA_GREEN];
destination[2] = pixel[FI_RGBA_RED];
destination[3] = pixel[FI_RGBA_ALPHA];
destination += 4;
pixel += 4;
}
}
}
}

ImageLoader::Impl::Impl()
{
freeImage_ = getGlobalFreeImageInstance();
}

std::shared_ptr<FreeImage> ImageLoader::Impl::getGlobalFreeImageInstance()
{
auto free_image = FreeImageInstance.lock();
if (!free_image) {
free_image = std::make_shared<FreeImage>();
FreeImageInstance = free_image;
}
return free_image;
}

} // namespace storm::renderer