Visual Computing Library
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/types.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 void onInit()
129 {
130 glViewport(0, 0, mSize.x(), mSize.y());
132 mDefaultClearColor.redF(),
133 mDefaultClearColor.greenF(),
134 mDefaultClearColor.blueF(),
135 mDefaultClearColor.alphaF());
136 }
137
144 void onResize(uint width, uint height)
145 {
146 mSize = {width, height};
147 glViewport(0, 0, width, height);
148 }
149
154 void onPaint()
155 {
157
158 // if depth requested, read it
159 if (mReadBufferCallback) {
160 DerivedRenderApp::CNV::drawContent(derived());
161 readDepthData();
163 }
164 DerivedRenderApp::CNV::draw(derived());
165 DerivedRenderApp::CNV::postDraw(derived());
166 }
167
177 const Point2i& point,
178 CallbackReadBuffer callback = nullptr)
179 {
180 if (point.x() < 0 || point.y() < 0 || // point out of bounds
181 point.x() >= mSize.x() || point.y() >= mSize.y()) {
182 return false;
183 }
184
185 mReadDepthPoint = point;
186 mReadBufferCallback = callback;
187 return true;
188 }
189
200 const std::string& filename,
201 uint width = 0,
202 uint height = 0)
203 {
204 (void) width;
205 (void) height;
206
207 std::vector<std::uint8_t> buffer(mSize.x() * mSize.y() * 4);
208 // read pixels
210 0,
211 0,
212 GLsizei(mSize.x()),
213 GLsizei(mSize.y()),
214 GL_RGBA,
216 buffer.data());
217
218 // write image using stb
219 bool ret = true;
221 try {
222 saveImageData(filename, mSize.x(), mSize.y(), buffer.data());
223 }
224 catch (const std::exception& e) {
225 ret = false;
226 }
228
229 return ret;
230 }
231
232private:
233 void readDepthData()
234 {
235 // get depth range
236 std::array<GLfloat, 2> depthRange = {0, 0};
237 glGetFloatv(GL_DEPTH_RANGE, depthRange.data());
238
239 // get viewport heigth only
240 GLint viewport[4];
241 glGetIntegerv(GL_VIEWPORT, viewport);
242
243 // read depth
244 GLfloat depth = depthRange[1];
245 glReadPixels(
246 GLint(mReadDepthPoint.x()),
247 GLint(viewport[3] - mReadDepthPoint.y() - 1),
248 1,
249 1,
250 GL_DEPTH_COMPONENT,
251 GL_FLOAT,
252 &depth);
253
254 // normalize depth into [0,1] interval
255 depth = (depth - depthRange[0]) / (depthRange[1] - depthRange[0]);
256
257 ReadData rd = FloatData({depth});
258
259 // callback
260 mReadBufferCallback(rd);
261
262 // cleanup
263 mReadDepthPoint = {-1, -1};
264 mReadBufferCallback = nullptr;
265 }
266
267 auto* derived() { return static_cast<DerivedRenderApp*>(this); }
268
269 const auto* derived() const
270 {
271 return static_cast<const DerivedRenderApp*>(this);
272 }
273};
274
275} // namespace vcl
276
277#endif // VCL_OPENGL2_CANVAS_H
The Canvas class describes a canvas on which opengl2 can draw.
Definition canvas.h:74
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:199
void onInit()
Automatically called by the DerivedRenderApp when the window initializes. Initialization is requires ...
Definition canvas.h:128
void onResize(uint width, uint height)
Automatically called by the DerivedRenderApp when the window is resized.
Definition canvas.h:144
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:176
void onPaint()
Automatically called by the DerivedRenderApp when the window asks to repaint.
Definition canvas.h:154
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:207
float blueF() const
Returns the float blue component of this color [0-1].
Definition color.h:213
float alphaF() const
Returns the float alpha component of this color [0-1].
Definition color.h:219
float redF() const
Returns the float red component of this color [0-1].
Definition color.h:201
The Point class represents an N-dimensional point containing N scalar values.
Definition point.h:58
ScalarType & x()
Returns a reference to the x-component of the Point object.
Definition point.h:131
ScalarType & y()
Returns a reference to the y-component of the Point object.
Definition point.h:153
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
Definition render_app.h:31
Point2< int > Point2i
A convenience alias for a 2-dimensional Point with integer components.
Definition point.h:731