custom color and depth formats for render target

This commit is contained in:
2018-10-23 16:22:38 +07:00
parent 687992e68f
commit f6dc7d2ee6
6 changed files with 98 additions and 41 deletions

View File

@@ -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,

View File

@@ -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) ) {

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;