mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
custom color and depth formats for render target
This commit is contained in:
@@ -46,9 +46,13 @@ namespace e2d
|
|||||||
class pixel_declaration final {
|
class pixel_declaration final {
|
||||||
public:
|
public:
|
||||||
enum class pixel_type : u8 {
|
enum class pixel_type : u8 {
|
||||||
rgba8,
|
depth16,
|
||||||
|
depth24,
|
||||||
depth24_stencil8,
|
depth24_stencil8,
|
||||||
|
|
||||||
|
rgb8,
|
||||||
|
rgba8,
|
||||||
|
|
||||||
dxt1,
|
dxt1,
|
||||||
dxt3,
|
dxt3,
|
||||||
dxt5,
|
dxt5,
|
||||||
@@ -57,7 +61,7 @@ namespace e2d
|
|||||||
rgb_pvrtc4,
|
rgb_pvrtc4,
|
||||||
|
|
||||||
rgba_pvrtc2,
|
rgba_pvrtc2,
|
||||||
rgba_pvrtc4
|
rgba_pvrtc4,
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
pixel_declaration() = default;
|
pixel_declaration() = default;
|
||||||
@@ -69,6 +73,9 @@ namespace e2d
|
|||||||
pixel_declaration(pixel_type type) noexcept;
|
pixel_declaration(pixel_type type) noexcept;
|
||||||
|
|
||||||
pixel_type type() const noexcept;
|
pixel_type type() const noexcept;
|
||||||
|
bool is_color() const noexcept;
|
||||||
|
bool is_depth() const noexcept;
|
||||||
|
bool is_stencil() const noexcept;
|
||||||
bool is_compressed() const noexcept;
|
bool is_compressed() const noexcept;
|
||||||
std::size_t bits_per_pixel() const noexcept;
|
std::size_t bits_per_pixel() const noexcept;
|
||||||
private:
|
private:
|
||||||
@@ -296,7 +303,7 @@ namespace e2d
|
|||||||
using internal_state_uptr = std::unique_ptr<internal_state>;
|
using internal_state_uptr = std::unique_ptr<internal_state>;
|
||||||
const internal_state& state() const noexcept;
|
const internal_state& state() const noexcept;
|
||||||
public:
|
public:
|
||||||
enum class type : u8 {
|
enum class external_texture : u8 {
|
||||||
color = (1 << 0),
|
color = (1 << 0),
|
||||||
depth = (1 << 1),
|
depth = (1 << 1),
|
||||||
color_and_depth = color | depth
|
color_and_depth = color | depth
|
||||||
@@ -730,7 +737,9 @@ namespace e2d
|
|||||||
|
|
||||||
render_target_ptr create_render_target(
|
render_target_ptr create_render_target(
|
||||||
const v2u& size,
|
const v2u& size,
|
||||||
render_target::type type);
|
const pixel_declaration& color_decl,
|
||||||
|
const pixel_declaration& depth_decl,
|
||||||
|
render_target::external_texture external_texture);
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
const material& mat,
|
const material& mat,
|
||||||
|
|||||||
@@ -186,7 +186,9 @@ int e2d_main() {
|
|||||||
|
|
||||||
const auto rt = the<render>().create_render_target(
|
const auto rt = the<render>().create_render_target(
|
||||||
the<window>().real_size() / 10u,
|
the<window>().real_size() / 10u,
|
||||||
render_target::type::color_and_depth);
|
pixel_declaration::pixel_type::rgba8,
|
||||||
|
pixel_declaration::pixel_type::depth16,
|
||||||
|
render_target::external_texture::color_and_depth);
|
||||||
|
|
||||||
const keyboard& k = the<input>().keyboard();
|
const keyboard& k = the<input>().keyboard();
|
||||||
while ( !the<window>().should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
|
while ( !the<window>().should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ namespace
|
|||||||
struct pixel_type_description {
|
struct pixel_type_description {
|
||||||
u32 minimal_size;
|
u32 minimal_size;
|
||||||
u32 bits_per_pixel;
|
u32 bits_per_pixel;
|
||||||
|
bool color;
|
||||||
|
bool depth;
|
||||||
|
bool stencil;
|
||||||
pixel_declaration::pixel_type type;
|
pixel_declaration::pixel_type type;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
bool must_be_square;
|
bool must_be_square;
|
||||||
@@ -20,17 +23,21 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
const pixel_type_description pixel_type_descriptions[] = {
|
const pixel_type_description pixel_type_descriptions[] = {
|
||||||
{1, 32, pixel_declaration::pixel_type::rgba8, false, false, false},
|
{1, 16, false, true, false, pixel_declaration::pixel_type::depth16, false, false, false},
|
||||||
{1, 32, pixel_declaration::pixel_type::depth24_stencil8, false, false, false},
|
{1, 24, false, true, false, pixel_declaration::pixel_type::depth24, false, false, false},
|
||||||
|
{1, 32, false, true, true, pixel_declaration::pixel_type::depth24_stencil8, false, false, false},
|
||||||
|
|
||||||
{4, 4, pixel_declaration::pixel_type::dxt1, true, false, true},
|
{1, 24, true, false, false, pixel_declaration::pixel_type::rgb8, false, false, false},
|
||||||
{4, 8, pixel_declaration::pixel_type::dxt3, true, false, true},
|
{1, 32, true, false, false, pixel_declaration::pixel_type::rgba8, false, false, false},
|
||||||
{4, 8, pixel_declaration::pixel_type::dxt5, true, false, true},
|
|
||||||
|
|
||||||
{8, 2, pixel_declaration::pixel_type::rgb_pvrtc2, true, true, true},
|
{4, 4, true, false, false, pixel_declaration::pixel_type::dxt1, true, false, true},
|
||||||
{8, 4, pixel_declaration::pixel_type::rgb_pvrtc4, true, true, true},
|
{4, 8, true, false, false, pixel_declaration::pixel_type::dxt3, true, false, true},
|
||||||
{8, 2, pixel_declaration::pixel_type::rgba_pvrtc2, true, true, true},
|
{4, 8, true, false, false, pixel_declaration::pixel_type::dxt5, true, false, true},
|
||||||
{8, 4, pixel_declaration::pixel_type::rgba_pvrtc4, true, true, true}
|
|
||||||
|
{8, 2, true, false, false, pixel_declaration::pixel_type::rgb_pvrtc2, true, true, true},
|
||||||
|
{8, 4, true, false, false, pixel_declaration::pixel_type::rgb_pvrtc4, true, true, true},
|
||||||
|
{8, 2, true, false, false, pixel_declaration::pixel_type::rgba_pvrtc2, true, true, true},
|
||||||
|
{8, 4, true, false, false, pixel_declaration::pixel_type::rgba_pvrtc4, true, true, true}
|
||||||
};
|
};
|
||||||
|
|
||||||
const pixel_type_description& get_pixel_type_description(pixel_declaration::pixel_type type) noexcept {
|
const pixel_type_description& get_pixel_type_description(pixel_declaration::pixel_type type) noexcept {
|
||||||
@@ -82,6 +89,18 @@ namespace e2d
|
|||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pixel_declaration::is_color() const noexcept {
|
||||||
|
return get_pixel_type_description(type_).color;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pixel_declaration::is_depth() const noexcept {
|
||||||
|
return get_pixel_type_description(type_).depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pixel_declaration::is_stencil() const noexcept {
|
||||||
|
return get_pixel_type_description(type_).stencil;
|
||||||
|
}
|
||||||
|
|
||||||
bool pixel_declaration::is_compressed() const noexcept {
|
bool pixel_declaration::is_compressed() const noexcept {
|
||||||
return get_pixel_type_description(type_).compressed;
|
return get_pixel_type_description(type_).compressed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ namespace e2d
|
|||||||
GL_CHECK_CODE(state_->dbg(), glCompressedTexImage2D(
|
GL_CHECK_CODE(state_->dbg(), glCompressedTexImage2D(
|
||||||
id.target(),
|
id.target(),
|
||||||
0,
|
0,
|
||||||
convert_pixel_type_to_compressed_format(decl.type()),
|
convert_pixel_type_to_internal_format_e(decl.type()),
|
||||||
math::numeric_cast<GLsizei>(image.size().x),
|
math::numeric_cast<GLsizei>(image.size().x),
|
||||||
math::numeric_cast<GLsizei>(image.size().y),
|
math::numeric_cast<GLsizei>(image.size().y),
|
||||||
0,
|
0,
|
||||||
@@ -549,7 +549,7 @@ namespace e2d
|
|||||||
GL_CHECK_CODE(state_->dbg(), glCompressedTexImage2D(
|
GL_CHECK_CODE(state_->dbg(), glCompressedTexImage2D(
|
||||||
id.target(),
|
id.target(),
|
||||||
0,
|
0,
|
||||||
convert_pixel_type_to_compressed_format(decl.type()),
|
convert_pixel_type_to_internal_format_e(decl.type()),
|
||||||
math::numeric_cast<GLsizei>(size.x),
|
math::numeric_cast<GLsizei>(size.x),
|
||||||
math::numeric_cast<GLsizei>(size.y),
|
math::numeric_cast<GLsizei>(size.y),
|
||||||
0,
|
0,
|
||||||
@@ -611,8 +611,15 @@ namespace e2d
|
|||||||
|
|
||||||
render_target_ptr render::create_render_target(
|
render_target_ptr render::create_render_target(
|
||||||
const v2u& size,
|
const v2u& size,
|
||||||
render_target::type type)
|
const pixel_declaration& color_decl,
|
||||||
|
const pixel_declaration& depth_decl,
|
||||||
|
render_target::external_texture external_texture)
|
||||||
{
|
{
|
||||||
|
E2D_ASSERT(
|
||||||
|
depth_decl.is_depth() &&
|
||||||
|
color_decl.is_color() &&
|
||||||
|
!color_decl.is_compressed());
|
||||||
|
|
||||||
gl_framebuffer_id id = gl_framebuffer_id::create(
|
gl_framebuffer_id id = gl_framebuffer_id::create(
|
||||||
state_->dbg(), GL_FRAMEBUFFER);
|
state_->dbg(), GL_FRAMEBUFFER);
|
||||||
if ( id.empty() ) {
|
if ( id.empty() ) {
|
||||||
@@ -621,8 +628,13 @@ namespace e2d
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool need_color = math::enum_to_number(type) & math::enum_to_number(render_target::type::color);
|
bool need_color =
|
||||||
bool need_depth = math::enum_to_number(type) & math::enum_to_number(render_target::type::depth);
|
math::enum_to_number(external_texture)
|
||||||
|
& math::enum_to_number(render_target::external_texture::color);
|
||||||
|
|
||||||
|
bool need_depth =
|
||||||
|
math::enum_to_number(external_texture)
|
||||||
|
& math::enum_to_number(render_target::external_texture::depth);
|
||||||
|
|
||||||
texture_ptr color;
|
texture_ptr color;
|
||||||
texture_ptr depth;
|
texture_ptr depth;
|
||||||
@@ -631,7 +643,7 @@ namespace e2d
|
|||||||
gl_renderbuffer_id depth_rb(state_->dbg());
|
gl_renderbuffer_id depth_rb(state_->dbg());
|
||||||
|
|
||||||
if ( need_color ) {
|
if ( need_color ) {
|
||||||
color = create_texture(size, pixel_declaration::pixel_type::rgba8);
|
color = create_texture(size, color_decl);
|
||||||
if ( !color ) {
|
if ( !color ) {
|
||||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||||
"failed to create color texture");
|
"failed to create color texture");
|
||||||
@@ -639,7 +651,10 @@ namespace e2d
|
|||||||
}
|
}
|
||||||
gl_attach_texture(state_->dbg(), id, color->state().id(), GL_COLOR_ATTACHMENT0);
|
gl_attach_texture(state_->dbg(), id, color->state().id(), GL_COLOR_ATTACHMENT0);
|
||||||
} else {
|
} else {
|
||||||
color_rb = gl_compile_renderbuffer(state_->dbg(), size, GL_RGBA8);
|
color_rb = gl_compile_renderbuffer(
|
||||||
|
state_->dbg(),
|
||||||
|
size,
|
||||||
|
convert_pixel_type_to_internal_format_e(color_decl.type()));
|
||||||
if ( color_rb.empty() ) {
|
if ( color_rb.empty() ) {
|
||||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||||
"failed to create color renderbuffer");
|
"failed to create color renderbuffer");
|
||||||
@@ -649,23 +664,30 @@ namespace e2d
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( need_depth ) {
|
if ( need_depth ) {
|
||||||
depth = create_texture(size, pixel_declaration::pixel_type::depth24_stencil8);
|
depth = create_texture(size, depth_decl);
|
||||||
if ( !depth ) {
|
if ( !depth ) {
|
||||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||||
"failed to create depth texture");
|
"failed to create depth texture");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
gl_attach_texture(state_->dbg(), id, depth->state().id(), GL_DEPTH_ATTACHMENT);
|
gl_attach_texture(state_->dbg(), id, depth->state().id(), GL_DEPTH_ATTACHMENT);
|
||||||
gl_attach_texture(state_->dbg(), id, depth->state().id(), GL_STENCIL_ATTACHMENT);
|
if ( depth_decl.is_stencil() ) {
|
||||||
|
gl_attach_texture(state_->dbg(), id, depth->state().id(), GL_STENCIL_ATTACHMENT);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
depth_rb = gl_compile_renderbuffer(state_->dbg(), size, GL_DEPTH24_STENCIL8);
|
depth_rb = gl_compile_renderbuffer(
|
||||||
|
state_->dbg(),
|
||||||
|
size,
|
||||||
|
convert_pixel_type_to_internal_format_e(depth_decl.type()));
|
||||||
if ( depth_rb.empty() ) {
|
if ( depth_rb.empty() ) {
|
||||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||||
"failed to create depth renderbuffer");
|
"failed to create depth renderbuffer");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
gl_attach_renderbuffer(state_->dbg(), id, depth_rb, GL_DEPTH_ATTACHMENT);
|
gl_attach_renderbuffer(state_->dbg(), id, depth_rb, GL_DEPTH_ATTACHMENT);
|
||||||
gl_attach_renderbuffer(state_->dbg(), id, depth_rb, GL_STENCIL_ATTACHMENT);
|
if ( depth_decl.is_stencil() ) {
|
||||||
|
gl_attach_renderbuffer(state_->dbg(), id, depth_rb, GL_STENCIL_ATTACHMENT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum fb_status = GL_FRAMEBUFFER_COMPLETE;
|
GLenum fb_status = GL_FRAMEBUFFER_COMPLETE;
|
||||||
|
|||||||
@@ -718,8 +718,11 @@ namespace e2d { namespace opengl
|
|||||||
GLenum convert_pixel_type_to_external_format(pixel_declaration::pixel_type f) noexcept {
|
GLenum convert_pixel_type_to_external_format(pixel_declaration::pixel_type f) noexcept {
|
||||||
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
||||||
switch ( f ) {
|
switch ( f ) {
|
||||||
DEFINE_CASE(rgba8, GL_RGBA);
|
DEFINE_CASE(depth16, GL_DEPTH_COMPONENT);
|
||||||
|
DEFINE_CASE(depth24, GL_DEPTH_COMPONENT);
|
||||||
DEFINE_CASE(depth24_stencil8, GL_DEPTH_STENCIL);
|
DEFINE_CASE(depth24_stencil8, GL_DEPTH_STENCIL);
|
||||||
|
DEFINE_CASE(rgb8, GL_RGB);
|
||||||
|
DEFINE_CASE(rgba8, GL_RGBA);
|
||||||
default:
|
default:
|
||||||
E2D_ASSERT_MSG(false, "unexpected pixel type");
|
E2D_ASSERT_MSG(false, "unexpected pixel type");
|
||||||
return GL_RGBA;
|
return GL_RGBA;
|
||||||
@@ -730,8 +733,11 @@ namespace e2d { namespace opengl
|
|||||||
GLenum convert_pixel_type_to_external_data_type(pixel_declaration::pixel_type f) noexcept {
|
GLenum convert_pixel_type_to_external_data_type(pixel_declaration::pixel_type f) noexcept {
|
||||||
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
||||||
switch ( f ) {
|
switch ( f ) {
|
||||||
DEFINE_CASE(rgba8, GL_UNSIGNED_BYTE);
|
DEFINE_CASE(depth16, GL_UNSIGNED_SHORT);
|
||||||
|
DEFINE_CASE(depth24, GL_UNSIGNED_INT);
|
||||||
DEFINE_CASE(depth24_stencil8, GL_UNSIGNED_INT_24_8);
|
DEFINE_CASE(depth24_stencil8, GL_UNSIGNED_INT_24_8);
|
||||||
|
DEFINE_CASE(rgb8, GL_UNSIGNED_BYTE);
|
||||||
|
DEFINE_CASE(rgba8, GL_UNSIGNED_BYTE);
|
||||||
default:
|
default:
|
||||||
E2D_ASSERT_MSG(false, "unexpected pixel type");
|
E2D_ASSERT_MSG(false, "unexpected pixel type");
|
||||||
return GL_UNSIGNED_BYTE;
|
return GL_UNSIGNED_BYTE;
|
||||||
@@ -742,18 +748,13 @@ namespace e2d { namespace opengl
|
|||||||
GLint convert_pixel_type_to_internal_format(pixel_declaration::pixel_type f) noexcept {
|
GLint convert_pixel_type_to_internal_format(pixel_declaration::pixel_type f) noexcept {
|
||||||
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
||||||
switch ( f ) {
|
switch ( f ) {
|
||||||
DEFINE_CASE(rgba8, GL_RGBA);
|
DEFINE_CASE(depth16, GL_DEPTH_COMPONENT16);
|
||||||
|
DEFINE_CASE(depth24, GL_DEPTH_COMPONENT24);
|
||||||
DEFINE_CASE(depth24_stencil8, GL_DEPTH24_STENCIL8);
|
DEFINE_CASE(depth24_stencil8, GL_DEPTH24_STENCIL8);
|
||||||
default:
|
|
||||||
E2D_ASSERT_MSG(false, "unexpected pixel type");
|
|
||||||
return GL_RGBA;
|
|
||||||
}
|
|
||||||
#undef DEFINE_CASE
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum convert_pixel_type_to_compressed_format(pixel_declaration::pixel_type f) noexcept {
|
DEFINE_CASE(rgb8, GL_RGB);
|
||||||
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
DEFINE_CASE(rgba8, GL_RGBA);
|
||||||
switch ( f ) {
|
|
||||||
DEFINE_CASE(dxt1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
|
DEFINE_CASE(dxt1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
|
||||||
DEFINE_CASE(dxt3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
|
DEFINE_CASE(dxt3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
|
||||||
DEFINE_CASE(dxt5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
|
DEFINE_CASE(dxt5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
|
||||||
@@ -770,12 +771,16 @@ namespace e2d { namespace opengl
|
|||||||
#undef DEFINE_CASE
|
#undef DEFINE_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLenum convert_pixel_type_to_internal_format_e(pixel_declaration::pixel_type f) noexcept {
|
||||||
|
return math::numeric_cast<GLenum>(convert_pixel_type_to_internal_format(f));
|
||||||
|
}
|
||||||
|
|
||||||
pixel_declaration convert_image_data_format_to_pixel_declaration(image_data_format f) noexcept {
|
pixel_declaration convert_image_data_format_to_pixel_declaration(image_data_format f) noexcept {
|
||||||
#define DEFINE_CASE(x,y) case image_data_format::x: return pixel_declaration(pixel_declaration::pixel_type::y)
|
#define DEFINE_CASE(x,y) case image_data_format::x: return pixel_declaration::pixel_type::y
|
||||||
switch ( f ) {
|
switch ( f ) {
|
||||||
DEFINE_CASE(g8, rgba8);
|
DEFINE_CASE(g8, rgb8);
|
||||||
DEFINE_CASE(ga8, rgba8);
|
DEFINE_CASE(ga8, rgba8);
|
||||||
DEFINE_CASE(rgb8, rgba8);
|
DEFINE_CASE(rgb8, rgb8);
|
||||||
DEFINE_CASE(rgba8, rgba8);
|
DEFINE_CASE(rgba8, rgba8);
|
||||||
|
|
||||||
DEFINE_CASE(dxt1, dxt1);
|
DEFINE_CASE(dxt1, dxt1);
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ namespace e2d { namespace opengl
|
|||||||
GLenum convert_pixel_type_to_external_data_type(pixel_declaration::pixel_type f) noexcept;
|
GLenum convert_pixel_type_to_external_data_type(pixel_declaration::pixel_type f) noexcept;
|
||||||
|
|
||||||
GLint convert_pixel_type_to_internal_format(pixel_declaration::pixel_type f) noexcept;
|
GLint convert_pixel_type_to_internal_format(pixel_declaration::pixel_type f) noexcept;
|
||||||
GLenum convert_pixel_type_to_compressed_format(pixel_declaration::pixel_type f) noexcept;
|
GLenum convert_pixel_type_to_internal_format_e(pixel_declaration::pixel_type f) noexcept;
|
||||||
pixel_declaration convert_image_data_format_to_pixel_declaration(image_data_format f) noexcept;
|
pixel_declaration convert_image_data_format_to_pixel_declaration(image_data_format f) noexcept;
|
||||||
|
|
||||||
GLenum convert_index_type(index_declaration::index_type it) noexcept;
|
GLenum convert_index_type(index_declaration::index_type it) noexcept;
|
||||||
|
|||||||
Reference in New Issue
Block a user