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

View File

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

View File

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

View File

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

View File

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

View File

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