OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
drawbuckets.cpp
Go to the documentation of this file.
1#include "drawbuckets.h"
2
3#include <Tempest/Vec>
4
7
8#include "gothic.h"
9
10using namespace Tempest;
11
12static size_t roundup(size_t i) {
13 const size_t rounding = 1024;
14 if(i%rounding!=0)
15 i += rounding-i%rounding;
16 return i;
17 };
18
19DrawBuckets::Id::Id(DrawBuckets* owner, size_t id):owner(owner), id(uint16_t(id)) {
20 }
21
22DrawBuckets::Id::Id(Id&& other) noexcept {
23 std::swap(owner, other.owner);
24 std::swap(id, other.id);
25 }
26
28 std::swap(owner, other.owner);
29 std::swap(id, other.id);
30 return *this;
31 }
32
35
36
39
41 for(size_t i=0; i<bucketsCpu.size(); ++i) {
42 auto& b = bucketsCpu[i];
43 if(b.staticMesh==&mesh && b.mat==mat)
44 return Id(this, i);
45 }
46
47 Bucket bx;
48 bx.staticMesh = &mesh;
49 bx.mat = mat;
50
51 bucketsDurtyBit = true;
52 bucketsCpu.emplace_back(std::move(bx));
53 return Id(this, bucketsCpu.size()-1);
54 }
55
57 for(size_t i=0; i<bucketsCpu.size(); ++i) {
58 auto& b = bucketsCpu[i];
59 if(b.animMesh==&mesh && b.mat==mat)
60 return Id(this, i);
61 }
62
63 Bucket bx;
64 bx.animMesh = &mesh;
65 bx.mat = mat;
66
67 bucketsDurtyBit = true;
68 bucketsCpu.emplace_back(std::move(bx));
69 return Id(this, bucketsCpu.size()-1);
70 }
71
72const std::vector<DrawBuckets::Bucket>& DrawBuckets::buckets() {
73 return bucketsCpu;
74 }
75
76void DrawBuckets::updateBindlessArrays() {
77 if(!Gothic::inst().options().doBindless)
78 return;
79
80 std::vector<const Tempest::Texture2d*> tex;
81 std::vector<const Tempest::StorageBuffer*> vbo, ibo;
82 std::vector<const Tempest::StorageBuffer*> morphId, morph;
83 for(auto& i:bucketsCpu) {
84 tex.push_back(i.mat.tex);
85 if(i.staticMesh!=nullptr) {
86 ibo .push_back(&i.staticMesh->ibo8);
87 vbo .push_back(&i.staticMesh->vbo);
88 morphId.push_back(i.staticMesh->morph.index);
89 morph .push_back(i.staticMesh->morph.samples);
90 } else {
91 ibo .push_back(&i.animMesh->ibo8);
92 vbo .push_back(&i.animMesh->vbo);
93 morphId.push_back(nullptr);
94 morph .push_back(nullptr);
95 }
96 }
97
98 // avoid shader linking stutter in vulkan
99 tex .resize(roundup(tex.size()));
100 vbo .resize(roundup(vbo.size()));
101 ibo .resize(roundup(ibo.size()));
102 morphId.resize(roundup(morphId.size()));
103 morph .resize(roundup(morph.size()));
104
105 Resources::recycle(std::move(desc.tex));
106 Resources::recycle(std::move(desc.vbo));
107 Resources::recycle(std::move(desc.ibo));
108 Resources::recycle(std::move(desc.morphId));
109 Resources::recycle(std::move(desc.morph));
110
111 auto& device = Resources::device();
112 desc.tex = device.descriptors(tex);
113 desc.vbo = device.descriptors(vbo);
114 desc.ibo = device.descriptors(ibo);
115 desc.morphId = device.descriptors(morphId);
116 desc.morph = device.descriptors(morph);
117 }
118
119bool DrawBuckets::commit(Encoder<CommandBuffer>& cmd, uint8_t fId) {
120 if(!bucketsDurtyBit)
121 return false;
122 bucketsDurtyBit = false;
123
124 std::vector<BucketGpu> bucket;
125 for(auto& i:bucketsCpu) {
126 BucketGpu bx;
127 bx.texAniMapDirPeriod = i.mat.texAniMapDirPeriod;
128 bx.waveMaxAmplitude = i.mat.waveMaxAmplitude;
129 bx.alphaWeight = i.mat.alphaWeight;
130 bx.envMapping = i.mat.envMapping;
131 if(i.staticMesh!=nullptr) {
132 auto& bbox = i.staticMesh->bbox.bbox;
133 bx.bboxRadius = i.staticMesh->bbox.rConservative;
134 bx.bbox[0] = Vec4(bbox[0].x,bbox[0].y,bbox[0].z,0.f);
135 bx.bbox[1] = Vec4(bbox[1].x,bbox[1].y,bbox[1].z,0.f);
136 if(i.staticMesh->morph.anim!=nullptr)
137 bx.flags |= BK_MORPH;
138 }
139 else if(i.animMesh!=nullptr) {
140 auto& bbox = i.animMesh->bbox.bbox;
141 bx.bboxRadius = i.animMesh->bbox.rConservative;
142 bx.bbox[0] = Vec4(bbox[0].x,bbox[0].y,bbox[0].z,0.f);
143 bx.bbox[1] = Vec4(bbox[1].x,bbox[1].y,bbox[1].z,0.f);
144 bx.flags |= BK_SKIN;
145 }
146 if(i.mat.alpha==Material::Solid)
147 bx.flags |= BK_SOLID;
148 if(i.mat.alpha==Material::Water)
149 bx.flags |= BK_WATER;
150 bucket.push_back(bx);
151 }
152
153 auto& device = Resources::device();
154 Resources::recycle(std::move(bucketsGpu));
155 bucketsGpu = device.ssbo(bucket);
156
157 updateBindlessArrays();
158 return true;
159 }
Id & operator=(Id &&other) noexcept
Id alloc(const Material &mat, const StaticMesh &mesh)
Tempest::DescriptorArray tex
Definition drawbuckets.h:80
bool commit(Tempest::Encoder< Tempest::CommandBuffer > &cmd, uint8_t fId)
Tempest::DescriptorArray ibo
Definition drawbuckets.h:82
Tempest::DescriptorArray morphId
Definition drawbuckets.h:83
auto buckets() -> const std::vector< Bucket > &
Tempest::DescriptorArray vbo
Definition drawbuckets.h:81
Tempest::DescriptorArray morph
Definition drawbuckets.h:84
static Gothic & inst()
Definition gothic.cpp:249
static Tempest::Device & device()
Definition resources.h:83
static void recycle(Tempest::DescriptorArray &&arr)
static size_t roundup(size_t i)
const StaticMesh * staticMesh
Definition drawbuckets.h:16
const AnimMesh * animMesh
Definition drawbuckets.h:17