Visual Computing Library  devel
Loading...
Searching...
No Matches
canvas.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_OPENGL2_CANVAS_H
24#define VCL_OPENGL2_CANVAS_H
25
26#include <vclib/io/image.h>
27#include <vclib/render/concepts/render_app.h>
28#include <vclib/render/read_buffer_types.h>
29#include <vclib/space/core/color.h>
30#include <vclib/space/core/point.h>
31#include <vclib/base.h>
32
33#ifdef __APPLE__
34#include <OpenGL/gl.h>
35#else
36#ifdef _WIN32
37#include <windows.h>
38#endif
39#include <GL/gl.h>
40#endif
41
42namespace vcl {
43
72template<typename DerivedRenderApp>
74{
75protected:
76 using FloatData = ReadBufferTypes::FloatData;
77 using ByteData = ReadBufferTypes::ByteData;
78 using ReadData = ReadBufferTypes::ReadData;
79
80public:
81 using CallbackReadBuffer = ReadBufferTypes::CallbackReadBuffer;
82
83private:
84 void* mWinId = nullptr;
85
86 Point2<uint> mSize = {0, 0};
87
88 vcl::Color mDefaultClearColor = vcl::Color::Black;
89
90 CallbackReadBuffer mReadBufferCallback = nullptr;
91 Point2i mReadDepthPoint = Point2i(-1, -1);
92
93public:
95 void* winId,
96 uint width,
97 uint height,
98 void* displayId = nullptr) : mWinId(winId), mSize(width, height)
99 {
100 static_assert(
102 "The DerivedRenderApp must satisfy the RenderAppConcept.");
103 }
104
105 ~CanvasOpenGL2() {}
106
107 Point2<uint> size() const { return mSize; }
108
109 uint viewId() const { return 0; }
110
111 void setDefaultClearColor(const Color& color)
112 {
113 mDefaultClearColor = color;
115 mDefaultClearColor.redF(),
116 mDefaultClearColor.greenF(),
117 mDefaultClearColor.blueF(),
118 mDefaultClearColor.alphaF());
119 }
120
128 bool screenshot(const std::string& filename, uint multiplier = 1)
129 {
131 }
132
140 void onInit()
141 {
142 glViewport(0, 0, mSize.x(), mSize.y());
144 mDefaultClearColor.redF(),
145 mDefaultClearColor.greenF(),
146 mDefaultClearColor.blueF(),
147 mDefaultClearColor.alphaF());
148 }
149
156 void onResize(uint width, uint height)
157 {
158 mSize = {width, height};
159 glViewport(0, 0, width, height);
160 }
161
166 void onPaint()
167 {
169
170 // if depth requested, read it
171 if (mReadBufferCallback) {
172 DerivedRenderApp::CNV::drawContent(derived());
173 readDepthData();
175 }
176 DerivedRenderApp::CNV::draw(derived());
177 DerivedRenderApp::CNV::postDraw(derived());
178 }
179
189 const Point2i& point,
190 CallbackReadBuffer callback = nullptr)
191 {
192 if (point.x() < 0 || point.y() < 0 || // point out of bounds
193 point.x() >= mSize.x() || point.y() >= mSize.y()) {
194 return false;
195 }
196
197 mReadDepthPoint = point;
198 mReadBufferCallback = callback;
199 return true;
200 }
201
211 bool onScreenshot(const std::string& filename, uint multiplier = 1)
212 {
213 (void) multiplier; // not used
214
215 std::vector<std::uint8_t> buffer(mSize.x() * mSize.y() * 4);
216 // read pixels
218 0,
219 0,
220 GLsizei(mSize.x()),
221 GLsizei(mSize.y()),
222 GL_RGBA,
224 buffer.data());
225
226 // write image using stb
227 bool ret = true;
229 try {
230 saveImageData(filename, mSize.x(), mSize.y(), buffer.data());
231 }
232 catch (const std::exception& e) {
233 ret = false;
234 }
236
237 return ret;
238 }
239
251 const Point2i& point,
252 CallbackReadBuffer callback = nullptr)
253 {
254 return false;
255 }
256
257private:
258 void readDepthData()
259 {
260 // get depth range
261 std::array<GLfloat, 2> depthRange = {0, 0};
262 glGetFloatv(GL_DEPTH_RANGE, depthRange.data());
263
264 // get viewport heigth only
265 GLint viewport[4];
266 glGetIntegerv(GL_VIEWPORT, viewport);
267
268 // read depth
269 GLfloat depth = depthRange[1];
270 glReadPixels(
271 GLint(mReadDepthPoint.x()),
272 GLint(viewport[3] - mReadDepthPoint.y() - 1),
273 1,
274 1,
275 GL_DEPTH_COMPONENT,
276 GL_FLOAT,
277 &depth);
278
279 // normalize depth into [0,1] interval
280 depth = (depth - depthRange[0]) / (depthRange[1] - depthRange[0]);
281
282 ReadData rd = FloatData({depth});
283
284 // callback
285 mReadBufferCallback(rd);
286
287 // cleanup
288 mReadDepthPoint = {-1, -1};
289 mReadBufferCallback = nullptr;
290 }
291
292 auto* derived() { return static_cast<DerivedRenderApp*>(this); }
293
294 const auto* derived() const
295 {
296 return static_cast<const DerivedRenderApp*>(this);
297 }
298};
299
300} // namespace vcl
301
302#endif // VCL_OPENGL2_CANVAS_H
A class representing a box in N-dimensional space.
Definition box.h:46
The Canvas class describes a canvas on which opengl2 can draw.
Definition canvas.h:74
void onInit()
Automatically called by the DerivedRenderApp when the window initializes. Initialization is requires ...
Definition canvas.h:140
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:250
void onResize(uint width, uint height)
Automatically called by the DerivedRenderApp when the window is resized.
Definition canvas.h:156
bool screenshot(const std::string &filename, uint multiplier=1)
Request a screenshot of the canvas. The screenshot will be saved asynchronously.
Definition canvas.h:128
bool onScreenshot(const std::string &filename, uint multiplier=1)
Automatically called by the DerivedRenderApp when a drawer asks for a screenshot.
Definition canvas.h:211
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:188
void onPaint()
Automatically called by the DerivedRenderApp when the window asks to repaint.
Definition canvas.h:166
The Color class represents a 32 bit color.
Definition color.h:48
float greenF() const
Returns the float green component of this color [0-1].
Definition color.h:210
float blueF() const
Returns the float blue component of this color [0-1].
Definition color.h:216
float alphaF() const
Returns the float alpha component of this color [0-1].
Definition color.h:222
float redF() const
Returns the float red component of this color [0-1].
Definition color.h:204
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
Point2< int > Point2i
A convenience alias for a 2-dimensional Point with integer components.
Definition point.h:706