File include/jrf/image.h changed (mode: 100644) (index 8af9e6d..f334468) |
17 |
17 |
* along with this library. If not, see <https://www.gnu.org/licenses/> |
* along with this library. If not, see <https://www.gnu.org/licenses/> |
18 |
18 |
*/ |
*/ |
19 |
19 |
#pragma once |
#pragma once |
20 |
|
#include <jlib/io_agent.h> |
|
21 |
20 |
#include <jlib/allocate.h> |
#include <jlib/allocate.h> |
22 |
|
#include "result.h" |
|
|
21 |
|
#include <cinttypes> |
23 |
22 |
|
|
24 |
23 |
namespace jrf { struct Image; } |
namespace jrf { struct Image; } |
25 |
24 |
struct jrf::Image |
struct jrf::Image |
|
... |
... |
struct jrf::Image |
40 |
39 |
[[nodiscard]] uint64_t size() { |
[[nodiscard]] uint64_t size() { |
41 |
40 |
return pixel_count() * pixelSize; |
return pixel_count() * pixelSize; |
42 |
41 |
} |
} |
43 |
|
[[nodiscard]] bool sameUV(const Extent& other) { |
|
44 |
|
return width == other.width && height == other.height; |
|
45 |
|
} |
|
46 |
42 |
uint16_t width; |
uint16_t width; |
47 |
43 |
uint16_t height; |
uint16_t height; |
48 |
44 |
uint16_t depth; |
uint16_t depth; |
|
... |
... |
struct jrf::Image |
57 |
53 |
void destroy() { |
void destroy() { |
58 |
54 |
jl::deallocate(&p_pixels); |
jl::deallocate(&p_pixels); |
59 |
55 |
} |
} |
60 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
61 |
|
Result read(IO *p_mediator) { |
|
62 |
|
if (p_mediator->read(&extent, sizeof(extent)) != sizeof(extent)) |
|
63 |
|
return Result::MEDIATOR_ERROR; |
|
64 |
|
if (p_mediator->read(&format, sizeof(format)) != sizeof(format)) |
|
65 |
|
return Result::MEDIATOR_ERROR; |
|
66 |
|
size = extent.size(); |
|
67 |
|
if (size == 0) { |
|
68 |
|
p_pixels = nullptr; |
|
69 |
|
return Result::FILE_NO_DATA; |
|
70 |
|
} |
|
71 |
|
if (not jl::allocate_bytes(&p_pixels, size)) |
|
72 |
|
return Result::ALLOCATION_FAIL; |
|
73 |
|
if (p_mediator->read(p_pixels, size) != int64_t(size)) { |
|
74 |
|
destroy(); |
|
75 |
|
return Result::MEDIATOR_ERROR; |
|
76 |
|
} |
|
77 |
|
return Result::SUCCESS; |
|
78 |
|
} |
|
79 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
80 |
|
Result write(IO *p_mediator) const { |
|
81 |
|
if (p_mediator->write(&extent, sizeof(extent)) != sizeof(extent)) |
|
82 |
|
return Result::MEDIATOR_ERROR; |
|
83 |
|
if (p_mediator->write(&format, sizeof(format)) != sizeof(format)) |
|
84 |
|
return Result::MEDIATOR_ERROR; |
|
85 |
|
if (p_mediator->write(p_pixels, size) != int64_t(size)) |
|
86 |
|
return Result::MEDIATOR_ERROR; |
|
87 |
|
return Result::SUCCESS; |
|
88 |
|
} |
|
89 |
56 |
uint8_t *p_pixels; |
uint8_t *p_pixels; |
90 |
57 |
uint64_t size; |
uint64_t size; |
91 |
58 |
Extent extent; |
Extent extent; |
File include/jrf/indices.h deleted (index 34d7451..0000000) |
1 |
|
/** |
|
2 |
|
* Copyright 2020 Damir Valiev |
|
3 |
|
* |
|
4 |
|
* This file is part of jrf C++ library. |
|
5 |
|
* |
|
6 |
|
* This library is free software: you can redistribute it and/or modify |
|
7 |
|
* it under the terms of the GNU General Public License as published by |
|
8 |
|
* the Free Software Foundation, either version 3 of the License, or |
|
9 |
|
* (at your option) any later version. |
|
10 |
|
* |
|
11 |
|
* This library is distributed in the hope that it will be useful, |
|
12 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 |
|
* GNU General Public License for more details. |
|
15 |
|
* |
|
16 |
|
* You should have received a copy of the GNU General Public License |
|
17 |
|
* along with this library. If not, see <https://www.gnu.org/licenses/> |
|
18 |
|
*/ |
|
19 |
|
#pragma once |
|
20 |
|
#include <jlib/io_agent.h> |
|
21 |
|
#include <jlib/allocate.h> |
|
22 |
|
#include "result.h" |
|
23 |
|
|
|
24 |
|
namespace jrf |
|
25 |
|
{ |
|
26 |
|
enum IndexFormat : uint32_t { U16 = 2, U32 = 4 }; |
|
27 |
|
struct Indices; |
|
28 |
|
} |
|
29 |
|
struct jrf::Indices |
|
30 |
|
{ |
|
31 |
|
void destroy() { |
|
32 |
|
jl::deallocate(&p_data); |
|
33 |
|
} |
|
34 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
35 |
|
Result read(IO *p_mediator) { |
|
36 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
37 |
|
if (not p_io->read_items(&format)) |
|
38 |
|
return Result::MEDIATOR_ERROR; |
|
39 |
|
if (not p_io->read_items(&size)) |
|
40 |
|
return Result::MEDIATOR_ERROR; |
|
41 |
|
if (size == 0) |
|
42 |
|
p_data = nullptr; |
|
43 |
|
else { |
|
44 |
|
if (not jl::allocate_bytes(&p_data, size)) |
|
45 |
|
return Result::MEDIATOR_ERROR; |
|
46 |
|
if (not p_io->read_bytes(p_data, size)) |
|
47 |
|
return this->destroy(), Result::MEDIATOR_ERROR; |
|
48 |
|
} |
|
49 |
|
return Result::SUCCESS; |
|
50 |
|
} |
|
51 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
52 |
|
Result write(IO *p_mediator) const { |
|
53 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
54 |
|
if (not p_io->write_items(&format)) |
|
55 |
|
return Result::MEDIATOR_ERROR; |
|
56 |
|
if (not p_io->write_items(&size)) |
|
57 |
|
return Result::MEDIATOR_ERROR; |
|
58 |
|
if (not p_io->write_bytes(p_data, size)) |
|
59 |
|
return Result::MEDIATOR_ERROR; |
|
60 |
|
|
|
61 |
|
return Result::SUCCESS; |
|
62 |
|
} |
|
63 |
|
uint8_t *p_data; |
|
64 |
|
uint64_t size; |
|
65 |
|
IndexFormat format; |
|
66 |
|
}; |
|
File include/jrf/mesh.h changed (mode: 100644) (index 68245c4..ceca7ff) |
17 |
17 |
* along with this library. If not, see <https://www.gnu.org/licenses/> |
* along with this library. If not, see <https://www.gnu.org/licenses/> |
18 |
18 |
*/ |
*/ |
19 |
19 |
#pragma once |
#pragma once |
20 |
|
#include "vertices.h" |
|
21 |
|
#include "indices.h" |
|
|
20 |
|
#include <jlib/allocate.h> |
|
21 |
|
#include <jlib/array.h> |
22 |
22 |
#include <jlib/string.h> |
#include <jlib/string.h> |
23 |
|
#include <jlib/darray.h> |
|
|
23 |
|
#include "result.h" |
24 |
24 |
|
|
25 |
|
namespace jrf |
|
26 |
|
{ |
|
27 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
28 |
|
Result read_str(IO *p_io, jl::string *p_dst) { |
|
29 |
|
jl::darray<char> path_tmp; |
|
30 |
|
path_tmp.init(); |
|
31 |
|
char sym; |
|
32 |
|
do { |
|
33 |
|
if (p_io->read(&sym, 1) != 1) |
|
34 |
|
return Result::MEDIATOR_ERROR; |
|
35 |
|
if (not path_tmp.insert(sym)) |
|
36 |
|
return Result::ALLOCATION_FAIL; |
|
37 |
|
} |
|
38 |
|
while(sym != '\0'); |
|
39 |
|
*p_dst = {path_tmp.begin(), path_tmp.end()}; |
|
40 |
|
return Result::SUCCESS; |
|
41 |
|
} |
|
|
25 |
|
namespace jrf { |
|
26 |
|
struct Vertices; |
|
27 |
|
struct Indices; |
42 |
28 |
template<typename T> |
template<typename T> |
43 |
29 |
struct Data; |
struct Data; |
44 |
30 |
struct Mesh; |
struct Mesh; |
|
31 |
|
|
|
32 |
|
namespace VertexFormatT { enum T : uint16_t { |
|
33 |
|
F16, F32, F64, |
|
34 |
|
I8, I16, I32, I64, |
|
35 |
|
U8, U16, U32, U64 |
|
36 |
|
}; } |
|
37 |
|
using VertexFormat = VertexFormatT::T; |
|
38 |
|
constexpr static const uint8_t VERTEX_FORMAT_SIZE[] = { |
|
39 |
|
2, 4, 8, |
|
40 |
|
1, 2, 4, 8, |
|
41 |
|
1, 2, 4, 8 |
|
42 |
|
}; |
|
43 |
|
enum VertexAttributeType { |
|
44 |
|
POSITION, TEX_COORD, NORMAL, |
|
45 |
|
RESERVED_BEGIN, |
|
46 |
|
RESERVED_COUNT = 16 |
|
47 |
|
}; |
|
48 |
|
static_assert (RESERVED_BEGIN < RESERVED_COUNT); |
|
49 |
|
constexpr static const uint8_t VERTEX_ATTRIBUTE_COUNT = RESERVED_COUNT; |
|
50 |
|
|
|
51 |
|
struct VertexAttribute { |
|
52 |
|
uint32_t offset; |
|
53 |
|
uint16_t dimension_count; |
|
54 |
|
VertexFormat format; |
|
55 |
|
}; |
|
56 |
|
using VertexAttributes = jl::array<VertexAttribute, VERTEX_ATTRIBUTE_COUNT>; |
|
57 |
|
|
|
58 |
|
namespace IndexFormatT { enum T : uint32_t { |
|
59 |
|
U16 = 2, |
|
60 |
|
U32 = 4 |
|
61 |
|
}; } |
|
62 |
|
using IndexFormat = IndexFormatT::T; |
45 |
63 |
} |
} |
|
64 |
|
struct jrf::Vertices { |
|
65 |
|
void destroy() { |
|
66 |
|
jl::deallocate(&p_data); |
|
67 |
|
} |
|
68 |
|
VertexAttributes attributes; |
|
69 |
|
uint64_t vecs_count; |
|
70 |
|
uint64_t data_size; |
|
71 |
|
void *p_data; |
|
72 |
|
}; |
|
73 |
|
struct jrf::Indices { |
|
74 |
|
void destroy() { |
|
75 |
|
jl::deallocate(&p_data); |
|
76 |
|
} |
|
77 |
|
uint8_t *p_data; |
|
78 |
|
uint64_t size; |
|
79 |
|
IndexFormat format; |
|
80 |
|
}; |
46 |
81 |
template<typename T> |
template<typename T> |
47 |
|
struct jrf::Data |
|
48 |
|
{ |
|
|
82 |
|
struct jrf::Data { |
49 |
83 |
void destroy() { |
void destroy() { |
50 |
84 |
switch(mode) { |
switch(mode) { |
51 |
85 |
case ResourceMode::DATA: u.data.destroy(); break; |
case ResourceMode::DATA: u.data.destroy(); break; |
|
... |
... |
struct jrf::Data |
53 |
87 |
case ResourceMode::NONE: break; |
case ResourceMode::NONE: break; |
54 |
88 |
} |
} |
55 |
89 |
} |
} |
56 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
57 |
|
Result read(IO *p_io) { |
|
58 |
|
if (p_io->read(&mode, sizeof(mode)) != sizeof(mode)) |
|
59 |
|
return Result::MEDIATOR_ERROR; |
|
60 |
|
switch(mode) { |
|
61 |
|
case ResourceMode::NONE: break; |
|
62 |
|
case ResourceMode::DATA: { |
|
63 |
|
Result res = u.data.read(p_io); |
|
64 |
|
if (res != Result::SUCCESS) |
|
65 |
|
return res; |
|
66 |
|
} break; |
|
67 |
|
case ResourceMode::PATH: { |
|
68 |
|
auto res = read_str(p_io, &u.path); |
|
69 |
|
if (res != Result::SUCCESS) |
|
70 |
|
return res; |
|
71 |
|
} |
|
72 |
|
} |
|
73 |
|
return Result::SUCCESS; |
|
74 |
|
} |
|
75 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
76 |
|
Result write(IO *p_io) const { |
|
77 |
|
if (p_io->write(&mode, sizeof(mode)) != sizeof(mode)) |
|
78 |
|
return Result::MEDIATOR_ERROR; |
|
79 |
|
switch(mode) { |
|
80 |
|
case ResourceMode::DATA: { |
|
81 |
|
Result res = u.data.write(p_io); |
|
82 |
|
if (res != Result::SUCCESS) |
|
83 |
|
return res; |
|
84 |
|
} break; |
|
85 |
|
case ResourceMode::PATH: { |
|
86 |
|
if (p_io->write(u.path.begin(), u.path.size()) |
|
87 |
|
!= int64_t(u.path.size())) |
|
88 |
|
return Result::MEDIATOR_ERROR; |
|
89 |
|
} break; |
|
90 |
|
default: break; |
|
91 |
|
} |
|
92 |
|
return Result::SUCCESS; |
|
93 |
|
} |
|
94 |
90 |
union { |
union { |
95 |
91 |
T data; |
T data; |
96 |
92 |
jl::string path; |
jl::string path; |
97 |
93 |
} u; |
} u; |
98 |
94 |
ResourceMode mode; |
ResourceMode mode; |
99 |
95 |
}; |
}; |
100 |
|
struct jrf::Mesh |
|
101 |
|
{ |
|
|
96 |
|
struct jrf::Mesh { |
102 |
97 |
void destroy() { |
void destroy() { |
103 |
98 |
vert.destroy(); |
vert.destroy(); |
104 |
99 |
ind .destroy(); |
ind .destroy(); |
105 |
100 |
} |
} |
106 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
107 |
|
Result read(IO *p_mediator) { |
|
108 |
|
Result res; |
|
109 |
|
res = vert.read(p_mediator); |
|
110 |
|
if (res != Result::SUCCESS) |
|
111 |
|
return res; |
|
112 |
|
res = ind.read(p_mediator); |
|
113 |
|
if (res != Result::SUCCESS) |
|
114 |
|
vert.destroy(); |
|
115 |
|
return res; |
|
116 |
|
} |
|
117 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
118 |
|
Result write(IO *p_mediator) const { |
|
119 |
|
Result res = vert.write(p_mediator); |
|
120 |
|
if (res != Result::SUCCESS) |
|
121 |
|
return res; |
|
122 |
|
return ind.write(p_mediator); |
|
123 |
|
} |
|
124 |
101 |
Data<Vertices> vert; |
Data<Vertices> vert; |
125 |
102 |
Data<Indices> ind; |
Data<Indices> ind; |
126 |
103 |
}; |
}; |
File include/jrf/read.h changed (mode: 100644) (index 73c6812..ada8262) |
19 |
19 |
#pragma once |
#pragma once |
20 |
20 |
#include "jrf.h" |
#include "jrf.h" |
21 |
21 |
#include "zip.h" |
#include "zip.h" |
|
22 |
|
#include <jlib/darray.h> |
22 |
23 |
#include <jlib/io_agent_mem_ro.h> |
#include <jlib/io_agent_mem_ro.h> |
23 |
24 |
#include <jlib/fs.h> |
#include <jlib/fs.h> |
24 |
25 |
|
|
|
26 |
|
namespace jrf { |
|
27 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
28 |
|
Result read_str(IO *p_io, jl::string *p_dst) { |
|
29 |
|
jl::darray<char> path_tmp; |
|
30 |
|
path_tmp.init(); |
|
31 |
|
char sym; |
|
32 |
|
do { |
|
33 |
|
if (p_io->read(&sym, 1) != 1) |
|
34 |
|
return Result::MEDIATOR_ERROR; |
|
35 |
|
if (not path_tmp.insert(sym)) |
|
36 |
|
return Result::ALLOCATION_FAIL; |
|
37 |
|
} |
|
38 |
|
while(sym != '\0'); |
|
39 |
|
*p_dst = {path_tmp.begin(), path_tmp.end()}; |
|
40 |
|
return Result::SUCCESS; |
|
41 |
|
} |
|
42 |
|
template<typename T, typename IO = jl::io_agent> [[nodiscard]] |
|
43 |
|
Result read(Data<T> *p, IO *p_io) { |
|
44 |
|
if (p_io->read(&p->mode, sizeof(p->mode)) != sizeof(p->mode)) |
|
45 |
|
return Result::MEDIATOR_ERROR; |
|
46 |
|
switch(p->mode) { |
|
47 |
|
case ResourceMode::NONE: break; |
|
48 |
|
case ResourceMode::DATA: { |
|
49 |
|
Result res = p->u.data.read(p_io); |
|
50 |
|
if (res != Result::SUCCESS) |
|
51 |
|
return res; |
|
52 |
|
} break; |
|
53 |
|
case ResourceMode::PATH: { |
|
54 |
|
auto res = read_str(p_io, &p->u.path); |
|
55 |
|
if (res != Result::SUCCESS) |
|
56 |
|
return res; |
|
57 |
|
} |
|
58 |
|
} |
|
59 |
|
return Result::SUCCESS; |
|
60 |
|
} |
|
61 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
62 |
|
Result read(Vertices *p, IO *p_mediator) { |
|
63 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
64 |
|
if (not p_io->read_items(&p->attributes)) |
|
65 |
|
return Result::MEDIATOR_ERROR; |
|
66 |
|
if (not p_io->read_items(&p->vecs_count)) |
|
67 |
|
return Result::MEDIATOR_ERROR; |
|
68 |
|
jl::array<size_t, VERTEX_ATTRIBUTE_COUNT> asizes; |
|
69 |
|
p->data_size = 0; |
|
70 |
|
for (uint8_t a = 0; a < VERTEX_ATTRIBUTE_COUNT; ++a) { |
|
71 |
|
asizes[a] = p->attributes[a].dimension_count |
|
72 |
|
* VERTEX_FORMAT_SIZE[p->attributes[a].format] * p->vecs_count; |
|
73 |
|
p->data_size += asizes[a]; |
|
74 |
|
} |
|
75 |
|
for (uint8_t a = 0; a < VERTEX_ATTRIBUTE_COUNT; ++a) |
|
76 |
|
if (p->attributes[a].offset + asizes[a] > p->data_size) |
|
77 |
|
return Result::FILE_CORRUPTED; |
|
78 |
|
if (p->data_size == 0) |
|
79 |
|
return Result::FILE_NO_DATA; |
|
80 |
|
if (not jl::allocate_bytes(&p->p_data, p->data_size)) |
|
81 |
|
return Result::MEDIATOR_ERROR; |
|
82 |
|
if (not p_io->read_bytes(p->p_data, p->data_size)) { |
|
83 |
|
p->destroy(); |
|
84 |
|
return Result::MEDIATOR_ERROR; |
|
85 |
|
} |
|
86 |
|
return Result::SUCCESS; |
|
87 |
|
} |
|
88 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
89 |
|
Result read(Indices *p, IO *p_mediator) { |
|
90 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
91 |
|
if (not p_io->read_items(&p->format)) |
|
92 |
|
return Result::MEDIATOR_ERROR; |
|
93 |
|
if (not p_io->read_items(&p->size)) |
|
94 |
|
return Result::MEDIATOR_ERROR; |
|
95 |
|
if (p->size == 0) |
|
96 |
|
p->p_data = nullptr; |
|
97 |
|
else { |
|
98 |
|
if (not jl::allocate_bytes(&p->p_data, p->size)) |
|
99 |
|
return Result::MEDIATOR_ERROR; |
|
100 |
|
if (not p_io->read_bytes(p->p_data, p->size)) { |
|
101 |
|
p->destroy(); |
|
102 |
|
return Result::MEDIATOR_ERROR; |
|
103 |
|
} |
|
104 |
|
} |
|
105 |
|
return Result::SUCCESS; |
|
106 |
|
} |
|
107 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
108 |
|
Result read(Mesh *p, IO *p_mediator) { |
|
109 |
|
Result res; |
|
110 |
|
res = read(&p->vert, p_mediator); |
|
111 |
|
if (res != Result::SUCCESS) |
|
112 |
|
return res; |
|
113 |
|
res = read(&p->ind, p_mediator); |
|
114 |
|
if (res != Result::SUCCESS) |
|
115 |
|
p->vert.destroy(); |
|
116 |
|
return res; |
|
117 |
|
} |
|
118 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
119 |
|
Result read(Image *p, IO *p_mediator) { |
|
120 |
|
if (p_mediator->read(&p->extent, sizeof(p->extent)) != sizeof(p->extent)) |
|
121 |
|
return Result::MEDIATOR_ERROR; |
|
122 |
|
if (p_mediator->read(&p->format, sizeof(p->format)) != sizeof(p->format)) |
|
123 |
|
return Result::MEDIATOR_ERROR; |
|
124 |
|
p->size = p->extent.size(); |
|
125 |
|
if (p->size == 0) { |
|
126 |
|
p->p_pixels = nullptr; |
|
127 |
|
return Result::FILE_NO_DATA; |
|
128 |
|
} |
|
129 |
|
if (not jl::allocate_bytes(&p->p_pixels, p->size)) |
|
130 |
|
return Result::ALLOCATION_FAIL; |
|
131 |
|
if (p_mediator->read(p->p_pixels, p->size) != int64_t(p->size)) { |
|
132 |
|
p->destroy(); |
|
133 |
|
return Result::MEDIATOR_ERROR; |
|
134 |
|
} |
|
135 |
|
return Result::SUCCESS; |
|
136 |
|
} |
|
137 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
138 |
|
Result read(Model *p, IO *p_mediator) { |
|
139 |
|
Result res; |
|
140 |
|
res = read(&p->mesh, p_mediator); |
|
141 |
|
if (res != Result::SUCCESS) |
|
142 |
|
return res; |
|
143 |
|
res = read(&p->image, p_mediator); |
|
144 |
|
if (res != Result::SUCCESS) |
|
145 |
|
p->mesh.destroy(); |
|
146 |
|
return res; |
|
147 |
|
} |
|
148 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
149 |
|
Result read(SceneEntry *p, IO *p_mediator) { |
|
150 |
|
Result res = read_str(p_mediator, &p->model_path); |
|
151 |
|
if (res != Result::SUCCESS) |
|
152 |
|
return res; |
|
153 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
154 |
|
if (not p_io->read_items(&p->options.pos)) |
|
155 |
|
goto CANCEL; |
|
156 |
|
if (not p_io->read_items(&p->options.shift)) |
|
157 |
|
goto CANCEL; |
|
158 |
|
if (not p_io->read_items(&p->options.transform)) |
|
159 |
|
goto CANCEL; |
|
160 |
|
return Result::SUCCESS; |
|
161 |
|
CANCEL: |
|
162 |
|
p->destroy(); |
|
163 |
|
return Result::MEDIATOR_ERROR; |
|
164 |
|
} |
|
165 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
166 |
|
Result read(Scene *p, IO *p_mediator) { |
|
167 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
168 |
|
if (not p_io->read_items(&p->options.shift)) |
|
169 |
|
return Result::MEDIATOR_ERROR; |
|
170 |
|
if (not p_io->read_items(&p->options.shift_po2)) |
|
171 |
|
return Result::MEDIATOR_ERROR; |
|
172 |
|
uint64_t entry_count; |
|
173 |
|
if (not p_io->read_items(&entry_count)) |
|
174 |
|
return Result::MEDIATOR_ERROR; |
|
175 |
|
if (entry_count == 0) { |
|
176 |
|
p->entries.init(); |
|
177 |
|
return Result::SUCCESS; |
|
178 |
|
} |
|
179 |
|
if (not p->entries.init(entry_count)) |
|
180 |
|
return Result::ALLOCATION_FAIL; |
|
181 |
|
for (uint64_t i = 0; i < entry_count; ++i) { |
|
182 |
|
Result res = read(&p->entries[i], p_mediator); |
|
183 |
|
if (res != Result::SUCCESS) { |
|
184 |
|
while(i > 0) |
|
185 |
|
p->entries[--i].destroy(); |
|
186 |
|
p->entries.destroy(); |
|
187 |
|
return res; |
|
188 |
|
} |
|
189 |
|
} |
|
190 |
|
return Result::SUCCESS; |
|
191 |
|
} |
|
192 |
|
} |
|
193 |
|
|
25 |
194 |
namespace jrf::details { |
namespace jrf::details { |
26 |
195 |
template<typename IO = jl::io_agent> |
template<typename IO = jl::io_agent> |
27 |
196 |
[[nodiscard]] inline |
[[nodiscard]] inline |
28 |
197 |
Result read(IO *p_io, ResourceType type, ResourceUnion *p_ru) { |
Result read(IO *p_io, ResourceType type, ResourceUnion *p_ru) { |
29 |
198 |
switch(type) { |
switch(type) { |
30 |
|
case ResourceType::IMAGE: return p_ru->image .read(p_io); |
|
31 |
|
case ResourceType::VERTICES: return p_ru->vertices.read(p_io); |
|
32 |
|
case ResourceType::INDICES: return p_ru->indices .read(p_io); |
|
33 |
|
case ResourceType::MESH: return p_ru->mesh .read(p_io); |
|
34 |
|
case ResourceType::MODEL: return p_ru->model .read(p_io); |
|
35 |
|
case ResourceType::SCENE: return p_ru->scene .read(p_io); |
|
36 |
|
default: return Result::UNKNOWN_RESOURCE_TYPE; |
|
|
199 |
|
case ResourceType::IMAGE: return read(&p_ru->image, p_io); |
|
200 |
|
case ResourceType::VERTICES: return read(&p_ru->vertices, p_io); |
|
201 |
|
case ResourceType::INDICES: return read(&p_ru->indices, p_io); |
|
202 |
|
case ResourceType::MESH: return read(&p_ru->mesh, p_io); |
|
203 |
|
case ResourceType::MODEL: return read(&p_ru->model, p_io); |
|
204 |
|
case ResourceType::SCENE: return read(&p_ru->scene, p_io); |
|
205 |
|
default: return Result::UNKNOWN_RESOURCE_TYPE; |
37 |
206 |
} |
} |
38 |
207 |
} |
} |
39 |
208 |
} |
} |
File include/jrf/scene.h changed (mode: 100644) (index a76e8d3..327a81f) |
20 |
20 |
#include "model.h" |
#include "model.h" |
21 |
21 |
#include <jlib/array.h> |
#include <jlib/array.h> |
22 |
22 |
|
|
23 |
|
namespace jrf { struct Scene; struct SceneEntry; } |
|
24 |
|
|
|
25 |
|
struct jrf::SceneEntry |
|
26 |
|
{ |
|
27 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
28 |
|
Result read(IO *p_mediator) { |
|
29 |
|
Result res = read_str(p_mediator, &model_path); |
|
30 |
|
if (res != Result::SUCCESS) |
|
31 |
|
return res; |
|
32 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
33 |
|
if (not p_io->read_items(&options.pos)) |
|
34 |
|
goto CANCEL; |
|
35 |
|
if (not p_io->read_items(&options.shift)) |
|
36 |
|
goto CANCEL; |
|
37 |
|
if (not p_io->read_items(&options.transform)) |
|
38 |
|
goto CANCEL; |
|
39 |
|
return Result::SUCCESS; |
|
40 |
|
CANCEL: destroy(); |
|
41 |
|
return Result::MEDIATOR_ERROR; |
|
42 |
|
} |
|
43 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
44 |
|
Result write(IO *p_mediator) const { |
|
45 |
|
if (p_mediator->write(model_path.begin(), model_path.size()) |
|
46 |
|
!= int64_t(model_path.size())) |
|
47 |
|
return Result::MEDIATOR_ERROR; |
|
48 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
49 |
|
if (not p_io->write_items(&options.pos)) |
|
50 |
|
return Result::MEDIATOR_ERROR; |
|
51 |
|
if (not p_io->write_items(&options.shift)) |
|
52 |
|
return Result::MEDIATOR_ERROR; |
|
53 |
|
if (not p_io->write_items(&options.transform)) |
|
54 |
|
return Result::MEDIATOR_ERROR; |
|
55 |
|
return Result::SUCCESS; |
|
|
23 |
|
namespace jrf { |
|
24 |
|
struct SceneEntryOptions; |
|
25 |
|
struct SceneEntry; |
|
26 |
|
struct SceneOptions; |
|
27 |
|
struct Scene; |
|
28 |
|
} |
|
29 |
|
struct jrf::SceneEntryOptions { |
|
30 |
|
void set_default() { |
|
31 |
|
pos = {}; |
|
32 |
|
shift = {}; |
|
33 |
|
transform = {}; |
|
34 |
|
transform[0] = transform[5] = transform[10] = transform[15] = 1; |
56 |
35 |
} |
} |
57 |
|
struct Options { |
|
58 |
|
void set_default() { |
|
59 |
|
pos = {}; |
|
60 |
|
shift = {}; |
|
61 |
|
transform = {}; |
|
62 |
|
transform[0] = transform[5] = transform[10] = transform[15] = 1; |
|
63 |
|
} |
|
64 |
|
jl::array<float, 3> pos; ///< position |
|
65 |
|
jl::array<int32_t,3> shift; ///< shift of position |
|
66 |
|
jl::array<float, 16> transform; ///< transformation matrix 4x4 |
|
67 |
|
}; |
|
|
36 |
|
jl::array<float, 3> pos; ///< position |
|
37 |
|
jl::array<int32_t,3> shift; ///< shift of position |
|
38 |
|
jl::array<float, 16> transform; ///< transformation matrix 4x4 |
|
39 |
|
}; |
|
40 |
|
struct jrf::SceneEntry { |
68 |
41 |
void destroy() { |
void destroy() { |
69 |
42 |
model_path.destroy(); |
model_path.destroy(); |
70 |
43 |
} |
} |
71 |
|
Options options; |
|
72 |
|
jl::string model_path; |
|
|
44 |
|
SceneEntryOptions options; |
|
45 |
|
jl::string model_path; |
73 |
46 |
}; |
}; |
74 |
|
struct jrf::Scene |
|
75 |
|
{ |
|
|
47 |
|
struct jrf::SceneOptions { |
|
48 |
|
void set_default() { |
|
49 |
|
*this = {}; |
|
50 |
|
} |
|
51 |
|
jl::array<int32_t, 3> shift; ///< global shift of scene |
|
52 |
|
int32_t shift_po2; ///< Power of two |
|
53 |
|
}; |
|
54 |
|
struct jrf::Scene { |
76 |
55 |
void destroy() { |
void destroy() { |
77 |
56 |
entries.destroy(&SceneEntry::destroy); |
entries.destroy(&SceneEntry::destroy); |
78 |
57 |
} |
} |
79 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
80 |
|
Result read(IO *p_mediator) { |
|
81 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
82 |
|
if (not p_io->read_items(&options.shift)) |
|
83 |
|
return Result::MEDIATOR_ERROR; |
|
84 |
|
if (not p_io->read_items(&options.shift_po2)) |
|
85 |
|
return Result::MEDIATOR_ERROR; |
|
86 |
|
uint64_t entry_count; |
|
87 |
|
if (not p_io->read_items(&entry_count)) |
|
88 |
|
return Result::MEDIATOR_ERROR; |
|
89 |
|
if (entry_count == 0) { |
|
90 |
|
entries.init(); |
|
91 |
|
return Result::SUCCESS; |
|
92 |
|
} |
|
93 |
|
if (not entries.init(entry_count)) |
|
94 |
|
return Result::ALLOCATION_FAIL; |
|
95 |
|
for (uint64_t i = 0; i < entry_count; ++i) { |
|
96 |
|
Result res = entries[i].read(p_mediator); |
|
97 |
|
if (res != Result::SUCCESS) { |
|
98 |
|
while(i > 0) |
|
99 |
|
entries[--i].destroy(); |
|
100 |
|
entries.destroy(); |
|
101 |
|
return res; |
|
102 |
|
} |
|
103 |
|
} |
|
104 |
|
return Result::SUCCESS; |
|
105 |
|
} |
|
106 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
107 |
|
Result write(IO *p_mediator) const { |
|
108 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
109 |
|
if (not p_io->write_items(&options.shift)) |
|
110 |
|
return Result::MEDIATOR_ERROR; |
|
111 |
|
if (not p_io->write_items(&options.shift_po2)) |
|
112 |
|
return Result::MEDIATOR_ERROR; |
|
113 |
|
size_t entry_count = entries.count(); |
|
114 |
|
if (not p_io->write_items(&entry_count)) |
|
115 |
|
return Result::MEDIATOR_ERROR; |
|
116 |
|
for (auto &e : entries) { |
|
117 |
|
Result res = e.write(p_mediator); |
|
118 |
|
if (res != Result::SUCCESS) |
|
119 |
|
return res; |
|
120 |
|
} |
|
121 |
|
return Result::SUCCESS; |
|
122 |
|
} |
|
123 |
|
struct Options { |
|
124 |
|
void set_default_value() { *this = {}; } |
|
125 |
|
jl::array<int32_t, 3> shift; ///< global shift of scene |
|
126 |
|
int32_t shift_po2; ///< Power of two |
|
127 |
|
}; |
|
128 |
|
Options options; |
|
|
58 |
|
SceneOptions options; |
129 |
59 |
jl::rarray<SceneEntry> entries; |
jl::rarray<SceneEntry> entries; |
130 |
60 |
}; |
}; |
File include/jrf/vertices.h deleted (index f792f45..0000000) |
1 |
|
/** |
|
2 |
|
* Copyright 2020 Damir Valiev |
|
3 |
|
* |
|
4 |
|
* This file is part of jrf C++ library. |
|
5 |
|
* |
|
6 |
|
* This library is free software: you can redistribute it and/or modify |
|
7 |
|
* it under the terms of the GNU General Public License as published by |
|
8 |
|
* the Free Software Foundation, either version 3 of the License, or |
|
9 |
|
* (at your option) any later version. |
|
10 |
|
* |
|
11 |
|
* This library is distributed in the hope that it will be useful, |
|
12 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 |
|
* GNU General Public License for more details. |
|
15 |
|
* |
|
16 |
|
* You should have received a copy of the GNU General Public License |
|
17 |
|
* along with this library. If not, see <https://www.gnu.org/licenses/> |
|
18 |
|
*/ |
|
19 |
|
#pragma once |
|
20 |
|
#include <jlib/io_agent.h> |
|
21 |
|
#include <jlib/allocate.h> |
|
22 |
|
#include <jlib/array.h> |
|
23 |
|
#include "result.h" |
|
24 |
|
|
|
25 |
|
namespace jrf { struct Vertices; } |
|
26 |
|
struct jrf::Vertices |
|
27 |
|
{ |
|
28 |
|
void destroy() { |
|
29 |
|
jl::deallocate(&p_data); |
|
30 |
|
} |
|
31 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
32 |
|
Result read(IO *p_mediator) { |
|
33 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
34 |
|
if (not p_io->read_items(&attributes)) |
|
35 |
|
return Result::MEDIATOR_ERROR; |
|
36 |
|
if (not p_io->read_items(&vecs_count)) |
|
37 |
|
return Result::MEDIATOR_ERROR; |
|
38 |
|
jl::array<size_t, ATTRIBUTE_COUNT> asizes; |
|
39 |
|
data_size = 0; |
|
40 |
|
for (uint8_t a = 0; a < ATTRIBUTE_COUNT; ++a) { |
|
41 |
|
asizes[a] = attributes[a].dimension_count |
|
42 |
|
* FORMAT_SIZE[attributes[a].format] * vecs_count; |
|
43 |
|
data_size += asizes[a]; |
|
44 |
|
} |
|
45 |
|
for (uint8_t a = 0; a < ATTRIBUTE_COUNT; ++a) |
|
46 |
|
if (attributes[a].offset + asizes[a] > data_size) |
|
47 |
|
return Result::FILE_CORRUPTED; |
|
48 |
|
if (data_size == 0) |
|
49 |
|
return Result::FILE_NO_DATA; |
|
50 |
|
if (not jl::allocate_bytes(&p_data, data_size)) |
|
51 |
|
return Result::MEDIATOR_ERROR; |
|
52 |
|
if (not p_io->read_bytes(p_data, data_size)) |
|
53 |
|
return this->destroy(), Result::MEDIATOR_ERROR; |
|
54 |
|
return Result::SUCCESS; |
|
55 |
|
} |
|
56 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
57 |
|
Result write(IO *p_mediator) const { |
|
58 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
59 |
|
if (not p_io->write_items(&attributes)) |
|
60 |
|
return Result::MEDIATOR_ERROR; |
|
61 |
|
if (not p_io->write_items(&vecs_count)) |
|
62 |
|
return Result::MEDIATOR_ERROR; |
|
63 |
|
if (not p_io->write_bytes(p_data, data_size)) |
|
64 |
|
return Result::MEDIATOR_ERROR; |
|
65 |
|
return Result::SUCCESS; |
|
66 |
|
} |
|
67 |
|
enum Format : uint16_t { |
|
68 |
|
F16, F32, F64, |
|
69 |
|
I8, I16, I32, I64, |
|
70 |
|
U8, U16, U32, U64 |
|
71 |
|
}; |
|
72 |
|
constexpr static const uint8_t FORMAT_SIZE[] = { |
|
73 |
|
2, 4, 8, |
|
74 |
|
1, 2, 4, 8, |
|
75 |
|
1, 2, 4, 8 |
|
76 |
|
}; |
|
77 |
|
enum AttributeType { |
|
78 |
|
POSITION, TEX_COORD, NORMAL, |
|
79 |
|
RESERVED_BEGIN, |
|
80 |
|
RESERVED_COUNT = 16 |
|
81 |
|
}; |
|
82 |
|
static_assert (RESERVED_BEGIN < RESERVED_COUNT); |
|
83 |
|
constexpr static const uint8_t ATTRIBUTE_COUNT = RESERVED_COUNT; |
|
84 |
|
|
|
85 |
|
struct Attribute { |
|
86 |
|
uint32_t offset; |
|
87 |
|
uint16_t dimension_count; |
|
88 |
|
Format format; |
|
89 |
|
}; |
|
90 |
|
using Attributes = jl::array<Attribute, ATTRIBUTE_COUNT>; |
|
91 |
|
|
|
92 |
|
Attributes attributes; |
|
93 |
|
uint64_t vecs_count; |
|
94 |
|
uint64_t data_size; |
|
95 |
|
void *p_data; |
|
96 |
|
}; |
|
File include/jrf/write.h changed (mode: 100644) (index 751db04..375ed8d) |
18 |
18 |
*/ |
*/ |
19 |
19 |
#pragma once |
#pragma once |
20 |
20 |
#include "jrf.h" |
#include "jrf.h" |
|
21 |
|
#include <jlib/io_agent.h> |
21 |
22 |
|
|
22 |
23 |
namespace jrf |
namespace jrf |
23 |
24 |
{ |
{ |
|
25 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
26 |
|
Result write(const Image &im, IO *p_mediator) { |
|
27 |
|
if (p_mediator->write(&im.extent, sizeof(im.extent)) != sizeof(im.extent)) |
|
28 |
|
return Result::MEDIATOR_ERROR; |
|
29 |
|
if (p_mediator->write(&im.format, sizeof(im.format)) != sizeof(im.format)) |
|
30 |
|
return Result::MEDIATOR_ERROR; |
|
31 |
|
if (p_mediator->write(im.p_pixels, im.size) != int64_t(im.size)) |
|
32 |
|
return Result::MEDIATOR_ERROR; |
|
33 |
|
return Result::SUCCESS; |
|
34 |
|
} |
|
35 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
36 |
|
Result write(const Indices &in, IO *p_mediator) { |
|
37 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
38 |
|
if (not p_io->write_items(&in.format)) |
|
39 |
|
return Result::MEDIATOR_ERROR; |
|
40 |
|
if (not p_io->write_items(&in.size)) |
|
41 |
|
return Result::MEDIATOR_ERROR; |
|
42 |
|
if (not p_io->write_bytes(in.p_data, in.size)) |
|
43 |
|
return Result::MEDIATOR_ERROR; |
|
44 |
|
|
|
45 |
|
return Result::SUCCESS; |
|
46 |
|
} |
|
47 |
|
template<typename T, typename IO = jl::io_agent> [[nodiscard]] |
|
48 |
|
Result write(const Data<T> &d, IO *p_io) { |
|
49 |
|
if (p_io->write(&d.mode, sizeof(d.mode)) != sizeof(d.mode)) |
|
50 |
|
return Result::MEDIATOR_ERROR; |
|
51 |
|
switch(d.mode) { |
|
52 |
|
case ResourceMode::DATA: { |
|
53 |
|
Result res = d.u.data.write(p_io); |
|
54 |
|
if (res != Result::SUCCESS) |
|
55 |
|
return res; |
|
56 |
|
} break; |
|
57 |
|
case ResourceMode::PATH: { |
|
58 |
|
if (p_io->write(d.u.path.begin(), d.u.path.size()) |
|
59 |
|
!= int64_t(d.u.path.size())) |
|
60 |
|
return Result::MEDIATOR_ERROR; |
|
61 |
|
} break; |
|
62 |
|
default: break; |
|
63 |
|
} |
|
64 |
|
return Result::SUCCESS; |
|
65 |
|
} |
|
66 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
67 |
|
Result write(const Vertices &v, IO *p_mediator) { |
|
68 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
69 |
|
if (not p_io->write_items(&v.attributes)) |
|
70 |
|
return Result::MEDIATOR_ERROR; |
|
71 |
|
if (not p_io->write_items(&v.vecs_count)) |
|
72 |
|
return Result::MEDIATOR_ERROR; |
|
73 |
|
if (not p_io->write_bytes(v.p_data, v.data_size)) |
|
74 |
|
return Result::MEDIATOR_ERROR; |
|
75 |
|
return Result::SUCCESS; |
|
76 |
|
} |
|
77 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
78 |
|
Result write(const Mesh &m, IO *p_mediator) { |
|
79 |
|
Result res = write(m.vert, p_mediator); |
|
80 |
|
if (res != Result::SUCCESS) |
|
81 |
|
return res; |
|
82 |
|
return write(m.ind, p_mediator); |
|
83 |
|
} |
|
84 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
85 |
|
Result write(const Model &m, IO *p_io) { |
|
86 |
|
Result res = write(&m.mesh, p_io); |
|
87 |
|
if (res != Result::SUCCESS) |
|
88 |
|
return res; |
|
89 |
|
return write(&m.image, p_io); |
|
90 |
|
} |
|
91 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
92 |
|
Result write(const SceneEntry &s, IO *p_mediator) { |
|
93 |
|
if (p_mediator->write(s.model_path.begin(), s.model_path.size()) |
|
94 |
|
!= int64_t(s.model_path.size())) |
|
95 |
|
return Result::MEDIATOR_ERROR; |
|
96 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
97 |
|
if (not p_io->write_items(&s.options.pos)) |
|
98 |
|
return Result::MEDIATOR_ERROR; |
|
99 |
|
if (not p_io->write_items(&s.options.shift)) |
|
100 |
|
return Result::MEDIATOR_ERROR; |
|
101 |
|
if (not p_io->write_items(&s.options.transform)) |
|
102 |
|
return Result::MEDIATOR_ERROR; |
|
103 |
|
return Result::SUCCESS; |
|
104 |
|
} |
|
105 |
|
template<typename IO = jl::io_agent> [[nodiscard]] |
|
106 |
|
Result write(const Scene &s, IO *p_mediator) { |
|
107 |
|
auto *p_io = jl::io_agent_p_alt_cast(p_mediator); |
|
108 |
|
if (not p_io->write_items(&s.options.shift)) |
|
109 |
|
return Result::MEDIATOR_ERROR; |
|
110 |
|
if (not p_io->write_items(&s.options.shift_po2)) |
|
111 |
|
return Result::MEDIATOR_ERROR; |
|
112 |
|
size_t entry_count = s.entries.count(); |
|
113 |
|
if (not p_io->write_items(&entry_count)) |
|
114 |
|
return Result::MEDIATOR_ERROR; |
|
115 |
|
for (auto &e : s.entries) { |
|
116 |
|
Result res = write(&e, p_mediator); |
|
117 |
|
if (res != Result::SUCCESS) |
|
118 |
|
return res; |
|
119 |
|
} |
|
120 |
|
return Result::SUCCESS; |
|
121 |
|
} |
24 |
122 |
template<typename IO = jl::io_agent> [[nodiscard]] |
template<typename IO = jl::io_agent> [[nodiscard]] |
25 |
123 |
Result write(IO *p_io, ResourceType type, ResourceUnion *p_ru) { |
Result write(IO *p_io, ResourceType type, ResourceUnion *p_ru) { |
26 |
124 |
switch(type) { |
switch(type) { |
|
... |
... |
namespace jrf |
47 |
145 |
header.type = RT; |
header.type = RT; |
48 |
146 |
if (p_io->write(&header, sizeof (EntryHeader)) != sizeof(EntryHeader)) |
if (p_io->write(&header, sizeof (EntryHeader)) != sizeof(EntryHeader)) |
49 |
147 |
return MEDIATOR_ERROR; |
return MEDIATOR_ERROR; |
50 |
|
return resource.write(p_io); |
|
|
148 |
|
return write(resource, p_io); |
51 |
149 |
} |
} |
52 |
150 |
} |
} |