Skip to content
Merged
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
4 changes: 2 additions & 2 deletions game/game/gamesession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ void GameSession::save(Serialize &fout, std::string_view name, const Pixmap& scr
fout.write(i.name);
}

fout.setEntry("preview.png");
fout.write(screen);
fout.setEntry("preview.jpg");
fout.write(std::tie(screen,"jpg"));

fout.setEntry("game/session");
fout.write(ticks,wrldTime,wrldTimePart,wrld->name());
Expand Down
6 changes: 5 additions & 1 deletion game/game/serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,14 @@ void Serialize::implRead(SaveGameHeader& p) {
}

void Serialize::implWrite(const Tempest::Pixmap& p) {
implWrite(p, "png");
}

void Serialize::implWrite(const Tempest::Pixmap& p, const char* ext) {
std::vector<uint8_t> tmp;
tmp.reserve(4*1024*1024);
Tempest::MemWriter w{tmp};
p.save(w);
p.save(w, ext);
writeBytes(tmp.data(),tmp.size());
}

Expand Down
3 changes: 3 additions & 0 deletions game/game/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ class Serialize {
void implRead (SaveGameHeader& p);

void implWrite(const Tempest::Pixmap& p);
void implWrite(const Tempest::Pixmap& p, const char* ext);
template<class Ext>
void implWrite(std::tuple<const Tempest::Pixmap&, Ext> p) { implWrite(std::get<0>(p), std::get<1>(p)); }
void implRead (Tempest::Pixmap& p);

void implWrite(const zenkit::INpc& h);
Expand Down
13 changes: 7 additions & 6 deletions game/graphics/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,22 @@ Shaders& Shaders::inst() {
}

void Shaders::compileKeyShaders() {
bink = postEffect("bink");
bink = postEffect("bink");
downscale = postEffect("downscale");
}

void Shaders::compileShaders() {
auto& device = Resources::device();

const bool meshlets = Gothic::options().doMeshShading;

copyBuf = computeShader("copy.comp.sprv");
copyImg = computeShader("copy_img.comp.sprv");
copy = postEffect("copy");
copyBuf = computeShader("copy.comp.sprv");
copyImg = computeShader("copy_img.comp.sprv");
copy = postEffect("copy");

patch = computeShader("patch.comp.sprv");
patch = computeShader("patch.comp.sprv");

stash = postEffect("stash");
stash = postEffect("stash");

clusterInit = computeShader("cluster_init.comp.sprv");
clusterPatch = computeShader("cluster_patch.comp.sprv");
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Shaders {
Tempest::ComputePipeline copyBuf;
Tempest::ComputePipeline copyImg;
Tempest::ComputePipeline patch;
Tempest::RenderPipeline copy;
Tempest::RenderPipeline copy, downscale;
Tempest::RenderPipeline stash;
Tempest::RenderPipeline bink;

Expand Down
31 changes: 28 additions & 3 deletions game/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,14 +1063,39 @@ void MainWindow::loadGame(std::string_view slot) {
}

void MainWindow::saveGame(std::string_view slot, std::string_view name) {
auto tex = renderer.screenshoot(cmdId);
auto pm = device.readPixels(textureCast<const Texture2d&>(tex));

if(dialogs.isActive())
return;
if(auto w = Gothic::inst().world(); w!=nullptr && w->currentCs()!=nullptr)
return;

auto tex = renderer.screenshoot(cmdId);
auto lres = Attachment();

static int32_t kThumbW = 800;
const int32_t kThumbH = tex.w()>0 ? int32_t((tex.h() * kThumbW) / tex.w()) : 0;
if(kThumbW>0 && kThumbH>0 && kThumbW<tex.w() && kThumbH<tex.h()) {
lres = device.attachment(Tempest::TextureFormat::RGBA8, uint32_t(kThumbW), uint32_t(kThumbH));
}

if(!lres.isEmpty()) {
// reduce size of the save entry preview screenshot for faster save & load
CommandBuffer cmd;
{
auto enc = cmd.startEncoding(device);
enc.setDebugMarker("Downscale screenhoot");
enc.setFramebuffer({{lres, Vec4(), Tempest::Preserve}});
enc.setPushData(IVec2(lres.w(), lres.h()));
enc.setBinding(0, tex, Sampler::nearest());
enc.setPipeline(Shaders::inst().downscale);
enc.draw(nullptr, 0, 3);
}
auto sync = device.submit(cmd);
sync.wait();
}

auto& thumb = lres.isEmpty() ? tex : lres;
auto pm = device.readPixels(textureCast<const Texture2d&>(thumb));

Gothic::inst().startSave(std::move(textureCast<Texture2d&>(tex)),[slot=std::string(slot),name=std::string(name),pm](std::unique_ptr<GameSession>&& game){
if(!game)
return std::move(game);
Expand Down
2 changes: 2 additions & 0 deletions game/ui/gamemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,8 @@ void GameMenu::updateSavTitle(GameMenu::Item& sel) {
reader.read(sel.savPriview); // legacy
else if(reader.setEntry("preview.png"))
reader.read(sel.savPriview);
else if(reader.setEntry("preview.jpg"))
reader.read(sel.savPriview);
}
catch(std::bad_alloc&) {
return;
Expand Down
1 change: 1 addition & 0 deletions shader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ add_shader(item.frag inventory/item.frag)

add_shader(stash.frag stash.frag)
add_shader(bink.frag bink/bink.frag)
add_shader(downscale.frag downscale.frag)

add_shader(direct_light.frag lighting/direct_light.frag)
add_shader(direct_light_sh.frag lighting/direct_light.frag -DSHADOW_MAP)
Expand Down
22 changes: 22 additions & 0 deletions shader/downscale.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#version 450

layout(binding = 0) uniform sampler2D src;
layout(location = 0) out vec4 outColor;

layout(push_constant, std140) uniform Push {
ivec2 dstSize;
};

void main() {
ivec2 srcSize = textureSize(src, 0);

ivec2 tl = (ivec2(gl_FragCoord.xy+ivec2(0))*srcSize)/dstSize;
ivec2 br = (ivec2(gl_FragCoord.xy+ivec2(1))*srcSize)/dstSize;

vec4 color = vec4(0);
for(int i=tl.x; i<br.x; ++i)
for(int r=tl.y; r<br.y; ++r) {
color += texelFetch(src, ivec2(i,r), 0);
}
outColor = color/((br.x-tl.x)*(br.y-tl.y));
}