Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Johannes Braun
glare
Commits
df9e0370
Commit
df9e0370
authored
Aug 31, 2017
by
Johannes Braun
Browse files
Newest Texture
parent
69ca59c2
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/executables/test_exe2/main.cpp
0 → 100644
View file @
df9e0370
#include
<array>
#include
<iostream>
#include
<atomic>
#include
<any>
#include
<memory>
#include
<functional>
#include
<set>
#include
<queue>
#include
<map>
#include
<experimental/filesystem>
#include
<experimental/string>
#include
<glm/glm.hpp>
#include
<glm/ext.hpp>
#include
<chrono>
#include
<mutex>
#include
<thread>
#include
<vector>
#include
<shared_mutex>
#include
<util/color.h>
#include
<core/state.h>
#include
<core/rendering/texture_renderer.h>
#include
<util/opengl.h>
struct
Texture
;
template
<
typename
From
,
typename
To
>
constexpr
float
conversionFactor
()
{
float
to_float
=
0
;
if
constexpr
(
std
::
is_same_v
<
From
,
float
>
)
to_float
=
1.
f
;
else
to_float
=
1
/
float
(
std
::
numeric_limits
<
From
>::
max
());
if
constexpr
(
std
::
is_same_v
<
To
,
float
>
)
return
to_float
;
else
return
to_float
*
float
(
std
::
numeric_limits
<
To
>::
max
());
}
template
<
typename
TBase
>
struct
Image
{
friend
struct
Texture
;
using
Dimensions
=
std
::
initializer_list
<
int
>
;
// You can either have a multisampled image without data.
explicit
Image
(
Dimensions
dimensions
,
int
comp
,
int
samples
)
:
m_components
(
comp
)
{
m_width
=
dimensions
.
begin
()[
0
];
m_height
=
dimensions
.
size
()
>
1
?
dimensions
.
begin
()[
1
]
:
1
;
m_depth
=
dimensions
.
size
()
>
2
?
dimensions
.
begin
()[
2
]
:
1
;
}
// Or a single-sample image with data.
explicit
Image
(
Dimensions
dimensions
,
int
comp
,
std
::
vector
<
TBase
>
data
=
std
::
vector
<
TBase
>
())
:
m_components
(
comp
),
data
(
std
::
move
(
data
))
{
m_width
=
dimensions
.
begin
()[
0
];
m_height
=
dimensions
.
size
()
>
1
?
dimensions
.
begin
()[
1
]
:
1
;
m_depth
=
dimensions
.
size
()
>
2
?
dimensions
.
begin
()[
2
]
:
1
;
}
// Or load an image from HDD as single-sample image
explicit
Image
(
const
std
::
experimental
::
filesystem
::
path
&
path
)
{
m_depth
=
1
;
if
constexpr
(
std
::
is_same_v
<
TBase
,
uint8_t
>
)
{
uint8_t
*
raw_data
=
stb
::
stbi_load
(
path
.
string
().
c_str
(),
&
m_width
,
&
m_height
,
&
m_components
,
0
);
if
(
!
raw_data
)
{
Log_Error
<<
"Loading image failed!
\"
"
<<
path
<<
"
\"
not found."
;
m_width
=
0
;
m_height
=
0
;
m_components
=
0
;
return
;
}
data
=
std
::
vector
<
uint8_t
>
(
raw_data
,
raw_data
+
m_width
*
m_height
*
m_components
);
}
else
{
float
*
raw_data
=
stb
::
stbi_loadf
(
path
.
string
().
c_str
(),
&
m_width
,
&
m_height
,
&
m_components
,
0
);
if
(
!
raw_data
)
{
Log_Error
<<
"Loading image failed!
\"
"
<<
path
<<
"
\"
not found."
;
m_width
=
0
;
m_height
=
0
;
m_components
=
0
;
return
;
}
data
=
std
::
vector
<
TBase
>
(
m_width
*
m_height
*
m_components
);
for
(
int
i
=
0
;
i
<
m_width
*
m_height
*
m_components
;
++
i
)
{
data
[
i
]
=
static_cast
<
TBase
>
(
conversionFactor
<
float
,
TBase
>
()
*
raw_data
[
i
]);
}
}
flip
();
}
// return r,rg,rgb or rgba
std
::
tuple
<
TBase
&
,
TBase
&
,
TBase
&
,
TBase
&>
operator
[](
Dimensions
pixel
)
{
// Don't allow texel fetches on MS images.
assert
(
m_samples
==
0
);
// Debug pixel size check.
assert
(
pixel
.
size
()
==
3
||
(
m_depth
==
1
&&
(
pixel
.
size
()
==
2
||
(
m_height
==
1
&&
pixel
.
size
()
==
1
))));
if
(
data
.
empty
())
throw
std
::
out_of_range
(
"This texture has no data. Cannot fetch a pixel for an empty texture."
);
glm
::
ivec3
position
(
0
);
int
pos
=
0
;
for
(
auto
&&
p
:
pixel
)
{
position
[
pos
++
]
=
p
;
}
// Debug bounds check.
assert
(
position
.
x
>=
0
&&
position
.
x
<
m_width
);
assert
(
position
.
y
>=
0
&&
position
.
y
<
m_height
);
assert
(
position
.
z
>=
0
&&
position
.
z
<
m_depth
);
color
<
TBase
>
result
(
0
);
for
(
int
i
=
0
;
i
<
m_components
;
++
i
)
{
// 4D access :P
result
[
i
]
=
data
[
m_width
*
m_height
*
m_components
*
position
.
z
+
m_width
*
m_components
*
position
.
y
+
m_components
*
position
.
x
+
i
];
}
m_ignore
=
0
;
auto
get
=
[
this
](
const
glm
::
ivec3
position
,
int
offset
)
->
TBase
&
{
return
offset
>=
m_components
?
m_ignore
:
data
[
m_width
*
m_height
*
m_components
*
position
.
z
+
m_width
*
m_components
*
position
.
y
+
m_components
*
position
.
x
+
offset
];
};
return
std
::
tie
(
get
(
position
,
0
),
get
(
position
,
1
),
get
(
position
,
2
),
get
(
position
,
3
));
}
void
save
(
const
fs
::
path
&
path
)
{
flip
();
if
constexpr
(
std
::
is_same_v
<
TBase
,
float
>
)
{
//if is float and extension is png, convert!
if
(
path
.
extension
()
!=
".hdr"
)
{
std
::
vector
<
uint8_t
>
converted
(
m_width
*
m_height
*
m_components
);
for
(
int
i
=
0
;
i
<
converted
.
size
();
++
i
)
{
converted
[
i
]
=
static_cast
<
uint8_t
>
(
conversionFactor
<
float
,
uint8_t
>
()
*
data
[
i
]);
}
images
::
save
(
path
,
m_width
,
m_height
,
m_components
,
converted
.
data
());
return
;
}
//Otherwise just save the floats.
images
::
save
(
path
,
m_width
,
m_height
,
m_components
,
converted
.
data
());
}
else
if
constexpr
(
std
::
is_same_v
<
TBase
,
uint8_t
>
)
{
images
::
save
(
path
,
m_width
,
m_height
,
m_components
,
data
.
data
());
}
else
{
if
(
path
.
extension
()
==
".hdr"
)
{
std
::
vector
<
float
>
converted
(
m_width
*
m_height
*
m_components
);
for
(
int
i
=
0
;
i
<
converted
.
size
();
++
i
)
{
converted
[
i
]
=
static_cast
<
float
>
(
conversionFactor
<
TBase
,
float
>
()
*
data
[
i
]);
}
images
::
save
(
path
,
m_width
,
m_height
,
m_components
,
converted
.
data
());
return
;
}
else
{
std
::
vector
<
uint8_t
>
converted
(
m_width
*
m_height
*
m_components
);
for
(
int
i
=
0
;
i
<
converted
.
size
();
++
i
)
{
converted
[
i
]
=
static_cast
<
uint8_t
>
(
conversionFactor
<
TBase
,
uint8_t
>
()
*
data
[
i
]);
}
images
::
save
(
path
,
m_width
,
m_height
,
m_components
,
converted
.
data
());
return
;
}
}
flip
();
}
int
width
()
const
{
return
m_width
;
}
int
height
()
const
{
return
m_height
;
}
int
depth
()
const
{
return
m_depth
;
}
int
components
()
const
{
return
m_components
;
}
int
samples
()
const
{
return
m_samples
;
}
void
flip
()
{
images
::
flip
(
static_cast
<
unsigned
>
(
m_width
),
static_cast
<
unsigned
>
(
m_height
),
static_cast
<
int
>
(
m_components
),
data
.
data
());
}
int
dimensions
()
const
{
return
1
+
(
m_height
!=
1
)
+
(
m_height
!=
1
&&
m_depth
!=
1
);
}
//private:
int
m_width
=
1
;
int
m_height
=
1
;
int
m_depth
=
1
;
int
m_components
=
0
;
int
m_samples
=
0
;
TBase
m_ignore
=
0
;
std
::
vector
<
TBase
>
data
;
};
struct
Texture
{
using
Target
=
gl
::
TextureType
;
using
SubTarget
=
gl
::
ImageTarget
;
using
StoreFormat
=
gl
::
TextureInternalFormat
;
using
SubTargetMultisample
=
gl
::
ImageTargetMultisample
;
struct
Parameters
{
gl
::
TextureWrapMode
wrap_r
=
gl
::
TextureWrapMode
::
eRepeat
;
gl
::
TextureWrapMode
wrap_s
=
gl
::
TextureWrapMode
::
eRepeat
;
gl
::
TextureWrapMode
wrap_t
=
gl
::
TextureWrapMode
::
eRepeat
;
gl
::
TextureFilterMin
filter_min
=
gl
::
TextureFilterMin
::
eLinearMipmapLinear
;
gl
::
TextureFilterMag
filter_mag
=
gl
::
TextureFilterMag
::
eLinear
;
gl
::
TextureCompareMode
compare_mode
=
gl
::
TextureCompareMode
::
eRToTexture
;
gl
::
CompareFunc
compare_func
=
gl
::
CompareFunc
::
eLess
;
float
anisotropy
=
-
1.
f
;
};
// General initialization
Texture
(
Target
target
,
StoreFormat
store_format
)
:
m_target
(
target
),
m_handle
(
std
::
move
(
target
)),
m_format
(
store_format
)
{
}
// Direct initialization for either 1D, 2D or 3D target.
template
<
typename
T
>
Texture
(
const
Image
<
T
>&
image
)
:
Texture
([
&
image
]()
{
switch
(
image
.
dimensions
())
{
case
1
:
return
Target
::
e1D
;
case
2
:
return
Target
::
e2D
;
case
3
:
return
Target
::
e3D
;
default:
return
Target
::
e2D
;
}
}(),
getFormat
(
image
))
{
switch
(
m_target
)
{
case
Target
::
e1D
:
set
(
SubTarget
::
e1D
,
image
,
m_latest_parameters
);
break
;
case
Target
::
e2D
:
set
(
SubTarget
::
e2D
,
image
,
m_latest_parameters
);
break
;
case
Target
::
e3D
:
set
(
SubTarget
::
e3D
,
image
,
m_latest_parameters
);
break
;
}
}
template
<
typename
T
>
Image
<
T
>
get
()
{
if
(
m_target
!=
gl
::
TextureType
::
e2D
||
m_components
==
-
1
)
{
throw
std
::
invalid_argument
(
"You cannot download this texture."
);
}
int
texture_width
=
width
();
int
texture_height
=
height
();
int
components
=
m_components
;
gl
::
TextureFormat
texture_format
=
[](
int
components
)
{
switch
(
components
)
{
case
1
:
return
gl
::
TextureFormat
::
eRed
;
case
2
:
return
gl
::
TextureFormat
::
eRG
;
case
3
:
return
gl
::
TextureFormat
::
eRGB
;
case
4
:
return
gl
::
TextureFormat
::
eRGBA
;
default:
throw
std
::
invalid_argument
(
"Texture format not valid."
);
}
}(
components
);
auto
texture_type
=
type
();
int
type_size
=
static_cast
<
int
>
([](
gl
::
Type
type
)
{
switch
(
type
)
{
case
gl
::
Type
::
eByte
:
return
sizeof
(
int8_t
);
case
gl
::
Type
::
eUByte
:
case
gl
::
Type
::
eUInt_8_8_8_8
:
case
gl
::
Type
::
eUInt_8_8_8_8_rev
:
return
sizeof
(
uint8_t
);
case
gl
::
Type
::
eInt
:
return
sizeof
(
int32_t
);
case
gl
::
Type
::
eUInt
:
return
sizeof
(
uint32_t
);
case
gl
::
Type
::
eFloat
:
return
sizeof
(
float
);
default:
throw
std
::
invalid_argument
(
"Texture format not valid."
);
}
}(
texture_type
));
std
::
vector
<
uint8_t
>
data
(
texture_width
*
texture_height
*
components
*
type_size
);
std
::
vector
<
T
>
converted
(
texture_width
*
texture_height
*
components
);
gl
::
getTextureImage
(
m_handle
,
0
,
texture_format
,
texture_type
,
data
.
size
(),
data
.
data
());
for
(
int
i
=
0
;
i
<
texture_width
*
texture_height
*
components
;
++
i
)
{
switch
(
texture_type
)
{
case
gl
::
Type
::
eByte
:
converted
[
i
]
=
static_cast
<
T
>
(
conversionFactor
<
int8_t
,
T
>
()
*
reinterpret_cast
<
int8_t
*>
(
data
.
data
())[
i
]);
break
;
case
gl
::
Type
::
eUByte
:
case
gl
::
Type
::
eUInt_8_8_8_8
:
case
gl
::
Type
::
eUInt_8_8_8_8_rev
:
converted
[
i
]
=
static_cast
<
T
>
(
conversionFactor
<
uint8_t
,
T
>
()
*
reinterpret_cast
<
uint8_t
*>
(
data
.
data
())[
i
]);
break
;
case
gl
::
Type
::
eInt
:
converted
[
i
]
=
static_cast
<
T
>
(
conversionFactor
<
int32_t
,
T
>
()
*
reinterpret_cast
<
int32_t
*>
(
data
.
data
())[
i
]);
break
;
case
gl
::
Type
::
eUInt
:
converted
[
i
]
=
static_cast
<
T
>
(
conversionFactor
<
uint32_t
,
T
>
()
*
reinterpret_cast
<
uint32_t
*>
(
data
.
data
())[
i
]);
break
;
case
gl
::
Type
::
eFloat
:
converted
[
i
]
=
static_cast
<
T
>
(
conversionFactor
<
float
,
T
>
()
*
reinterpret_cast
<
float
*>
(
data
.
data
())[
i
]);
break
;
default:
throw
std
::
invalid_argument
(
"Texture format not valid."
);
}
}
return
Image
<
T
>
({
texture_width
,
texture_height
},
components
,
converted
);
}
template
<
typename
T
>
void
set
(
SubTargetMultisample
t
,
const
Image
<
T
>&
image
)
{
set
(
t
,
image
,
m_latest_parameters
);
}
// up until the set methods, no openGL is needed yet.
// Upload an image
template
<
typename
T
>
void
set
(
SubTargetMultisample
t
,
const
Image
<
T
>&
image
,
Parameters
parameters
)
{
assert
(
image
.
samples
()
!=
0
);
m_components
=
image
.
components
();
gl
::
textureImage
(
m_handle
,
t
,
image
.
samples
(),
m_format
,
{
image
.
width
(),
image
.
height
(),
image
.
depth
()
});
apply
(
std
::
move
(
parameters
))
}
template
<
typename
T
>
void
set
(
SubTarget
t
,
const
Image
<
T
>&
image
)
{
set
(
t
,
image
,
m_latest_parameters
);
}
// up until the set methods, no openGL is needed yet.
// Upload an image
template
<
typename
T
>
void
set
(
SubTarget
t
,
const
Image
<
T
>&
image
,
Parameters
parameters
)
{
set
(
t
,
0
,
image
,
std
::
move
(
parameters
));
}
// Upload an image
template
<
typename
T
>
void
set
(
SubTarget
t
,
int
level
,
const
Image
<
T
>&
image
,
Parameters
parameters
)
{
// Don't allow level parameter on MS textures.
// images are multisampled if sample count is not 0.
assert
(
image
.
samples
()
==
0
);
gl
::
TextureFormat
texture_format
=
[](
int
components
)
{
switch
(
components
)
{
case
1
:
return
gl
::
TextureFormat
::
eRed
;
case
2
:
return
gl
::
TextureFormat
::
eRG
;
case
3
:
return
gl
::
TextureFormat
::
eRGB
;
case
4
:
return
gl
::
TextureFormat
::
eRGBA
;
default:
throw
std
::
invalid_argument
(
"Texture format not valid."
);
}
}(
image
.
components
());
m_components
=
image
.
components
();
gl
::
textureImage
(
m_handle
,
t
,
level
,
m_format
,
texture_format
,
{
image
.
width
(),
image
.
height
(),
image
.
depth
()
},
image
.
data
.
empty
()
?
nullptr
:
image
.
data
.
data
());
apply
(
std
::
move
(
parameters
));
}
const
Parameters
&
parameters
()
const
{
return
m_latest_parameters
;
}
void
apply
(
Parameters
parameters
)
{
m_latest_parameters
=
std
::
move
(
parameters
);
float
anisotropy
=
m_latest_parameters
.
anisotropy
;
if
(
anisotropy
==
-
1.
f
)
gl
::
getFloatv
(
gl
::
GetParameter
::
eMaxTextureMaxAnisotropy
,
&
anisotropy
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eMaxAnisotropy
,
anisotropy
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eWrapR
,
m_latest_parameters
.
wrap_r
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eWrapS
,
m_latest_parameters
.
wrap_s
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eWrapT
,
m_latest_parameters
.
wrap_t
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eMagFilter
,
m_latest_parameters
.
filter_mag
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eMinFilter
,
m_latest_parameters
.
filter_min
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eCompareMode
,
m_latest_parameters
.
compare_mode
);
gl
::
textureParameter
(
m_handle
,
gl
::
TextureParameter
::
eCompareFunc
,
m_latest_parameters
.
compare_func
);
gl
::
generateTextureMipmap
(
m_handle
);
}
unsigned
id
()
const
{
return
m_handle
;
}
bool
textureResident
()
const
{
return
m_texture_address
!=
0
&&
gl
::
isTextureHandleResident
(
m_texture_address
);
}
bool
imageResident
()
const
{
return
m_image_address
!=
0
&&
gl
::
isImageHandleResident
(
m_image_address
);
}
uint64_t
textureAddress
()
const
{
if
(
!
textureResident
())
{
m_texture_address
=
gl
::
getTextureHandle
(
m_handle
);
gl
::
makeTextureHandleResident
(
m_texture_address
);
}
assert
(
textureResident
());
return
m_texture_address
;
}
uint64_t
imageAddress
(
gl
::
Access
access
)
const
{
if
(
!
imageResident
())
{
m_image_address
=
gl
::
getImageHandle
(
m_handle
,
0
,
false
,
0
,
gl
::
ImageUnitFormat
(
m_format
));
gl
::
makeImageHandleResident
(
m_image_address
,
access
);
}
assert
(
imageResident
());
return
m_image_address
;
}
int
samples
()
const
{
int
s
;
gl
::
getTextureLevelParameteriv
(
m_handle
,
0
,
gl
::
TextureLevelParameter
::
eSamples
,
&
s
);
return
s
;
}
gl
::
Type
type
()
const
{
gl
::
Type
type
;
gl
::
getInternalFormatParameter
(
m_target
,
m_format
,
gl
::
TextureInternalFormatParameter
::
eTextureImageType
,
reinterpret_cast
<
int
*>
(
&
type
));
return
type
;
}
int
width
()
const
{
int
width
;
gl
::
getTextureLevelParameteriv
(
m_handle
,
0
,
gl
::
TextureLevelParameter
::
eWidth
,
&
width
);
return
width
;
}
int
height
()
const
{
int
height
;
gl
::
getTextureLevelParameteriv
(
m_handle
,
0
,
gl
::
TextureLevelParameter
::
eHeight
,
&
height
);
return
height
;
}
int
depth
()
const
{
int
depth
;
gl
::
getTextureLevelParameteriv
(
m_handle
,
0
,
gl
::
TextureLevelParameter
::
eDepth
,
&
depth
);
return
depth
;
}
private:
template
<
typename
T
>
static
StoreFormat
getFormat
(
const
Image
<
T
>&
image
)
{
switch
(
image
.
components
())
{
case
1
:
if
constexpr
(
std
::
is_same_v
<
T
,
float
>
)
return
gl
::
TextureInternalFormat
::
eR32Float
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint8_t
>
)
return
gl
::
TextureInternalFormat
::
eR8
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint16_t
>
)
return
gl
::
TextureInternalFormat
::
eR16UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint32_t
>
)
return
gl
::
TextureInternalFormat
::
eR32UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int8_t
>
)
return
gl
::
TextureInternalFormat
::
eR8Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int16_t
>
)
return
gl
::
TextureInternalFormat
::
eR16Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int32_t
>
)
return
gl
::
TextureInternalFormat
::
eR32Int
;
case
2
:
if
constexpr
(
std
::
is_same_v
<
T
,
float
>
)
return
gl
::
TextureInternalFormat
::
eRG32Float
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint8_t
>
)
return
gl
::
TextureInternalFormat
::
eRG8
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint16_t
>
)
return
gl
::
TextureInternalFormat
::
eRG16UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint32_t
>
)
return
gl
::
TextureInternalFormat
::
eRG32UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int8_t
>
)
return
gl
::
TextureInternalFormat
::
eRG8Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int16_t
>
)
return
gl
::
TextureInternalFormat
::
eRG16Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int32_t
>
)
return
gl
::
TextureInternalFormat
::
eRG32Int
;
case
3
:
if
constexpr
(
std
::
is_same_v
<
T
,
float
>
)
return
gl
::
TextureInternalFormat
::
eRGB32Float
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint8_t
>
)
return
gl
::
TextureInternalFormat
::
eRGB8
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint16_t
>
)
return
gl
::
TextureInternalFormat
::
eRGB16UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint32_t
>
)
return
gl
::
TextureInternalFormat
::
eRGB32UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int8_t
>
)
return
gl
::
TextureInternalFormat
::
eRGB8Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int16_t
>
)
return
gl
::
TextureInternalFormat
::
eRGB16Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int32_t
>
)
return
gl
::
TextureInternalFormat
::
eRGB32Int
;
case
4
:
if
constexpr
(
std
::
is_same_v
<
T
,
float
>
)
return
gl
::
TextureInternalFormat
::
eRGBA32Float
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint8_t
>
)
return
gl
::
TextureInternalFormat
::
eRGBA8
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint16_t
>
)
return
gl
::
TextureInternalFormat
::
eRGBA16UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
uint32_t
>
)
return
gl
::
TextureInternalFormat
::
eRGBA32UInt
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int8_t
>
)
return
gl
::
TextureInternalFormat
::
eRGBA8Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int16_t
>
)
return
gl
::
TextureInternalFormat
::
eRGBA16Int
;
else
if
constexpr
(
std
::
is_same_v
<
T
,
int32_t
>
)
return
gl
::
TextureInternalFormat
::
eRGBA32Int
;
throw
std
::
invalid_argument
(
"Using images other than 32 bit float and integral types is not yet implemented"
);
default:
throw
std
::
invalid_argument
(
"Malformed image! Component count not in range 1 to 4."
);
}
}
int
m_components
=
-
1
;
Target
m_target
;
StoreFormat
m_format
;
Parameters
m_latest_parameters
;
gl
::
handle
::
texture
m_handle
;
mutable
uint64_t
m_texture_address
=
0
;
mutable
uint64_t
m_image_address
=
0
;
};
int
main
()
{
auto
context_id
=
glare
::
core
::
Context
::
createAsCurrent
(
files
::
asset
(
"/preferences/default.xml"
));
Image
<
uint8_t
>
image_src
(
files
::
asset
(
"/textures/bricky.png"
));
Texture
texture
(
image_src
);
auto
image
=
texture
.
get
<
uint8_t
>
();
image
.
save
(
files
::
asset
(
"/screenshots/bricky_output.png"
));
auto
imageF
=
texture
.
get
<
int
>
();
imageF
.
save
(
files
::
asset
(
"/screenshots/bricky_output_float.png"
));
imageF
.
save
(
files
::
asset
(
"/screenshots/bricky_output_float.hdr"
));
auto
texrend
=
glare
::
core
::
DefaultTextureRenderers
::
makeSimpleRenderer
();
glare
::
core
::
Context
::
current
().
loop
([
&
](){
texrend
->
draw
(
texture
.
textureAddress
());
});
system
(
"pause"
);
return
0
;
}
\ No newline at end of file
src/libraries/util/opengl.cpp
View file @
df9e0370
...
...
@@ -607,7 +607,7 @@ namespace gl
{
case
gl
::
ImageTarget
::
e1D
:
case
gl
::
ImageTarget
::
e1DProxy
:
assert
(
dimensions
.
size
()
=
=
1
);
assert
(
dimensions
.
size
()
>
=
1
);
gl
::
textureImage1D
(
texture
,
gl
::
TextureImageTarget1D
(
target
),
level
,
fmt
,
dimensions
.
begin
()[
0
],
0
,
format
,
typeFromInternal
(
texture_target
,
fmt
),
data
);
break
;
...
...
@@ -624,7 +624,7 @@ namespace gl
case
gl
::
ImageTarget
::
eCubeMapNegY
:
case
gl
::
ImageTarget
::
eCubeMapPosZ
:
case
gl
::
ImageTarget
::
eCubeMapNegZ
:
assert
(
dimensions
.
size
()
=
=
2
);
assert
(
dimensions
.
size
()
>
=
2
);