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 {
|
||||
public:
|
||||
enum class pixel_type : u8 {
|
||||
rgba8,
|
||||
depth16,
|
||||
depth24,
|
||||
depth24_stencil8,
|
||||
|
||||
rgb8,
|
||||
rgba8,
|
||||
|
||||
dxt1,
|
||||
dxt3,
|
||||
dxt5,
|
||||
@@ -57,7 +61,7 @@ namespace e2d
|
||||
rgb_pvrtc4,
|
||||
|
||||
rgba_pvrtc2,
|
||||
rgba_pvrtc4
|
||||
rgba_pvrtc4,
|
||||
};
|
||||
public:
|
||||
pixel_declaration() = default;
|
||||
@@ -69,6 +73,9 @@ namespace e2d
|
||||
pixel_declaration(pixel_type type) 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;
|
||||
std::size_t bits_per_pixel() const noexcept;
|
||||
private:
|
||||
@@ -296,7 +303,7 @@ namespace e2d
|
||||
using internal_state_uptr = std::unique_ptr<internal_state>;
|
||||
const internal_state& state() const noexcept;
|
||||
public:
|
||||
enum class type : u8 {
|
||||
enum class external_texture : u8 {
|
||||
color = (1 << 0),
|
||||
depth = (1 << 1),
|
||||
color_and_depth = color | depth
|
||||
@@ -730,7 +737,9 @@ namespace e2d
|
||||
|
||||
render_target_ptr create_render_target(
|
||||
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(
|
||||
const material& mat,
|
||||
|
||||
@@ -186,7 +186,9 @@ int e2d_main() {
|
||||
|
||||
const auto rt = the<render>().create_render_target(
|
||||
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();
|
||||
while ( !the<window>().should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
|
||||
|
||||
@@ -13,6 +13,9 @@ namespace
|
||||
struct pixel_type_description {
|
||||
u32 minimal_size;
|
||||
u32 bits_per_pixel;
|
||||
bool color;
|
||||
bool depth;
|
||||
bool stencil;
|
||||
pixel_declaration::pixel_type type;
|
||||
bool compressed;
|
||||
bool must_be_square;
|
||||
@@ -20,17 +23,21 @@ namespace
|
||||
};
|
||||
|
||||
const pixel_type_description pixel_type_descriptions[] = {
|
||||
{1, 32, pixel_declaration::pixel_type::rgba8, false, false, false},
|
||||
{1, 32, pixel_declaration::pixel_type::depth24_stencil8, false, false, false},
|
||||
{1, 16, false, true, false, pixel_declaration::pixel_type::depth16, 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},
|
||||
{4, 8, pixel_declaration::pixel_type::dxt3, true, false, true},
|
||||
{4, 8, pixel_declaration::pixel_type::dxt5, true, false, true},
|
||||
{1, 24, true, false, false, pixel_declaration::pixel_type::rgb8, false, false, false},
|
||||
{1, 32, true, false, false, pixel_declaration::pixel_type::rgba8, false, false, false},
|
||||
|
||||
{8, 2, pixel_declaration::pixel_type::rgb_pvrtc2, true, true, true},
|
||||
{8, 4, pixel_declaration::pixel_type::rgb_pvrtc4, true, true, true},
|
||||
{8, 2, pixel_declaration::pixel_type::rgba_pvrtc2, true, true, true},
|
||||
{8, 4, pixel_declaration::pixel_type::rgba_pvrtc4, true, true, true}
|
||||
{4, 4, true, false, false, pixel_declaration::pixel_type::dxt1, true, false, true},
|
||||
{4, 8, true, false, false, pixel_declaration::pixel_type::dxt3, true, false, true},
|
||||
{4, 8, true, false, false, pixel_declaration::pixel_type::dxt5, true, false, 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 {
|
||||
@@ -82,6 +89,18 @@ namespace e2d
|
||||
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 {
|
||||
return get_pixel_type_description(type_).compressed;
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ namespace e2d
|
||||
GL_CHECK_CODE(state_->dbg(), glCompressedTexImage2D(
|
||||
id.target(),
|
||||
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().y),
|
||||
0,
|
||||
@@ -549,7 +549,7 @@ namespace e2d
|
||||
GL_CHECK_CODE(state_->dbg(), glCompressedTexImage2D(
|
||||
id.target(),
|
||||
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.y),
|
||||
0,
|
||||
@@ -611,8 +611,15 @@ namespace e2d
|
||||
|
||||
render_target_ptr render::create_render_target(
|
||||
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(
|
||||
state_->dbg(), GL_FRAMEBUFFER);
|
||||
if ( id.empty() ) {
|
||||
@@ -621,8 +628,13 @@ namespace e2d
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool need_color = math::enum_to_number(type) & math::enum_to_number(render_target::type::color);
|
||||
bool need_depth = math::enum_to_number(type) & math::enum_to_number(render_target::type::depth);
|
||||
bool need_color =
|
||||
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 depth;
|
||||
@@ -631,7 +643,7 @@ namespace e2d
|
||||
gl_renderbuffer_id depth_rb(state_->dbg());
|
||||
|
||||
if ( need_color ) {
|
||||
color = create_texture(size, pixel_declaration::pixel_type::rgba8);
|
||||
color = create_texture(size, color_decl);
|
||||
if ( !color ) {
|
||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||
"failed to create color texture");
|
||||
@@ -639,7 +651,10 @@ namespace e2d
|
||||
}
|
||||
gl_attach_texture(state_->dbg(), id, color->state().id(), GL_COLOR_ATTACHMENT0);
|
||||
} 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() ) {
|
||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||
"failed to create color renderbuffer");
|
||||
@@ -649,23 +664,30 @@ namespace e2d
|
||||
}
|
||||
|
||||
if ( need_depth ) {
|
||||
depth = create_texture(size, pixel_declaration::pixel_type::depth24_stencil8);
|
||||
depth = create_texture(size, depth_decl);
|
||||
if ( !depth ) {
|
||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||
"failed to create depth texture");
|
||||
return nullptr;
|
||||
}
|
||||
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 {
|
||||
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() ) {
|
||||
state_->dbg().error("RENDER: Failed to create framebuffer: %0",
|
||||
"failed to create depth renderbuffer");
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -718,8 +718,11 @@ namespace e2d { namespace opengl
|
||||
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
|
||||
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(rgb8, GL_RGB);
|
||||
DEFINE_CASE(rgba8, GL_RGBA);
|
||||
default:
|
||||
E2D_ASSERT_MSG(false, "unexpected pixel type");
|
||||
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 {
|
||||
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
||||
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(rgb8, GL_UNSIGNED_BYTE);
|
||||
DEFINE_CASE(rgba8, GL_UNSIGNED_BYTE);
|
||||
default:
|
||||
E2D_ASSERT_MSG(false, "unexpected pixel type");
|
||||
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 {
|
||||
#define DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
||||
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);
|
||||
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 DEFINE_CASE(x,y) case pixel_declaration::pixel_type::x: return y
|
||||
switch ( f ) {
|
||||
DEFINE_CASE(rgb8, GL_RGB);
|
||||
DEFINE_CASE(rgba8, GL_RGBA);
|
||||
|
||||
DEFINE_CASE(dxt1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
|
||||
DEFINE_CASE(dxt3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
|
||||
DEFINE_CASE(dxt5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
|
||||
@@ -770,12 +771,16 @@ namespace e2d { namespace opengl
|
||||
#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 {
|
||||
#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 ) {
|
||||
DEFINE_CASE(g8, rgba8);
|
||||
DEFINE_CASE(g8, rgb8);
|
||||
DEFINE_CASE(ga8, rgba8);
|
||||
DEFINE_CASE(rgb8, rgba8);
|
||||
DEFINE_CASE(rgb8, rgb8);
|
||||
DEFINE_CASE(rgba8, rgba8);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
GLenum convert_index_type(index_declaration::index_type it) noexcept;
|
||||
|
||||
Reference in New Issue
Block a user