Skip to content

Commit

Permalink
Picture preview
Browse files Browse the repository at this point in the history
* add file preview to browser
* separate vulkan textures and samplers
  • Loading branch information
karwler committed Feb 7, 2023
1 parent 348331c commit 9b224c3
Show file tree
Hide file tree
Showing 37 changed files with 2,066 additions and 3,358 deletions.
11 changes: 7 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ endif()

# dependencies
set(VER_ARC "3.6.2")
set(VER_SDL "2.26.2")
set(VER_IMG "2.6.2")
set(VER_TTF "2.20.1")
set(VER_SDL "2.26.3")
set(VER_IMG "2.6.3")
set(VER_TTF "2.20.2")
set(VER_GLM "0.9.9.8")
set(VER_CURL "7.83.1")
set(VER_LXML "2.9.14")
Expand Down Expand Up @@ -260,7 +260,10 @@ else()
set(ICONS_DIR "${DATA_DIR}/icons")
set(LICN_DIR "${DATA_DIR}/licenses")

include_directories($<$<BOOL:${DOWNLOADER}>:/usr/include/libxml2>)
if(DOWNLOADER)
find_package(LibXml2 REQUIRED)
include_directories("${LIBXML2_INCLUDE_DIRS}")
endif()
endif()

# compiler flags
Expand Down
34 changes: 9 additions & 25 deletions rsc/vk_shaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,11 @@
layout(push_constant) uniform PushData {
ivec4 rect;
ivec4 frame;
ivec4 txloc;
vec4 color;
uvec2 tid;
uint sid;
} pc;
layout(set = 0, binding = 0) uniform UniformData0 {
vec2 tbounds[3];
} u0;
layout(set = 1, binding = 0) uniform UniformData1 {
layout(set = 0, binding = 0) uniform UniformData {
vec4 pview;
} u1;
Expand All @@ -37,9 +32,9 @@
}
if (dsiz.x > 0.0 && dsiz.y > 0.0) {
vec2 uvpos = vec2(pc.txloc.xy) + (dpos - vec2(pc.rect.xy)) / vec2(pc.rect.zw) * vec2(pc.txloc.zw);
vec2 uvsiz = dsiz / vec2(pc.rect.zw) * vec2(pc.txloc.zw);
fragUV = (vposs[gl_VertexIndex] * uvsiz + uvpos) / u0.tbounds[pc.tid.x];
vec2 uvpos = (dpos - vec2(pc.rect.xy)) / vec2(pc.rect.zw);
vec2 uvsiz = dsiz / vec2(pc.rect.zw);
fragUV = vposs[gl_VertexIndex] * uvsiz + uvpos;
vec2 loc = vposs[gl_VertexIndex] * dsiz + dpos;
gl_Position = vec4((loc - u1.pview.xy) / u1.pview.zw - 1.0, 0.0, 1.0);
} else {
Expand All @@ -53,30 +48,19 @@
layout(push_constant) uniform PushData {
ivec4 rect;
ivec4 frame;
ivec4 txloc;
vec4 color;
uvec2 tid;
uint sid;
} pc;
layout(set = 0, binding = 1) uniform sampler2DArray icons;
layout(set = 0, binding = 2) uniform sampler2DArray texts;
layout(set = 0, binding = 3) uniform sampler2DArray rpics;
layout(set = 0, binding = 1) uniform sampler colorSamp[2];
layout(set = 1, binding = 0) uniform texture2D colorTex;
layout(location = 0) noperspective in vec2 fragUV;
layout(location = 0) out vec4 outColor;
void main() {
switch (pc.tid.x) {
case 0:
outColor = texture(icons, vec3(fragUV, pc.tid.y)) * pc.color;
break;
case 1:
outColor = texture(texts, vec3(fragUV, pc.tid.y));
break;
case 2:
outColor = texture(rpics, vec3(fragUV, pc.tid.y));
}
outColor = texture(sampler2D(colorTex, colorSamp[pc.sid]), fragUV) * pc.color;
}'''

vsSel = '''#version 450
Expand Down
74 changes: 30 additions & 44 deletions src/engine/drawSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,51 +146,37 @@ DrawSys::DrawSys(const umap<int, SDL_Window*>& windows, Settings* sets, const Fi
#endif
}

vector<pair<sizet, SDL_Surface*>> icons;
try {
sizet i = 0;
vector<string> names;
for (const fs::directory_entry& it : fs::directory_iterator(fileSys->dirIcons(), fs::directory_options::skip_permission_denied)) {
SDL_Surface* white = SDL_CreateRGBSurfaceWithFormat(0, 2, 2, 32, SDL_PIXELFORMAT_RGBA32);
if (!white)
throw std::runtime_error("Failed to create blank texture: "s + SDL_GetError());
SDL_FillRect(white, nullptr, 0xFFFFFFFF);
Texture* tex = renderer->texFromImg(white);
if (!tex)
throw std::runtime_error("Failed to create blank texture");
texes.emplace(string(), tex);
blank = tex;

for (const fs::directory_entry& it : fs::directory_iterator(fileSys->dirIcons(), fs::directory_options::skip_permission_denied)) {
#if SDL_IMAGE_VERSION_ATLEAST(2, 6, 0)
if (SDL_RWops* ifh = SDL_RWFromFile(it.path().u8string().c_str(), "rb")) {
if (SDL_Surface* aimg = IMG_LoadSizedSVG_RW(ifh, iconSize, iconSize)) {
names.push_back(it.path().stem().u8string());
icons.emplace_back(i++, aimg);
} else if (SDL_RWseek(ifh, 0, RW_SEEK_SET); SDL_Surface* bimg = IMG_Load_RW(ifh, SDL_FALSE)) {
names.push_back(it.path().stem().u8string());
icons.emplace_back(i++, bimg);
}
SDL_RWclose(ifh);
}
if (SDL_RWops* ifh = SDL_RWFromFile(it.path().u8string().c_str(), "rb")) {
if (SDL_Surface* aimg = IMG_LoadSizedSVG_RW(ifh, iconSize, iconSize))
texes.emplace(it.path().stem().u8string(), renderer->texFromImg(aimg));
else if (SDL_RWseek(ifh, 0, RW_SEEK_SET); SDL_Surface* bimg = IMG_Load_RW(ifh, SDL_FALSE))
texes.emplace(it.path().stem().u8string(), renderer->texFromImg(bimg));
SDL_RWclose(ifh);
}
#else
if (SDL_Surface* img = IMG_Load(it.path().u8string().c_str())) {
names.push_back(it.path().stem().u8string());
icons.emplace_back(i++, img);
}
if (SDL_Surface* img = IMG_Load(it.path().u8string().c_str()))
texes.emplace(it.path().stem().u8string(), renderer->texFromImg(img));
#endif
}
names.emplace_back();
vector<pair<sizet, Texture*>> refs = renderer->initIconTextures(std::move(icons));
icons.clear();
texes.reserve(refs.size());
for (auto [id, tex] : refs)
texes.emplace(std::move(names[id]), tex);
try {
blank = texes.at(string());
} catch (const std::out_of_range&) {
throw std::runtime_error("Failed to create blank texture");
}
setFont(sets->font, sets, fileSys);
} catch (const std::runtime_error&) {
for (auto [id, img] : icons)
SDL_FreeSurface(img);
throw;
}
setFont(sets->font, sets, fileSys);
}

DrawSys::~DrawSys() {
if (renderer)
renderer->freeIconTextures(texes);
for (auto& [name, tex] : texes)
renderer->freeTexture(tex);
delete renderer;
}

Expand Down Expand Up @@ -225,12 +211,12 @@ const Texture* DrawSys::texture(const string& name) const {
}

vector<pair<string, Texture*>> DrawSys::transferPictures(PictureLoader* pl) {
vector<pair<sizet, Texture*>> refs = renderer->initRpicTextures(pl->extractPics());
std::sort(refs.begin(), refs.end(), [](const pair<sizet, Texture*>& a, const pair<sizet, Texture*>& b) -> bool { return a.first < b.first; });
vector<pair<sizet, SDL_Surface*>> refs = pl->extractPics();
std::sort(refs.begin(), refs.end(), [](const pair<sizet, SDL_Surface*>& a, const pair<sizet, SDL_Surface*>& b) -> bool { return a.first < b.first; });

vector<pair<string, Texture*>> ptxv(refs.size());
for (sizet i = 0; i < ptxv.size(); ++i)
ptxv[i] = pair(std::move(pl->names[refs[i].first]), refs[i].second);
ptxv[i] = pair(std::move(pl->names[refs[i].first]), renderer->texFromImg(refs[i].second));
return ptxv;
}

Expand Down Expand Up @@ -402,15 +388,15 @@ void DrawSys::loadTexturesDirectoryThreaded(std::atomic_bool& running, uptr<Pict
for (sizet mov = btom<uptrt>(pl->fwd), i = pl->fwd ? 0 : files.size() - 1, c = 0; i < files.size() && c < lim && m < mem; i += mov) {
if (!running)
return;
pushEvent(UserCode::readerProgress, PictureLoader::progressText(pl->limitToStr(c, m, sizMag), progLim));
pushEvent(SDL_USEREVENT_READER_PROGRESS, PictureLoader::progressText(pl->limitToStr(c, m, sizMag), progLim));

if (SDL_Surface* img = IMG_Load((pl->curDir / files[i]).u8string().c_str())) {
pl->pics.emplace_back(i, img);
m += uptrt(img->w) * uptrt(img->h) * uptrt(img->format->BytesPerPixel);
++c;
}
}
pushEvent(UserCode::readerFinished, pl.release());
pushEvent(SDL_USEREVENT_READER_FINISHED, pl.release());
running = false;
}

Expand All @@ -429,7 +415,7 @@ void DrawSys::loadTexturesArchiveThreaded(std::atomic_bool& running, uptr<Pictur
archive_read_free(arch);
return;
}
pushEvent(UserCode::readerProgress, PictureLoader::progressText(pl->limitToStr(c, m, sizMag), progLim));
pushEvent(SDL_USEREVENT_READER_PROGRESS, PictureLoader::progressText(pl->limitToStr(c, m, sizMag), progLim));

string pname = archive_entry_pathname_utf8(entry);
if (pair<sizet, uptrt>& ent = files[pname]; ent.first >= start && ent.first < end)
Expand All @@ -440,7 +426,7 @@ void DrawSys::loadTexturesArchiveThreaded(std::atomic_bool& running, uptr<Pictur
}
}
archive_read_free(arch);
pushEvent(UserCode::readerFinished, pl.release());
pushEvent(SDL_USEREVENT_READER_FINISHED, pl.release());
running = false;
}

Expand Down
12 changes: 6 additions & 6 deletions src/engine/drawSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ class DrawSys {
#endif
const Texture* texture(const string& name) const;
vector<pair<string, Texture*>> transferPictures(PictureLoader* pl);
void freeRpicTextures(vector<pair<string, Texture*>>&& texv);
void freeTextTexture(Texture* tex);
Texture* texFromImg(SDL_Surface* img);
void freeTexture(Texture* tex);
void setCompression(bool on);
void getAdditionalSettings(bool& compression, vector<pair<u32vec2, string>>& devices);

Expand Down Expand Up @@ -178,12 +178,12 @@ inline Texture* DrawSys::renderText(const string& text, int height, uint length)
return renderText(text.c_str(), height, length);
}

inline void DrawSys::freeRpicTextures(vector<pair<string, Texture*>>&& texv) {
renderer->freeRpicTextures(std::move(texv));
inline Texture* DrawSys::texFromImg(SDL_Surface* img) {
return renderer->texFromImg(img);
}

inline void DrawSys::freeTextTexture(Texture* tex) {
renderer->freeTextTexture(tex);
inline void DrawSys::freeTexture(Texture* tex) {
renderer->freeTexture(tex);
}

inline void DrawSys::setCompression(bool on) {
Expand Down
7 changes: 5 additions & 2 deletions src/engine/fileSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ Settings* FileSys::loadSettings() const {
sets->font = FileSys::isFont(findFont(il.getVal())) ? il.getVal() : Settings::defaultFont;
else if (!SDL_strcasecmp(il.getPrp().c_str(), iniKeywordTheme))
sets->setTheme(il.getVal(), getAvailableThemes());
else if (!SDL_strcasecmp(il.getPrp().c_str(), iniKeywordPreview))
sets->preview = toBool(il.getVal());
else if (!SDL_strcasecmp(il.getPrp().c_str(), iniKeywordShowHidden))
sets->showHidden = toBool(il.getVal());
else if (!SDL_strcasecmp(il.getPrp().c_str(), iniKeywordTooltips))
Expand Down Expand Up @@ -265,6 +267,7 @@ void FileSys::saveSettings(const Settings* sets) const {
IniLine::writeVal(ofh, iniKeywordDirection, Direction::names[uint8(sets->direction)]);
IniLine::writeVal(ofh, iniKeywordFont, sets->font);
IniLine::writeVal(ofh, iniKeywordTheme, sets->getTheme());
IniLine::writeVal(ofh, iniKeywordPreview, toStr(sets->preview));
IniLine::writeVal(ofh, iniKeywordShowHidden, toStr(sets->showHidden));
IniLine::writeVal(ofh, iniKeywordTooltips, toStr(sets->tooltips));
IniLine::writeVal(ofh, iniKeywordLibrary, sets->getDirLib().u8string());
Expand Down Expand Up @@ -569,15 +572,15 @@ void FileSys::moveContentThreaded(std::atomic_bool& running, fs::path src, fs::p
if (!running)
break;

pushEvent(UserCode::moveProgress, reinterpret_cast<void*>(i), reinterpret_cast<void*>(lim));
pushEvent(SDL_USEREVENT_MOVE_PROGRESS, reinterpret_cast<void*>(i), reinterpret_cast<void*>(lim));
#ifdef _WIN32
if (fs::path path = src / files[i]; _wrename(path.c_str(), (dst / files[i]).c_str()))
#else
if (fs::path path = src / files[i]; rename(path.c_str(), (dst / files[i]).c_str()))
#endif
logError("failed no move ", path);
}
pushEvent(UserCode::moveFinished);
pushEvent(SDL_USEREVENT_MOVE_FINISHED);
running = false;
}

Expand Down
1 change: 1 addition & 0 deletions src/engine/fileSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class FileSys {
static constexpr char iniKeywordPictureLimit[] = "picture_limit";
static constexpr char iniKeywordFont[] = "font";
static constexpr char iniKeywordTheme[] = "theme";
static constexpr char iniKeywordPreview[] = "preview";
static constexpr char iniKeywordShowHidden[] = "show_hidden";
static constexpr char iniKeywordTooltips[] = "tooltips";
static constexpr char iniKeywordLibrary[] = "library";
Expand Down
12 changes: 12 additions & 0 deletions src/engine/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,15 @@ Renderer::View::View(SDL_Window* window, const Recti& area) :
void Renderer::setCompression(bool) {}

void Renderer::finishRender() {}

SDL_Surface* Renderer::limitSize(SDL_Surface* img, uint32 limit) {
if (img && (uint32(img->w) > limit || uint32(img->h) > limit)) {
float scale = float(limit) / float(img->w > img->h ? img->w : img->h);
SDL_Surface* dst = SDL_CreateRGBSurfaceWithFormat(0, int(float(img->w) * scale), int(float(img->h) * scale), img->format->BitsPerPixel, img->format->format);
if (dst)
SDL_BlitScaled(img, nullptr, dst, nullptr);
SDL_FreeSurface(img);
img = dst;
}
return img;
}
12 changes: 6 additions & 6 deletions src/engine/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class Texture {
private:
ivec2 res = ivec2(0);
ivec2 res;

protected:
Texture(ivec2 size);
Expand Down Expand Up @@ -52,13 +52,13 @@ class Renderer {
virtual void startSelDraw(View* view, ivec2 pos) = 0;
virtual void drawSelRect(const Widget* wgt, const Recti& rect, const Recti& frame) = 0;
virtual Widget* finishSelDraw(View* view) = 0;
virtual vector<pair<sizet, Texture*>> initIconTextures(vector<pair<sizet, SDL_Surface*>>&& iconImp) = 0;
virtual vector<pair<sizet, Texture*>> initRpicTextures(vector<pair<sizet, SDL_Surface*>>&& rpicImp) = 0;
virtual Texture* texFromImg(SDL_Surface* img) = 0;
virtual Texture* texFromText(SDL_Surface* img) = 0;
virtual void freeIconTextures(umap<string, Texture*>& texes) = 0;
virtual void freeRpicTextures(vector<pair<string, Texture*>>&& texes) = 0;
virtual void freeTextTexture(Texture* tex) = 0;
virtual void freeTexture(Texture* tex) = 0;

const umap<int, View*>& getViews() const;
protected:
static SDL_Surface* limitSize(SDL_Surface* img, uint32 limit);
};

inline const umap<int, Renderer::View*>& Renderer::getViews() const {
Expand Down
Loading

0 comments on commit 9b224c3

Please sign in to comment.