23#ifndef VCL_BGFX_CANVAS_H
24#define VCL_BGFX_CANVAS_H
26#include <vclib/bgfx/context.h>
27#include <vclib/bgfx/read_framebuffer_request.h>
28#include <vclib/bgfx/system/native_window_handle.h>
29#include <vclib/io/image.h>
30#include <vclib/render/concepts/render_app.h>
31#include <vclib/render/input.h>
32#include <vclib/render/read_buffer_types.h>
33#include <vclib/base.h>
69template<
typename DerivedRenderApp>
72 using ReadFramebufferRequest = detail::ReadFramebufferRequest;
75 using FloatData = ReadBufferTypes::FloatData;
76 using ByteData = ReadBufferTypes::ByteData;
77 using ReadData = ReadBufferTypes::ReadData;
80 using CallbackReadBuffer = ReadBufferTypes::CallbackReadBuffer;
83 void* mWinId =
nullptr;
87 bgfx::ViewId mViewId = BGFX_INVALID_VIEW;
93 vcl::Color mDefaultClearColor = vcl::Color::Black;
99 std::optional<ReadFramebufferRequest> mReadRequest = std::nullopt;
106 void* displayId =
nullptr) : mWinId(winId)
110 "The DerivedRenderApp must satisfy the RenderAppConcept.");
122 if (bgfx::isValid(mFbh))
127 if (
ctx.isValidViewId(mViewId))
128 ctx.releaseViewId(mViewId);
133 bgfx::ViewId viewId()
const {
return mViewId; }
135 bgfx::FrameBufferHandle frameBuffer()
const {
return mFbh; }
137 void setDefaultClearColor(
const Color& color)
139 mDefaultClearColor = color;
175 mSize = {width, height};
178 if (bgfx::isValid(mFbh))
182 mFbh =
ctx.createFramebufferAndInitView(
183 mWinId, mViewId, width, height,
true, mDefaultClearColor.rgba());
185 assert(
ctx.isDefaultWindow(mWinId) == !bgfx::isValid(mFbh));
194 bgfx::setViewFrameBuffer(mViewId, mFbh);
195 bgfx::touch(mViewId);
198 DerivedRenderApp::CNV::draw(derived());
199 DerivedRenderApp::CNV::postDraw(derived());
202 (mReadRequest != std::nullopt && !mReadRequest->isSubmitted());
207 mCurrFrame = bgfx::frame();
209 if (mReadRequest->submit()) {
215 mCurrFrame = bgfx::frame();
218 if (mReadRequest != std::nullopt) {
220 const bool done = mReadRequest->performRead(mCurrFrame);
222 mReadRequest = std::nullopt;
228#if defined(__APPLE__)
243 CallbackReadBuffer
callback =
nullptr)
246 || mReadRequest != std::nullopt
247 || point.
x() < 0 || point.
y() < 0
248 || point.
x() >= mSize.x() || point.
y() >= mSize.y()) {
252 mReadRequest.emplace(point, mSize,
callback);
268 || mReadRequest != std::nullopt) {
276 CallbackReadBuffer
callback = [=](
const ReadData& data) {
278 std::holds_alternative<ReadFramebufferRequest::ByteData>(data));
279 const auto& d = std::get<ReadFramebufferRequest::ByteData>(data);
284 vcl::saveImageData(
filename, size.x(), size.y(), d.data());
286 catch (
const std::exception& e) {
287 std::cerr <<
"Error saving image: " << e.what() << std::endl;
291 mReadRequest.emplace(size,
callback, mDefaultClearColor);
307 CallbackReadBuffer
callback =
nullptr)
310 || mReadRequest != std::nullopt
311 || point.
x() < 0 || point.
y() < 0
312 || point.
x() >= mSize.x() || point.
y() >= mSize.y()) {
316 mReadRequest.emplace(point, mSize,
true,
callback);
322 void offscreenFrame()
324 assert(mReadRequest != std::nullopt && !mReadRequest->isSubmitted());
327 bgfx::setViewFrameBuffer(
328 mReadRequest->viewId(), mReadRequest->frameBuffer());
329 bgfx::touch(mReadRequest->viewId());
332 auto tmpId = mViewId;
333 mViewId = mReadRequest->viewId();
334 switch (mReadRequest->type()) {
335 case ReadFramebufferRequest::Type::COLOR:
336 case ReadFramebufferRequest::Type::DEPTH:
337 DerivedRenderApp::CNV::drawContent(derived());
339 case ReadFramebufferRequest::Type::ID:
340 DerivedRenderApp::CNV::drawId(derived());
342 default:
assert(
false &&
"unsupported readback type");
break;
347 auto* derived() {
return static_cast<DerivedRenderApp*
>(
this); }
349 const auto* derived()
const
351 return static_cast<const DerivedRenderApp*
>(
this);
A class representing a box in N-dimensional space.
Definition box.h:46
The Canvas class describes a canvas on which bgfx can draw.
Definition canvas.h:71
bool screenshot(const std::string &filename, uint multiplier=1)
Request a screenshot of the canvas. The screenshot will be saved asynchronously.
Definition canvas.h:153
void onInit()
Automatically called by the DerivedRenderApp when the window initializes. Initialization is requires ...
Definition canvas.h:165
bool onReadDepth(const Point2i &point, CallbackReadBuffer callback=nullptr)
Automatically called by the DerivedRenderApp when a drawer asks to read the depth buffer at a specifi...
Definition canvas.h:241
void onPaint()
Automatically called by the DerivedRenderApp when the window asks to repaint.
Definition canvas.h:192
bool onScreenshot(const std::string &filename, uint multiplier=1)
Automatically called by the DerivedRenderApp when a drawer asks for a screenshot. Also called by the ...
Definition canvas.h:265
void onResize(uint width, uint height)
Automatically called by the DerivedRenderApp when the window is resized.
Definition canvas.h:173
bool onReadId(const Point2i &point, CallbackReadBuffer callback=nullptr)
Automatically called by the DerivedRenderApp when a drawer asks to read the ID at a specific point.
Definition canvas.h:305
The Color class represents a 32 bit color.
Definition color.h:48
static Context & instance(void *windowHandle=nullptr, void *displayHandle=nullptr)
Return the context instance.
Definition context.cpp:371
The Point class represents an N-dimensional point containing N scalar values.
Definition point.h:55
ScalarType & x()
Returns a reference to the x-component of the Point object.
Definition point.h:128
ScalarType & y()
Returns a reference to the y-component of the Point object.
Definition point.h:150
Definition render_app.h:31