mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
grab_XXX functions are temporarily removed
This commit is contained in:
@@ -961,23 +961,6 @@ namespace e2d
|
||||
buffer_view pixels,
|
||||
const b2u& region);
|
||||
|
||||
// very slow
|
||||
render& grab_texture(
|
||||
const texture_ptr& tex,
|
||||
const b2u& region,
|
||||
image& result);
|
||||
|
||||
// very slow
|
||||
render& grab_render_target(
|
||||
const render_target_ptr& rt,
|
||||
const b2u& region,
|
||||
image& result);
|
||||
|
||||
// very slow
|
||||
render& grab_screen(
|
||||
const b2u& region,
|
||||
image& result);
|
||||
|
||||
const device_caps& device_capabilities() const noexcept;
|
||||
bool is_pixel_supported(const pixel_declaration& decl) const noexcept;
|
||||
bool is_index_supported(const index_declaration& decl) const noexcept;
|
||||
|
||||
@@ -286,35 +286,6 @@ namespace e2d
|
||||
E2D_UNUSED(tex, pixels, region);
|
||||
return *this;
|
||||
}
|
||||
|
||||
render& render::grab_texture(
|
||||
const texture_ptr& tex,
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
E2D_UNUSED(tex, region);
|
||||
result.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
render& render::grab_render_target(
|
||||
const render_target_ptr& rt,
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
E2D_UNUSED(rt, region);
|
||||
result.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
render& render::grab_screen(
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
E2D_UNUSED(tex);
|
||||
result.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const render::device_caps& render::device_capabilities() const noexcept {
|
||||
static device_caps caps;
|
||||
|
||||
@@ -301,147 +301,6 @@ namespace
|
||||
static render::property_block props;
|
||||
return props;
|
||||
}
|
||||
|
||||
void grab_framebuffer_content(
|
||||
debug& debug,
|
||||
const opengl::gl_framebuffer_id& fb,
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
with_gl_bind_framebuffer(debug, fb,
|
||||
[&debug, ®ion, &result]() {
|
||||
GLint format;
|
||||
GLint type;
|
||||
GL_CHECK_CODE(debug, glGetIntegerv(
|
||||
GL_IMPLEMENTATION_COLOR_READ_FORMAT,
|
||||
&format));
|
||||
GL_CHECK_CODE(debug, glGetIntegerv(
|
||||
GL_IMPLEMENTATION_COLOR_READ_TYPE,
|
||||
&type));
|
||||
|
||||
image_data_format img_format;
|
||||
if ( (format == GL_ALPHA || format == GL_LUMINANCE) && type == GL_UNSIGNED_BYTE ) {
|
||||
img_format = image_data_format::g8;
|
||||
} else if ( format == GL_RGB && type == GL_UNSIGNED_BYTE ) {
|
||||
img_format = image_data_format::rgb8;
|
||||
} else if ( format == GL_RGBA && type == GL_UNSIGNED_BYTE ) {
|
||||
img_format = image_data_format::rgba8;
|
||||
} else {
|
||||
E2D_ASSERT_MSG(false, "unsupported pixel format");
|
||||
// OpenGL ES 2 already supports RGBA8 format for glReadPixels
|
||||
format = GL_RGBA;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
img_format = image_data_format::rgba8;
|
||||
}
|
||||
|
||||
pixel_declaration decl = convert_image_data_format_to_pixel_declaration(img_format);
|
||||
buffer pixels;
|
||||
pixels.resize(((decl.bits_per_pixel() * region.size.x) / 8u) * region.size.y);
|
||||
|
||||
GL_CHECK_CODE(debug, glReadPixels(
|
||||
math::numeric_cast<GLint>(region.position.x),
|
||||
math::numeric_cast<GLint>(region.position.y),
|
||||
math::numeric_cast<GLsizei>(region.size.x),
|
||||
math::numeric_cast<GLsizei>(region.size.y),
|
||||
format,
|
||||
type,
|
||||
pixels.data()));
|
||||
result = image(region.size, img_format, std::move(pixels));
|
||||
});
|
||||
}
|
||||
|
||||
void grab_compressed_texture(
|
||||
render& render,
|
||||
const texture_ptr& tex,
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
const char vs_source[] = R"glsl(
|
||||
#version 120
|
||||
|
||||
attribute vec2 a_position;
|
||||
varying vec2 v_uv;
|
||||
|
||||
void main(){
|
||||
v_uv = a_position * 0.5 + 0.5;
|
||||
gl_Position = vec4(a_position.xy, 0.0, 1.0);
|
||||
}
|
||||
)glsl";
|
||||
|
||||
const char fs_source[] = R"glsl(
|
||||
#version 120
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
varying vec2 v_uv;
|
||||
|
||||
void main(){
|
||||
gl_FragColor = texture2D(u_texture, v_uv);
|
||||
}
|
||||
)glsl";
|
||||
|
||||
const v2f vertices[] = {
|
||||
v2f(-1.0f, 1.0f), v2f(-1.0f, -1.0f), v2f(1.0f, 1.0f), v2f(1.0f, -1.0f)
|
||||
};
|
||||
|
||||
shader_ptr shader = render.create_shader(vs_source, fs_source);
|
||||
if ( !shader ) {
|
||||
throw bad_render_operation();
|
||||
}
|
||||
|
||||
vertex_buffer_ptr vbuffer = render.create_vertex_buffer(
|
||||
buffer_view(vertices),
|
||||
vertex_declaration().add_attribute<v2f>("a_position"),
|
||||
vertex_buffer::usage::static_draw);
|
||||
if ( !vbuffer ) {
|
||||
throw bad_render_operation();
|
||||
}
|
||||
|
||||
render::geometry geometry;
|
||||
geometry.add_vertices(vbuffer);
|
||||
geometry.topo(render::topology::triangles_strip);
|
||||
|
||||
render::material material;
|
||||
material.add_pass(render::pass_state()
|
||||
.shader(shader)
|
||||
.properties(render::property_block()
|
||||
.sampler("u_texture", render::sampler_state()
|
||||
.texture(tex)
|
||||
.min_filter(render::sampler_min_filter::nearest)
|
||||
.mag_filter(render::sampler_mag_filter::nearest))));
|
||||
|
||||
// convert compressed format to non-compressed
|
||||
const auto convert_to_noncompressed = [](pixel_declaration decl) {
|
||||
#define DEFINE_CASE(x, y) case pixel_declaration::pixel_type::x: return pixel_declaration::pixel_type::y;
|
||||
switch ( decl.type() ) {
|
||||
DEFINE_CASE(rgb_dxt1, rgba8)
|
||||
DEFINE_CASE(rgba_dxt1, rgba8)
|
||||
DEFINE_CASE(rgba_dxt3, rgba8)
|
||||
DEFINE_CASE(rgba_dxt5, rgba8)
|
||||
DEFINE_CASE(rgb_pvrtc2, rgba8)
|
||||
DEFINE_CASE(rgb_pvrtc4, rgba8)
|
||||
DEFINE_CASE(rgba_pvrtc2, rgba8)
|
||||
DEFINE_CASE(rgba_pvrtc4, rgba8)
|
||||
DEFINE_CASE(rgba_pvrtc2_v2, rgba8)
|
||||
DEFINE_CASE(rgba_pvrtc4_v2, rgba8)
|
||||
default:
|
||||
E2D_ASSERT_MSG(false, "unexpected pixel format");
|
||||
return pixel_declaration::pixel_type::rgba8;
|
||||
}
|
||||
#undef DEFINE_CASE
|
||||
};
|
||||
|
||||
render_target_ptr rt = render.create_render_target(
|
||||
tex->size(),
|
||||
convert_to_noncompressed(tex->decl()),
|
||||
pixel_declaration::pixel_type::depth16,
|
||||
render_target::external_texture::color);
|
||||
|
||||
render.execute(render::viewport_command(b2u(tex->size())));
|
||||
render.execute(render::target_command(rt));
|
||||
render.execute(render::draw_command(material, geometry));
|
||||
render.grab_render_target(rt, region, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
@@ -1228,71 +1087,6 @@ namespace e2d
|
||||
return *this;
|
||||
}
|
||||
|
||||
render& render::grab_texture(
|
||||
const texture_ptr& tex,
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
E2D_ASSERT(tex);
|
||||
E2D_ASSERT(tex->decl().is_color());
|
||||
E2D_ASSERT(region.size.x > 0 && region.size.y > 0);
|
||||
E2D_ASSERT(region.position.x + region.size.x <= tex->size().x);
|
||||
E2D_ASSERT(region.position.y + region.size.y <= tex->size().y);
|
||||
|
||||
if ( tex->decl().is_compressed() ) {
|
||||
grab_compressed_texture(*this, tex, region, result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
gl_framebuffer_id id = gl_framebuffer_id::create(state_->dbg(), GL_FRAMEBUFFER);
|
||||
if ( id.empty() ) {
|
||||
throw bad_render_operation();
|
||||
}
|
||||
gl_attach_texture(state_->dbg(), id, tex->state().id(), GL_COLOR_ATTACHMENT0);
|
||||
GLenum fb_status = GL_FRAMEBUFFER_COMPLETE;
|
||||
if ( !gl_check_framebuffer(state_->dbg(), id, &fb_status) ) {
|
||||
throw bad_render_operation();
|
||||
}
|
||||
grab_framebuffer_content(
|
||||
state_->dbg(),
|
||||
id,
|
||||
region,
|
||||
result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
render& render::grab_render_target(
|
||||
const render_target_ptr& rt,
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
E2D_ASSERT(rt);
|
||||
E2D_ASSERT(region.size.x > 0 && region.size.y > 0);
|
||||
E2D_ASSERT(region.position.x + region.size.x <= rt->size().x);
|
||||
E2D_ASSERT(region.position.y + region.size.y <= rt->size().y);
|
||||
grab_framebuffer_content(
|
||||
state_->dbg(),
|
||||
rt->state().id(),
|
||||
region,
|
||||
result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
render& render::grab_screen(
|
||||
const b2u& region,
|
||||
image& result)
|
||||
{
|
||||
E2D_ASSERT(region.size.x > 0 && region.size.y > 0);
|
||||
E2D_ASSERT(region.position.x + region.size.x <= state_->wnd().real_size().x);
|
||||
E2D_ASSERT(region.position.y + region.size.y <= state_->wnd().real_size().y);
|
||||
grab_framebuffer_content(
|
||||
state_->dbg(),
|
||||
state_->default_fb(),
|
||||
region,
|
||||
result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const render::device_caps& render::device_capabilities() const noexcept {
|
||||
E2D_ASSERT(is_in_main_thread());
|
||||
return state_->device_capabilities();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#if defined(E2D_BUILD_MODE) && E2D_BUILD_MODE == E2D_BUILD_MODE_DEBUG
|
||||
# define GL_FLUSH_ERRORS(dbg)\
|
||||
for ( GLenum err = glGetError(); err != GL_NO_ERROR; err = glGetError() ) {\
|
||||
E2D_ASSERT_MSG(false, "RENDER: GL_FLUSH_ERRORS()");\
|
||||
(dbg).log(err == GL_OUT_OF_MEMORY\
|
||||
? debug::level::fatal\
|
||||
: debug::level::error,\
|
||||
@@ -26,13 +25,13 @@
|
||||
"--> Line: %1\n"\
|
||||
"--> Code: %2",\
|
||||
__FILE__, __LINE__, e2d::opengl::gl_error_code_to_cstr(err));\
|
||||
E2D_ASSERT_MSG(false, "RENDER: GL_FLUSH_ERRORS()");\
|
||||
if ( err == GL_OUT_OF_MEMORY ) std::terminate();\
|
||||
}
|
||||
# define GL_CHECK_CODE(dbg, code)\
|
||||
GL_FLUSH_ERRORS(dbg);\
|
||||
code;\
|
||||
for ( GLenum err = glGetError(); err != GL_NO_ERROR; err = glGetError() ) {\
|
||||
E2D_ASSERT_MSG(false, #code);\
|
||||
(dbg).log(err == GL_OUT_OF_MEMORY\
|
||||
? debug::level::fatal\
|
||||
: debug::level::error,\
|
||||
@@ -41,6 +40,7 @@
|
||||
"--> Line: %2\n"\
|
||||
"--> Code: %3",\
|
||||
#code, __FILE__, __LINE__, e2d::opengl::gl_error_code_to_cstr(err));\
|
||||
E2D_ASSERT_MSG(false, #code);\
|
||||
if ( err == GL_OUT_OF_MEMORY ) std::terminate();\
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -198,12 +198,7 @@ TEST_CASE("render"){
|
||||
for ( auto& c : src ) {
|
||||
c = rand() % 255;
|
||||
}
|
||||
r.update_texture(tex, src, b2u(0, 0, 128, 128));
|
||||
|
||||
image dst;
|
||||
r.grab_texture(tex, b2u(0, 0, 128, 128), dst);
|
||||
REQUIRE(dst.format() == image_data_format::rgba8);
|
||||
REQUIRE(src == dst.data());
|
||||
REQUIRE_NOTHROW(r.update_texture(tex, src, b2u(0, 0, 128, 128)));
|
||||
}
|
||||
{
|
||||
texture_ptr tex = r.create_texture(v2u(128,128), pixel_declaration::pixel_type::g8);
|
||||
@@ -214,22 +209,7 @@ TEST_CASE("render"){
|
||||
for ( auto& c : src ) {
|
||||
c = rand() % 255;
|
||||
}
|
||||
r.update_texture(tex, src, b2u(0, 0, 128, 128));
|
||||
|
||||
image dst;
|
||||
r.grab_texture(tex, b2u(0, 0, 128, 128), dst);
|
||||
if ( dst.format() == image_data_format::g8 ) {
|
||||
REQUIRE(src == dst.data());
|
||||
} else {
|
||||
// OpenGL ES 2 may not support Alpha8 format
|
||||
REQUIRE(dst.format() == image_data_format::rgba8);
|
||||
REQUIRE(dst.data().size() == src.size()*4);
|
||||
bool equal = true;
|
||||
for ( size_t i = 0; i < src.size(); ++i ) {
|
||||
equal &= (src.data()[i] == dst.data().data()[i*4+3]);
|
||||
}
|
||||
REQUIRE(equal);
|
||||
}
|
||||
REQUIRE_NOTHROW(r.update_texture(tex, src, b2u(0, 0, 128, 128)));
|
||||
}
|
||||
{
|
||||
texture_ptr tex = r.create_texture(v2u(128,128), pixel_declaration::pixel_type::rgb8);
|
||||
@@ -240,24 +220,7 @@ TEST_CASE("render"){
|
||||
for ( auto& c : src ) {
|
||||
c = rand() % 255;
|
||||
}
|
||||
r.update_texture(tex, src, b2u(0, 0, 128, 128));
|
||||
|
||||
image dst;
|
||||
r.grab_texture(tex, b2u(0, 0, 128, 128), dst);
|
||||
if ( dst.format() == image_data_format::rgb8 ) {
|
||||
REQUIRE(src == dst.data());
|
||||
} else {
|
||||
// OpenGL ES 2 may not support RGB8 format
|
||||
REQUIRE(dst.format() == image_data_format::rgba8);
|
||||
REQUIRE(dst.data().size() == src.size()*4/3);
|
||||
bool equal = true;
|
||||
for ( size_t i = 0, j = 0; i < src.size(); i += 3, j += 4 ) {
|
||||
equal &= (src.data()[i+0] == dst.data().data()[j+0]);
|
||||
equal &= (src.data()[i+1] == dst.data().data()[j+1]);
|
||||
equal &= (src.data()[i+2] == dst.data().data()[j+2]);
|
||||
}
|
||||
REQUIRE(equal);
|
||||
}
|
||||
REQUIRE_NOTHROW(r.update_texture(tex, src, b2u(0, 0, 128, 128)));
|
||||
}
|
||||
{
|
||||
texture_ptr tex = r.create_texture(v2u(57,31), pixel_declaration::pixel_type::rgba8);
|
||||
@@ -268,12 +231,7 @@ TEST_CASE("render"){
|
||||
for ( auto& c : src ) {
|
||||
c = rand() % 255;
|
||||
}
|
||||
r.update_texture(tex, src, b2u(0, 0, 57, 31));
|
||||
|
||||
image dst;
|
||||
r.grab_texture(tex, b2u(0, 0, 57, 31), dst);
|
||||
REQUIRE(dst.format() == image_data_format::rgba8);
|
||||
REQUIRE(src == dst.data());
|
||||
REQUIRE_NOTHROW(r.update_texture(tex, src, b2u(0, 0, 57, 31)));
|
||||
}
|
||||
{
|
||||
texture_ptr tex = r.create_texture(v2u(128,128), pixel_declaration::pixel_type::rgba8);
|
||||
@@ -284,25 +242,7 @@ TEST_CASE("render"){
|
||||
for ( auto& c : src ) {
|
||||
c = rand() % 255;
|
||||
}
|
||||
r.update_texture(tex, src, b2u(22, 17, 31, 44));
|
||||
|
||||
image dst;
|
||||
r.grab_texture(tex, b2u(0, 0, 128, 128), dst);
|
||||
REQUIRE(dst.format() == image_data_format::rgba8);
|
||||
|
||||
const size_t data_size = ((tex->size().x * tex->decl().bits_per_pixel()) / 8u) * tex->size().y;
|
||||
REQUIRE(data_size == dst.data().size());
|
||||
|
||||
bool equal = true;
|
||||
const size_t bpp = tex->decl().bits_per_pixel() / 8;
|
||||
for ( u32 y = 0; y < 44; ++y ) {
|
||||
const u8* dst_row = dst.data().data() + ((y + 17) * 128 + 22) * bpp;
|
||||
const u8* src_row = src.data() + (y * 31 * bpp);
|
||||
for ( u32 x = 0; x < 31 * bpp; ++x ) {
|
||||
equal &= (src_row[x] == dst_row[x]);
|
||||
}
|
||||
}
|
||||
REQUIRE(equal);
|
||||
REQUIRE_NOTHROW(r.update_texture(tex, src, b2u(22, 17, 31, 44)));
|
||||
}
|
||||
{
|
||||
texture_ptr tex = r.create_texture(v2u(128,128), pixel_declaration::pixel_type::rgba8);
|
||||
@@ -332,12 +272,7 @@ TEST_CASE("render"){
|
||||
|
||||
texture_ptr tex = r.create_texture(src.size(), pixel_declaration::pixel_type::rgba_dxt5);
|
||||
REQUIRE(tex != nullptr);
|
||||
r.update_texture(tex, src, v2u(0,0));
|
||||
|
||||
image dst;
|
||||
r.grab_texture(tex, b2u(src.size()), dst);
|
||||
REQUIRE(dst.format() == image_data_format::rgba8);
|
||||
REQUIRE(src.size() == dst.size());
|
||||
REQUIRE_NOTHROW(r.update_texture(tex, src, v2u(0,0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user