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;
163 mSize = {width, height};
166 if (bgfx::isValid(mFbh))
170 mFbh =
ctx.createFramebufferAndInitView(
171 mWinId, mViewId, width, height,
true, mDefaultClearColor.rgba());
173 assert(
ctx.isDefaultWindow(mWinId) == !bgfx::isValid(mFbh));
182 bgfx::setViewFrameBuffer(mViewId, mFbh);
183 bgfx::touch(mViewId);
186 DerivedRenderApp::CNV::draw(derived());
187 DerivedRenderApp::CNV::postDraw(derived());
190 (mReadRequest != std::nullopt && !mReadRequest->isSubmitted());
195 mCurrFrame = bgfx::frame();
197 if (mReadRequest->submit()) {
203 mCurrFrame = bgfx::frame();
206 if (mReadRequest != std::nullopt) {
208 const bool done = mReadRequest->performRead(mCurrFrame);
210 mReadRequest = std::nullopt;
216#if defined(__APPLE__)
231 CallbackReadBuffer
callback =
nullptr)
234 || mReadRequest != std::nullopt
235 || point.
x() < 0 || point.
y() < 0
236 || point.
x() >= mSize.x() || point.
y() >= mSize.y()) {
240 mReadRequest.emplace(point, mSize,
callback);
259 || mReadRequest != std::nullopt) {
265 if (width != 0 && height != 0)
266 size = {width, height};
269 CallbackReadBuffer
callback = [=](
const ReadData& data) {
271 std::holds_alternative<ReadFramebufferRequest::ByteData>(data));
272 const auto& d = std::get<ReadFramebufferRequest::ByteData>(data);
276 vcl::saveImageData(
filename, size.x(), size.y(), d.data());
278 catch (
const std::exception& e) {
279 std::cerr <<
"Error saving image: " << e.what() << std::endl;
283 mReadRequest.emplace(size,
callback, mDefaultClearColor);
289 void offscreenFrame()
291 assert(mReadRequest != std::nullopt && !mReadRequest->isSubmitted());
294 bgfx::setViewFrameBuffer(
295 mReadRequest->viewId(), mReadRequest->frameBuffer());
296 bgfx::touch(mReadRequest->viewId());
299 auto tmpId = mViewId;
300 mViewId = mReadRequest->viewId();
301 DerivedRenderApp::CNV::drawContent(derived());
305 auto* derived() {
return static_cast<DerivedRenderApp*
>(
this); }
307 const auto* derived()
const
309 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:229
bool onScreenshot(const std::string &filename, uint width=0, uint height=0)
Automatically called by the DerivedRenderApp when a drawer asks for a screenshot.
Definition canvas.h:253
static Context & instance(void *windowHandle=nullptr, void *displayHandle=nullptr)
Return the context instance.
Definition context.cpp:365