Cannot render to frame buffer
Closed this issue · 1 comments
Hi,
Thanks for this excellent library, I was using sokol_gfx
directly in a 2D engine and sokol_gp
made my life a lot easier.
However, I can't seem to be able to render to a frame buffer. My rendering starts with a start
call, which receives an optional render target:
void start(rm::RenderTarget const* target) override {
_renderTarget = target;
if (_renderTarget == nullptr) {
sgp_begin(_size.width(), _size.height());
sgp_viewport(0, 0, _size.width(), _size.height());
sgp_project(0.0f, _size.width(), 0.0f, _size.height());
sgp_set_color(0.0f, 0.0f, 0.0f, 1.0f);
sgp_clear();
sgp_reset_color();
}
else {
rm::Size<long> const& size = _renderTarget->size();
sgp_begin(size.width(), size.height());
sgp_viewport(0, 0, size.width(), size.height());
sgp_project(0, size.width(), 0.0f, size.height());
sg_pass_action action = {};
action.colors[0].action = SG_ACTION_CLEAR;
action.colors[0].value.r = 0.0f;
action.colors[0].value.g = 0.0f;
action.colors[0].value.b = 0.0f;
action.colors[0].value.a = 1.0f;
sg_begin_pass(static_cast<SokolRenderTarget const*>(_renderTarget)->_pass, &action);
}
}
After that, I can draw quads, textured or not:
void draw(rm::Quad const& quad, rm::Texture const* const texture, Post post) override {
rm::Point const& position = quad.position();
rm::Size<float> const& size = quad.size();
rm::Point const& center = quad.center();
rm::Vec2 const& scale = quad.scale();
float const angle = -quad.angle();
rm::Color const& color = quad.color();
rm::Point const screencenter(position.x() + center.x(), position.y() + center.y());
sgp_push_transform();
sgp_scale_at(scale.x(), scale.y(), screencenter.x(), screencenter.y());
sgp_rotate_at(angle, screencenter.x(), screencenter.y());
sgp_set_color(color.r(), color.g(), color.b(), color.a());
sgp_set_blend_mode(SGP_BLENDMODE_BLEND);
if (texture != nullptr) {
sgp_set_image(0, static_cast<SokolTexture const*>(texture)->_texture);
sgp_draw_textured_rect(position.x(), position.y(), size.width(), size.height());
sgp_reset_image(0);
}
else {
sgp_draw_filled_rect(position.x(), position.y(), size.width(), size.height());
}
sgp_reset_blend_mode();
sgp_reset_color();
sgp_pop_transform();
}
And then I call present to commit the draw calls:
void present() override {
if (_renderTarget == nullptr) {
sg_pass_action action = {0};
sg_begin_default_pass(&action, _size.width(), _size.height());
sgp_flush();
sgp_end();
sg_end_pass();
sg_commit();
_platform->swapBuffers();
}
else {
sgp_flush();
sgp_end();
sg_end_pass();
_renderTarget = nullptr;
}
}
When I render to the screen, I can see everything is there (it's just one textured quad), but if I render to a framebuffer, all I see when I render it to the screen is a white quad. If I set a breakpoint at draw
I can see that texture
is not null, and all the other values are good. I can also see that the framebuffer path is being taken in start
and present
.
This is how I'm creating the framebuffer:
SokolRenderTarget(long const width, long const height, Filter const filter) : rm::RenderTarget(width, height) {
{
sg_image_desc desc = {};
desc.render_target = true;
desc.width = width;
desc.height = height;
desc.pixel_format = SG_PIXELFORMAT_RGBA8;
desc.min_filter = filter == rm::Texture::Filter::Nearest ? SG_FILTER_NEAREST : SG_FILTER_LINEAR;
desc.mag_filter = desc.min_filter;
desc.wrap_u = SG_WRAP_CLAMP_TO_EDGE;
desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE;
_target = sg_make_image(&desc);
}
{
sg_desc sgdesc = sg_query_desc();
sg_image_desc desc = {};
desc.render_target = true;
desc.width = width;
desc.height = height;
desc.pixel_format = SG_PIXELFORMAT_DEPTH_STENCIL;
desc.sample_count = sgdesc.context.sample_count;
_depth = sg_make_image(&desc);
}
{
sg_pass_desc desc = {};
desc.color_attachments[0].image = _target;
desc.depth_stencil_attachment.image = _depth;
_pass = sg_make_pass(&desc);
}
}
I followed the framebuffer example to write the code, but the example is a bit contrived in that it follows a fixed path whereas I need the flexibility to draw anything, anytime to a framebuffer, but still it looks correct to me.
Any help is greatly appreciated.
Hm I've tried so many things that I can't tell why it's working now. It was my fault of course, as the framebuffer sample worked just fine.
Well, sorry for the noise, and thanks again for this great library.