31#include <visp3/core/vpConfig.h>
33#if defined(VISP_HAVE_PANDA3D)
35#include <visp3/ar/vpPanda3DGeometryRenderer.h>
36#include "windowFramework.h"
37#include "graphicsOutput.h"
38#include "graphicsEngine.h"
39#include "graphicsBuffer.h"
43const std::string SHADER_VERT_NORMAL_AND_DEPTH_CAMERA =
45"in vec3 p3d_Normal;\n"
46"in vec4 p3d_Vertex;\n"
47"uniform mat3 p3d_NormalMatrix;\n"
48"uniform mat4 p3d_ModelViewMatrix;\n"
49"uniform mat4 p3d_ModelViewProjectionMatrix;\n"
51"out float distToCamera;\n"
54" gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
55" oNormal = p3d_NormalMatrix * normalize(p3d_Normal);\n"
56" vec4 cs_position = p3d_ModelViewMatrix * p3d_Vertex;\n"
57" distToCamera = -cs_position.z;\n"
60const std::string SHADER_VERT_NORMAL_AND_DEPTH_OBJECT =
62"in vec3 p3d_Normal;\n"
63"in vec4 p3d_Vertex;\n"
64"uniform mat4 p3d_ModelViewMatrix;\n"
65"uniform mat4 p3d_ModelViewProjectionMatrix;\n"
67"out float distToCamera;\n"
70" gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
71" oNormal = vec3(p3d_Normal.x, -p3d_Normal.z, p3d_Normal.y);\n"
72" vec4 cs_position = p3d_ModelViewMatrix * p3d_Vertex;\n"
73" distToCamera = -cs_position.z;\n"
76const std::string SHADER_FRAG_NORMAL_AND_DEPTH =
79"in float distToCamera;\n"
80"out vec4 p3d_FragData;\n"
83" p3d_FragData.bgra = vec4(normalize(oNormal), distToCamera);\n"
87const std::string SHADER_FRAG_NORMAL_AND_DEPTH_FAST =
90"in float distToCamera;\n"
91"out vec4 p3d_FragData;\n"
92"uniform float nearV;\n"
93"uniform float farV;\n"
96" //float depthV = distToCamera <= nearV ? 0.0 : (distToCamera - nearV) / (farV - nearV);\n"
97" float depthV = distToCamera / farV;\n"
98" vec3 n = normalize(oNormal);\n"
99" n = (n + 1.0) / 2.0;\n"
100" p3d_FragData.bgra = vec4(n, depthV);\n"
108 return "normals-world";
110 return "normals-camera";
132 shader = Shader::make(Shader::ShaderLanguage::SL_GLSL,
133 SHADER_VERT_NORMAL_AND_DEPTH_OBJECT,
134 m_fast ? SHADER_FRAG_NORMAL_AND_DEPTH_FAST : SHADER_FRAG_NORMAL_AND_DEPTH);
137 shader = Shader::make(Shader::ShaderLanguage::SL_GLSL,
138 SHADER_VERT_NORMAL_AND_DEPTH_CAMERA,
139 m_fast ? SHADER_FRAG_NORMAL_AND_DEPTH_FAST : SHADER_FRAG_NORMAL_AND_DEPTH);
149 FrameBufferProperties fbp;
151 fbp.set_rgb_color(
true);
152 fbp.set_float_depth(
false);
153 fbp.set_float_color(
true);
154 fbp.set_depth_bits(16);
155 fbp.set_rgba_bits(32, 32, 32, 32);
158 fbp.set_rgb_color(
true);
159 fbp.set_float_depth(
false);
160 fbp.set_float_color(
false);
161 fbp.set_depth_bits(16);
162 fbp.set_rgba_bits(8, 8, 8, 8);
165 WindowProperties win_prop;
168 int flags = GraphicsPipe::BF_refuse_window | GraphicsPipe::BF_resizeable;
169 GraphicsOutput *windowOutput =
m_window->get_graphics_output();
170 GraphicsEngine *engine = windowOutput->get_engine();
171 GraphicsPipe *pipe = windowOutput->get_pipe();
174 m_normalDepthBuffer = engine->make_output(pipe, renderTypeToName(m_renderType) + std::to_string(
id),
m_renderOrder, fbp, win_prop, flags,
175 windowOutput->get_gsg(), windowOutput);
176 m_normalDepthTexture =
new Texture(
"geometry texture " + std::to_string(
id));
178 if (m_normalDepthBuffer ==
nullptr) {
184 m_buffers.push_back(m_normalDepthBuffer);
185 m_normalDepthBuffer->set_inverted(windowOutput->get_gsg()->get_copy_texture_inverted());
188 m_normalDepthTexture->set_format(Texture::F_rgba32);
191 m_normalDepthTexture->set_component_type(Texture::T_unsigned_byte);
192 m_normalDepthTexture->set_format(Texture::F_rgba);
194 m_normalDepthBuffer->add_render_texture(m_normalDepthTexture, GraphicsOutput::RenderTextureMode::RTM_copy_texture, GraphicsOutput::RenderTexturePlane::RTP_color);
195 m_normalDepthBuffer->set_clear_color(LColor(0.f));
196 m_normalDepthBuffer->set_clear_color_active(
true);
198 DisplayRegion *region = m_normalDepthBuffer->make_display_region();
199 if (region ==
nullptr) {
203 region->set_clear_color(LColor(0.f));
208 normals.
resize(m_normalDepthTexture->get_y_size(), m_normalDepthTexture->get_x_size());
209 depth.resize(m_normalDepthTexture->get_y_size(), m_normalDepthTexture->get_x_size());
211 const unsigned numComponents = m_normalDepthTexture->get_num_components();
212 if (numComponents != 4) {
216 int rowIncrement = normals.
getWidth() * 4;
220 T *data = (T *)(&(m_normalDepthTexture->get_ram_image().front()));
221 data = data + rowIncrement * (normals.
getHeight() - 1);
222#if defined(VISP_HAVE_OPENMP)
223#pragma omp parallel for
225 for (
int i = 0; i < static_cast<int>(normals.
getHeight()); ++i) {
226 const T *
const rowData = data - i * rowIncrement;
228 vpRGBf *normalRow = normals[i];
229 float *depthRow = depth[i];
230 for (
unsigned int j = 0; j < normals.
getWidth(); ++j) {
231 normalRow[j].
R = (rowData[j * 4]);
232 normalRow[j].
G = (rowData[j * 4 + 1]);
233 normalRow[j].
B = (rowData[j * 4 + 2]);
234 depthRow[j] = (rowData[j * 4 + 3]);
241 Texture::ComponentType expectedComponent = Texture::T_unsigned_byte;
242 float maxValue =
static_cast<float>(std::numeric_limits<T>::max());
243 const T *data = (T *)(&(m_normalDepthTexture->get_ram_image().front()));
247 if (m_normalDepthTexture->get_component_type() != expectedComponent) {
250#if defined(VISP_HAVE_OPENMP)
251#pragma omp parallel for
253 for (
int i = 0; i < static_cast<int>(normals.
getHeight()); ++i) {
254 const T *
const rowData = data - i * rowIncrement;
255 vpRGBf *normalRow = normals[i];
256 float *depthRow = depth[i];
257 std::array<float, 3> v;
258 for (
int j = 0; j < static_cast<int>(normals.
getWidth()); ++j) {
260 v[0] = (
static_cast<float>(rowData[j_4]) / maxValue) * 2.f - 1.f;
261 v[1] = (
static_cast<float>(rowData[j_4 + 1]) / maxValue) * 2.f - 1.f;
262 v[2] = (
static_cast<float>(rowData[j_4 + 2]) / maxValue) * 2.f - 1.f;
265 normalRow[j].
R = v[0];
266 normalRow[j].
G = v[1];
267 normalRow[j].
B = v[2];
268 depthRow[j] = (
static_cast<float>(rowData[j_4 + 3]) / maxValue) * farV;
281 const unsigned top =
static_cast<unsigned int>(std::max(0.0, bb.getTop()));
282 const unsigned left =
static_cast<unsigned int>(std::max(0.0, bb.getLeft()));
283 const unsigned numComponents = m_normalDepthTexture->get_num_components();
287 int image_width =
static_cast<int>(std::min(
m_renderParameters.getImageWidth(), w - left));
291 const float *data = (
float *)(&(m_normalDepthTexture->get_ram_image().front()));
294 if (numComponents != 4) {
297 if (m_normalDepthTexture->get_component_type() != Texture::T_float) {
300#if defined(VISP_HAVE_OPENMP)
301#pragma omp parallel for
303 for (
int i = 0; i < image_height; ++i) {
304 const float *
const rowData = data - i * rowIncrement;
305 vpRGBf *normalRow = normals[top + i];
306 float *depthRow = depth[top + i];
307 for (
int j = 0; j < image_width; ++j) {
308 int left_j = left + j;
310 normalRow[left_j].
R = (rowData[j_4]);
311 normalRow[left_j].
G = (rowData[j_4 + 1]);
312 normalRow[left_j].
B = (rowData[j_4 + 2]);
313 depthRow[left_j] = (rowData[j_4 + 3]);
320 Texture::ComponentType expectedComponent = Texture::T_unsigned_byte;
321 float maxValue =
static_cast<float>(std::numeric_limits<T>::max());
322 const T *data = (T *)(&(m_normalDepthTexture->get_ram_image().front()));
326 if (numComponents != 4) {
329 if (m_normalDepthTexture->get_component_type() != expectedComponent) {
333 for (
int i = 0; i < image_height; ++i) {
334 const T *
const rowData = data - i * rowIncrement;
335 vpRGBf *normalRow = normals[top + i];
336 float *depthRow = depth[top + i];
337 std::array<float, 3> v;
338 for (
int j = 0; j < image_width; ++j) {
339 int left_j = left + j;
341 v[0] = (
static_cast<float>(rowData[j_4]) / maxValue) * 2.f - 1.f;
342 v[1] = (
static_cast<float>(rowData[j_4 + 1]) / maxValue) * 2.f - 1.f;
343 v[2] = (
static_cast<float>(rowData[j_4 + 2]) / maxValue) * 2.f - 1.f;
345 normalRow[left_j].
R = v[0];
346 normalRow[left_j].
G = v[1];
347 normalRow[left_j].
B = v[2];
348 depthRow[left_j] = (
static_cast<float>(rowData[j_4 + 3]) / maxValue) * farV;
358 normals.
resize(m_normalDepthTexture->get_y_size(), m_normalDepthTexture->get_x_size());
359 int rowIncrement = normals.
getWidth() * 4;
361 if (m_normalDepthTexture->get_component_type() != Texture::T_float) {
365 float *data = (
float *)(&(m_normalDepthTexture->get_ram_image().front()));
366 data = data + rowIncrement * (normals.
getHeight() - 1);
367 for (
unsigned int i = 0; i < normals.
getHeight(); ++i) {
368 const float *
const rowData = data - i * rowIncrement;
369 vpRGBf *normalRow = normals[i];
370 for (
unsigned int j = 0; j < normals.
getWidth(); ++j) {
371 normalRow[j].
R = (rowData[j * 4]);
372 normalRow[j].
G = (rowData[j * 4 + 1]);
373 normalRow[j].
B = (rowData[j * 4 + 2]);
379 Texture::ComponentType expectedComponent = Texture::T_unsigned_byte;
380 float maxValue =
static_cast<float>(std::numeric_limits<T>::max());
381 const T *data = (T *)(&(m_normalDepthTexture->get_ram_image().front()));
385 if (m_normalDepthTexture->get_component_type() != expectedComponent) {
389 for (
unsigned int i = 0; i < normals.
getHeight(); ++i) {
390 const T *
const rowData = data - i * rowIncrement;
391 vpRGBf *normalRow = normals[i];
392 std::array<float, 3> v;
393 for (
int j = 0; j < static_cast<int>(normals.
getWidth()); ++j) {
395 v[0] = (
static_cast<float>(rowData[j_4]) / maxValue) * 2.f - 1.f;
396 v[1] = (
static_cast<float>(rowData[j_4 + 1]) / maxValue) * 2.f - 1.f;
397 v[2] = (
static_cast<float>(rowData[j_4 + 2]) / maxValue) * 2.f - 1.f;
398 normalRow[j].
R = v[0];
399 normalRow[j].
G = v[1];
400 normalRow[j].
B = v[2];
409 depth.resize(m_normalDepthTexture->get_y_size(), m_normalDepthTexture->get_x_size());
410 int rowIncrement = depth.getWidth() * 4;
413 if (m_normalDepthTexture->get_component_type() != Texture::T_float) {
417 float *data = (
float *)(&(m_normalDepthTexture->get_ram_image().front()));
418 data = data + rowIncrement * (depth.getHeight() - 1);
420 for (
unsigned int i = 0; i < depth.getHeight(); ++i) {
421 const float *
const rowData = data - i * rowIncrement;
422 float *depthRow = depth[i];
423 for (
unsigned int j = 0; j < depth.getWidth(); ++j) {
424 depthRow[j] = (rowData[j * 4 + 3]);
432 Texture::ComponentType expectedComponent = Texture::T_unsigned_byte;
433 float maxValue =
static_cast<float>(std::numeric_limits<T>::max());
434 const T *data = (T *)(&(m_normalDepthTexture->get_ram_image().front()));
438 if (m_normalDepthTexture->get_component_type() != expectedComponent) {
442 for (
unsigned int i = 0; i < depth.getHeight(); ++i) {
443 const T *
const rowData = data - i * rowIncrement;
444 float *depthRow = depth[i];
446 for (
int j = 0; j < static_cast<int>(depth.getWidth()); ++j) {
448 depthRow[j] = (
static_cast<float>(rowData[j_4 + 3]) / maxValue) * farV;
456#elif !defined(VISP_BUILD_SHARED_LIBS)
458void dummy_vpPanda3DGeometryRenderer() { }
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
@ dimensionError
Bad dimension.
Definition of the vpImage class member functions.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getHeight() const
vpPanda3DBaseRenderer(const std::string &rendererName)
NodePath m_renderRoot
Rendering parameters.
std::string m_name
Inverse of VISP_T_PANDA.
std::vector< PointerTo< GraphicsOutput > > m_buffers
NodePath of the camera.
PointerTo< WindowFramework > m_window
Rendering priority for this renderer and its buffers. A lower value will be rendered first....
int m_renderOrder
name of the renderer
vpPanda3DRenderParameters m_renderParameters
Pointer to owning window, which can create buffers etc. It is not necessarily visible.
void getRender(vpImage< vpRGBf > &colorData, vpImage< float > &depth) const
Get render results into ViSP readable structures.
void beforeFrameRendered() VP_OVERRIDE
vpPanda3DGeometryRenderer(vpRenderType renderType, bool fast=true)
void setupScene() VP_OVERRIDE
Initialize the scene for this specific renderer.
void setupRenderTarget() VP_OVERRIDE
Initialize buffers and other objects that are required to save the render.
@ CAMERA_NORMALS
Surface normals in the object frame.
Defines a rectangle in the plane.