Skip to content

Commit 7357cb0

Browse files
committed
feat: use paths and string keys in texture library
The texture library needs string keys to identify "shaders", they remain narrow UTF-8 as all image paths in use are ASCII and while there's now proper path use for texture loading it doesn't need to permeate quite that far into that kind of performance-sensitive place.
1 parent 99be82d commit 7357cb0

File tree

6 files changed

+46
-53
lines changed

6 files changed

+46
-53
lines changed

engine/render.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class r_IRenderer {
7777
virtual void BeginFrame() = 0;
7878
virtual void EndFrame() = 0;
7979

80-
virtual r_shaderHnd_c* RegisterShader(const char* name, int flags) = 0;
80+
virtual r_shaderHnd_c* RegisterShader(std::string_view name, int flags) = 0;
8181
virtual r_shaderHnd_c* RegisterShaderFromImage(std::unique_ptr<image_c> img, int flags) = 0;
8282
virtual void GetShaderImageSize(r_shaderHnd_c* hnd, int &width, int &height) = 0;
8383
virtual void SetShaderLoadingPriority(r_shaderHnd_c* hnd, int pri) = 0;

engine/render/r_main.cpp

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,40 +45,39 @@ enum r_takeScreenshot_e {
4545
class r_shader_c {
4646
public:
4747
r_renderer_c* renderer;
48-
char* name;
48+
std::string name;
4949
dword nameHash;
5050
int refCount;
5151
r_tex_c* tex;
5252

53-
r_shader_c(r_renderer_c* renderer, const char* shname, int flags);
54-
r_shader_c(r_renderer_c* renderer, const char* shname, int flags, std::unique_ptr<image_c> img);
53+
r_shader_c(r_renderer_c* renderer, std::string_view shname, int flags);
54+
r_shader_c(r_renderer_c* renderer, std::string_view shname, int flags, std::unique_ptr<image_c> img);
5555
~r_shader_c();
5656
};
5757

58-
r_shader_c::r_shader_c(r_renderer_c* renderer, const char* shname, int flags)
58+
r_shader_c::r_shader_c(r_renderer_c* renderer, std::string_view shname, int flags)
5959
: renderer(renderer)
6060
{
61-
name = AllocString(shname);
62-
nameHash = StringHash(shname, 0xFFFF);
61+
name = shname;
62+
nameHash = StringHash(name.c_str(), 0xFFFF);
6363
refCount = 0;
6464
tex = new r_tex_c(renderer->texMan, name, flags);
6565
if (tex->error) {
66-
renderer->sys->con->Warning("couldn't load texture '%s'", name);
66+
renderer->sys->con->Warning("couldn't load texture '%s'", name.c_str());
6767
}
6868
}
6969

70-
r_shader_c::r_shader_c(r_renderer_c* renderer, const char* shname, int flags, std::unique_ptr<image_c> img)
70+
r_shader_c::r_shader_c(r_renderer_c* renderer, std::string_view shname, int flags, std::unique_ptr<image_c> img)
7171
: renderer(renderer)
7272
{
73-
name = AllocString(shname);
74-
nameHash = StringHash(shname, 0xFFFF);
73+
name = shname;
74+
nameHash = StringHash(name.c_str(), 0xFFFF);
7575
refCount = 0;
7676
tex = new r_tex_c(renderer->texMan, std::move(img), flags);
7777
}
7878

7979
r_shader_c::~r_shader_c()
8080
{
81-
FreeString(name);
8281
delete tex;
8382
}
8483

@@ -1570,19 +1569,20 @@ void r_renderer_c::PurgeShaders()
15701569
}
15711570
}
15721571

1573-
r_shaderHnd_c* r_renderer_c::RegisterShader(const char* shname, int flags)
1572+
r_shaderHnd_c* r_renderer_c::RegisterShader(std::string_view shname, int flags)
15741573
{
1575-
if (*shname == 0) {
1574+
if (shname.empty()) {
15761575
return NULL;
15771576
}
15781577

1579-
dword nameHash = StringHash(shname, 0xFFFF);
1578+
std::string name(shname);
1579+
dword nameHash = StringHash(name, 0xFFFF);
15801580
int newId = -1;
15811581
for (int s = 0; s < numShader; s++) {
15821582
if (!shaderList[s]) {
15831583
newId = s;
15841584
}
1585-
else if (shaderList[s]->nameHash == nameHash && _stricmp(shname, shaderList[s]->name) == 0 && shaderList[s]->tex->flags == flags) {
1585+
else if (shaderList[s]->nameHash == nameHash && _stricmp(name.c_str(), shaderList[s]->name.c_str()) == 0 && shaderList[s]->tex->flags == flags) {
15861586
// Shader already exists, return a new handle for it
15871587
// Ensure texture is loaded as soon as possible
15881588
shaderList[s]->tex->ForceLoad();
@@ -1930,7 +1930,7 @@ void r_renderer_c::DoScreenshot(image_c* i, int type, const char* ext)
19301930
// Flip and convert the image to RGB
19311931
int const readSpan = xs * 4;
19321932
int const writeSpan = xs * 3;
1933-
std::vector<byte> ss(writeSize); // This is a raw pointer as ownership is taken by the image object.
1933+
std::vector<byte> ss(writeSize);
19341934
byte* p1 = sbuf.data();
19351935
byte* p2 = ss.data() + writeSize - writeSpan;
19361936
for (int y = 0; y < ys; ++y, p2 -= writeSpan * 2) {
@@ -1949,26 +1949,23 @@ void r_renderer_c::DoScreenshot(image_c* i, int type, const char* ext)
19491949

19501950
time_t curTime;
19511951
time(&curTime);
1952-
std::string ssname = fmt::format(CFG_DATAPATH "Screenshots/{:%m%d%y_%H%M%S}.{}",
1953-
fmt::localtime(curTime), ext);
1954-
// curTimeSt.tm_mon+1, curTimeSt.tm_mday, curTimeSt.tm_year%100,
1955-
// curTimeSt.tm_hour, curTimeSt.tm_min, curTimeSt.tm_sec, ext);
1952+
auto ssPath = std::filesystem::u8path(fmt::format(CFG_DATAPATH "Screenshots/{:%m%d%y_%H%M%S}.{}",
1953+
fmt::localtime(curTime), ext));
19561954

19571955

19581956
// Make folder if it doesn't exist
19591957
std::error_code ec;
1960-
std::filesystem::create_directory(CFG_DATAPATH "Screenshots", ec);
1958+
std::filesystem::create_directories(ssPath.parent_path(), ec);
19611959
if (ec) {
19621960
sys->con->Print("Couldn't create screenshot folder!\n");
19631961
return;
19641962
}
19651963

1966-
if (i->Save(ssname.c_str())) {
1964+
if (i->Save(ssPath)) {
19671965
sys->con->Print("Couldn't write screenshot!\n");
19681966
return;
19691967
}
1970-
1971-
sys->con->Print(fmt::format("Wrote screenshot to {}\n", ssname).c_str());
1968+
sys->con->Print(fmt::format("Wrote screenshot to {}\n", ssPath.u8string()).c_str());
19721969
}
19731970

19741971
r_renderer_c::RenderTarget& r_renderer_c::GetDrawRenderTarget()

engine/render/r_main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class r_renderer_c: public r_IRenderer, public conCmdHandler_c {
7373
void BeginFrame();
7474
void EndFrame();
7575

76-
r_shaderHnd_c* RegisterShader(const char* shname, int flags);
76+
r_shaderHnd_c* RegisterShader(std::string_view shname, int flags);
7777
r_shaderHnd_c* RegisterShaderFromImage(std::unique_ptr<image_c> img, int flags);
7878
void GetShaderImageSize(r_shaderHnd_c* hnd, int &width, int &height);
7979
void SetShaderLoadingPriority(r_shaderHnd_c* hnd, int pri);

engine/render/r_texture.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ static void T_ResampleImage(byte* in, dword in_w, dword in_h, int in_comp, byte*
294294
// OpenGL Texture Class
295295
// ====================
296296

297-
r_tex_c::r_tex_c(r_ITexManager* manager, const char* fileName, int flags)
297+
r_tex_c::r_tex_c(r_ITexManager* manager, std::string_view fileName, int flags)
298298
{
299299
Init(manager, fileName, flags);
300300

@@ -307,7 +307,7 @@ r_tex_c::r_tex_c(r_ITexManager* manager, const char* fileName, int flags)
307307

308308
r_tex_c::r_tex_c(r_ITexManager* manager, std::unique_ptr<image_c> img, int flags)
309309
{
310-
Init(manager, NULL, flags);
310+
Init(manager, {}, flags);
311311

312312
// Direct upload
313313
img = BuildMipSet(std::move(img));
@@ -322,7 +322,7 @@ r_tex_c::~r_tex_c()
322322
glDeleteTextures(1, &texId);
323323
}
324324

325-
void r_tex_c::Init(r_ITexManager* i_manager, const char* i_fileName, int i_flags)
325+
void r_tex_c::Init(r_ITexManager* i_manager, std::string_view i_fileName, int i_flags)
326326
{
327327
manager = (t_manager_c*)i_manager;
328328
renderer = manager->renderer;
@@ -331,7 +331,7 @@ void r_tex_c::Init(r_ITexManager* i_manager, const char* i_fileName, int i_flags
331331
loadPri = 0;
332332
texId = 0;
333333
flags = i_flags;
334-
fileName = i_fileName ? i_fileName : "";
334+
fileName = i_fileName;
335335
fileWidth = 0;
336336
fileHeight = 0;
337337
}
@@ -482,15 +482,15 @@ void r_tex_c::LoadFile()
482482
}
483483

484484
// Try to load image file using appropriate loader
485-
std::string loadPath = fileName;
486-
img = std::unique_ptr<image_c>(image_c::LoaderForFile(renderer->sys->con, loadPath.c_str()));
485+
auto path = std::filesystem::u8path(fileName);
486+
img = std::unique_ptr<image_c>(image_c::LoaderForFile(renderer->sys->con, path));
487487
if (img) {
488488
auto sizeCallback = [this](int width, int height) {
489489
this->fileWidth = width;
490490
this->fileHeight = height;
491491
this->status = SIZE_KNOWN;
492492
};
493-
error = img->Load(loadPath.c_str(), sizeCallback);
493+
error = img->Load(path, sizeCallback);
494494
if ( !error ) {
495495
stackLayers = img->tex.layers();
496496
const bool is_async = !!(flags & TF_ASYNC);

engine/render/r_texture.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class r_tex_c {
3939
GLenum target{};
4040
size_t stackLayers = 1;
4141

42-
r_tex_c(class r_ITexManager* manager, const char* fileName, int flags);
42+
r_tex_c(class r_ITexManager* manager, std::string_view fileName, int flags);
4343
r_tex_c(class r_ITexManager* manager, std::unique_ptr<image_c> img, int flags);
4444
~r_tex_c();
4545

@@ -57,7 +57,7 @@ class r_tex_c {
5757
private:
5858
class t_manager_c* manager;
5959
class r_renderer_c* renderer;
60-
void Init(class r_ITexManager* manager, const char* fileName, int flags);
60+
void Init(class r_ITexManager* manager, std::string_view fileName, int flags);
6161
void Upload(image_c& img, int flags);
6262
std::unique_ptr<image_c> BuildMipSet(std::unique_ptr<image_c> img);
6363
};

ui_api.cpp

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -299,15 +299,14 @@ SG_LUA_CPP_FUN_BEGIN(NewArtHandle)
299299

300300
int n = lua_gettop(L);
301301
ui->LExpect(L, n >= 1, "Usage: NewArtHandle(fileName)");
302-
std::filesystem::path filePath = reader.ArgToString(1);
302+
std::filesystem::path filePath = std::filesystem::u8path(reader.ArgToString(1));
303303
if (filePath.is_relative())
304304
filePath = ui->scriptWorkDir / filePath;
305-
std::string fileName = filePath.generic_string();
306-
std::unique_ptr<image_c> img(image_c::LoaderForFile(ui->sys->con, fileName.c_str()));
305+
std::unique_ptr<image_c> img(image_c::LoaderForFile(ui->sys->con, filePath));
307306
if (!img)
308307
return 0;
309308

310-
if (img->Load(fileName.c_str()))
309+
if (img->Load(filePath))
311310
return 0;
312311

313312
const auto format = img->tex.format();
@@ -398,38 +397,35 @@ SG_LUA_CPP_FUN_BEGIN(imgHandleLoad)
398397
int n = lua_gettop(L);
399398
ui->LExpect(L, n >= 1, "Usage: imgHandle:Load(fileName[, flag1[, flag2...]])");
400399
ui->LExpect(L, lua_isstring(L, 1), "imgHandle:Load() argument 1: expected string, got %s", luaL_typename(L, 1));
401-
const char* fileName = lua_tostring(L, 1);
402-
char fullFileName[512];
403-
if (strchr(fileName, ':') || !ui->scriptWorkDir) {
404-
strcpy(fullFileName, fileName);
405-
}
406-
else {
407-
sprintf(fullFileName, "%s/%s", ui->scriptWorkDir, fileName);
400+
auto fileName = std::filesystem::u8path(lua_tostring(L, 1));
401+
if (!fileName.is_absolute() && !ui->scriptWorkDir.empty()) {
402+
fileName = ui->scriptWorkDir / fileName;
408403
}
409404
delete imgHandle->hnd;
410405
int flags = TF_NOMIPMAP;
411406
for (int f = 2; f <= n; f++) {
412407
if (!lua_isstring(L, f)) {
413408
continue;
414409
}
415-
const char* flag = lua_tostring(L, f);
416-
if (!strcmp(flag, "ASYNC")) {
410+
std::string flag = lua_tostring(L, f);
411+
if (flag == "ASYNC") {
417412
flags |= TF_ASYNC;
418413
}
419-
else if (!strcmp(flag, "CLAMP")) {
414+
else if (flag == "CLAMP") {
420415
flags |= TF_CLAMP;
421416
}
422-
else if (!strcmp(flag, "MIPMAP")) {
417+
else if (flag == "MIPMAP") {
423418
flags &= ~TF_NOMIPMAP;
424419
}
425-
else if (!strcmp(flag, "NEAREST")) {
420+
else if (flag == "NEAREST") {
426421
flags |= TF_NEAREST;
427422
}
428423
else {
429-
ui->LExpect(L, 0, "imgHandle:Load(): unrecognised flag '%s'", flag);
424+
ui->LExpect(L, 0, "imgHandle:Load(): unrecognised flag '%s'", flag.c_str());
430425
}
431426
}
432-
imgHandle->hnd = ui->renderer->RegisterShader(fullFileName, flags);
427+
// TODO(LV): should we use u8path throughout here, to support any callers that use paths outside of working directory?
428+
imgHandle->hnd = ui->renderer->RegisterShader(fileName.u8string(), flags);
433429
return 0;
434430
}
435431
SG_LUA_CPP_FUN_END()

0 commit comments

Comments
 (0)