46 using ReadFramebufferRequest = detail::ReadFramebufferRequest;
49 using FloatData = ReadBufferTypes::FloatData;
50 using ByteData = ReadBufferTypes::ByteData;
51 using ReadData = ReadBufferTypes::ReadData;
54 using CallbackReadBuffer = ReadBufferTypes::CallbackReadBuffer;
57 void* mWinId =
nullptr;
61 bgfx::ViewId mViewId = BGFX_INVALID_VIEW;
67 vcl::Color mDefaultClearColor = vcl::Color::Black;
73 std::optional<ReadFramebufferRequest> mReadRequest = std::nullopt;
80 void* displayId =
nullptr) : mWinId(winId)
84 "The DerivedRenderApp must satisfy the RenderAppConcept.");
96 if (bgfx::isValid(mFbh))
101 if (
ctx.isValidViewId(mViewId))
102 ctx.releaseViewId(mViewId);
107 bgfx::ViewId viewId()
const {
return mViewId; }
109 bgfx::FrameBufferHandle frameBuffer()
const {
return mFbh; }
111 void setDefaultClearColor(
const Color& color)
113 mDefaultClearColor = color;
149 mSize = {width, height};
152 if (bgfx::isValid(mFbh))
156 mFbh =
ctx.createFramebufferAndInitView(
157 mWinId, mViewId, width, height,
true, mDefaultClearColor.rgba());
159 assert(
ctx.isDefaultWindow(mWinId) == !bgfx::isValid(mFbh));
168 bgfx::setViewFrameBuffer(mViewId, mFbh);
169 bgfx::touch(mViewId);
172 DerivedRenderApp::CNV::draw(derived());
173 DerivedRenderApp::CNV::postDraw(derived());
176 (mReadRequest != std::nullopt && !mReadRequest->isSubmitted());
181 mCurrFrame = bgfx::frame();
183 if (mReadRequest->submit()) {
189 mCurrFrame = bgfx::frame();
192 if (mReadRequest != std::nullopt) {
194 const bool done = mReadRequest->performRead(mCurrFrame);
196 mReadRequest = std::nullopt;
202#if defined(__APPLE__)
217 CallbackReadBuffer
callback =
nullptr)
220 || mReadRequest != std::nullopt
221 || point.
x() < 0 || point.
y() < 0
222 || point.
x() >= mSize.x() || point.
y() >= mSize.y()) {
226 mReadRequest.emplace(point, mSize,
callback);
242 || mReadRequest != std::nullopt) {
250 CallbackReadBuffer
callback = [=](
const ReadData& data) {
252 std::holds_alternative<ReadFramebufferRequest::ByteData>(data));
253 const auto& d = std::get<ReadFramebufferRequest::ByteData>(data);
258 vcl::saveImageData(
filename, size.x(), size.y(), d.data());
260 catch (
const std::exception& e) {
261 std::cerr <<
"Error saving image: " << e.what() << std::endl;
265 mReadRequest.emplace(size,
callback, mDefaultClearColor);
281 CallbackReadBuffer
callback =
nullptr)
284 || mReadRequest != std::nullopt
285 || point.
x() < 0 || point.
y() < 0
286 || point.
x() >= mSize.x() || point.
y() >= mSize.y()) {
290 mReadRequest.emplace(point, mSize,
true,
callback);
296 void offscreenFrame()
298 assert(mReadRequest != std::nullopt && !mReadRequest->isSubmitted());
301 bgfx::setViewFrameBuffer(
302 mReadRequest->viewId(), mReadRequest->frameBuffer());
303 bgfx::touch(mReadRequest->viewId());
306 auto tmpId = mViewId;
307 mViewId = mReadRequest->viewId();
308 switch (mReadRequest->type()) {
309 case ReadFramebufferRequest::Type::COLOR:
310 case ReadFramebufferRequest::Type::DEPTH:
311 DerivedRenderApp::CNV::drawContent(derived());
313 case ReadFramebufferRequest::Type::ID:
314 DerivedRenderApp::CNV::drawId(derived());
316 default:
assert(
false &&
"unsupported readback type");
break;
321 auto* derived() {
return static_cast<DerivedRenderApp*
>(
this); }
323 const auto* derived()
const
325 return static_cast<const DerivedRenderApp*
>(
this);
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:215
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:239
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:279
static Context & instance(void *windowHandle=nullptr, void *displayHandle=nullptr)
Return the context instance.
Definition context.cpp:371