Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpPanda3DPostProcessFilter.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 */
30
31#include <visp3/ar/vpPanda3DPostProcessFilter.h>
32
33#if defined(VISP_HAVE_PANDA3D)
34
35#include "lightRampAttrib.h"
36#include "graphicsOutput.h"
37#include "windowFramework.h"
38#include "graphicsEngine.h"
39
42"#version 330\n"
43"in vec4 p3d_Vertex;\n"
44"uniform mat4 p3d_ModelViewProjectionMatrix;\n"
45"in vec2 p3d_MultiTexCoord0;\n"
46"out vec2 texcoords;\n"
47
48"void main()\n"
49"{\n"
50" gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
51" texcoords = p3d_MultiTexCoord0;\n"
52"}\n";
53
55{
56 CardMaker cm("cm");
57 cm.set_frame_fullscreen_quad();
58 m_renderRoot = NodePath(cm.generate()); // Render root is a 2D rectangle
59 m_renderRoot.set_depth_test(false);
60 m_renderRoot.set_depth_write(false);
61 GraphicsOutput *buffer = m_inputRenderer->getMainOutputBuffer();
62 if (buffer == nullptr) {
64 "Cannot add a postprocess filter to a renderer that does not define getMainOutputBuffer()");
65 }
66 m_shader = Shader::make(Shader::ShaderLanguage::SL_GLSL,
69 m_renderRoot.set_shader(m_shader);
70 m_renderRoot.set_shader_input("dp", LVector2f(1.0 / buffer->get_texture()->get_x_size(), 1.0 / buffer->get_texture()->get_y_size()));
71 m_renderRoot.set_texture(buffer->get_texture());
72 m_renderRoot.set_attrib(LightRampAttrib::make_identity());
73}
74
76{
77 m_cameraPath = m_window->make_camera();
78 m_camera = (Camera *)m_cameraPath.node();
79 PT(OrthographicLens) lens = new OrthographicLens();
80 lens->set_film_size(2, 2);
81 lens->set_film_offset(0, 0);
82 lens->set_near_far(-1000, 1000);
83 m_camera->set_lens(lens);
84 m_cameraPath = m_renderRoot.attach_new_node(m_camera);
85 m_camera->set_scene(m_renderRoot);
86}
87
88PointerTo<Texture> vpPanda3DPostProcessFilter::setupTexture(const FrameBufferProperties &fbp) const
89{
90 PointerTo<Texture> tex = new Texture();
91 fbp.setup_color_texture(tex);
92 return tex;
93}
94
96{
97
98 if (m_window == nullptr) {
99 throw vpException(vpException::fatalError, "Cannot setup render target when window is null");
100 }
101 FrameBufferProperties fbp = getBufferProperties();
102 WindowProperties win_prop;
103 win_prop.set_size(m_renderParameters.getImageWidth(), m_renderParameters.getImageHeight());
104
105 // Don't open a window - force it to be an offscreen buffer.
106 int flags = GraphicsPipe::BF_refuse_window | GraphicsPipe::BF_resizeable;
107 GraphicsOutput *windowOutput = m_window->get_graphics_output();
108 GraphicsEngine *engine = windowOutput->get_engine();
109 GraphicsStateGuardian *gsg = windowOutput->get_gsg();
110 GraphicsPipe *pipe = windowOutput->get_pipe();
111 static int id = 0;
112 m_buffer = engine->make_output(pipe, m_name + std::to_string(id), m_renderOrder,
113 fbp, win_prop, flags,
114 gsg, windowOutput);
115
116 ++id;
117 if (m_buffer == nullptr) {
118 throw vpException(vpException::fatalError, "Could not create buffer");
119 }
120 m_buffers.push_back(m_buffer);
121 //m_buffer->set_inverted(true);
122 m_texture = setupTexture(fbp);
123
124
125 m_buffer->add_render_texture(m_texture, m_isOutput ? GraphicsOutput::RenderTextureMode::RTM_copy_texture : GraphicsOutput::RenderTextureMode::RTM_bind_or_copy);
126 m_buffer->set_clear_color(LColor(0.f));
127 m_buffer->set_clear_color_active(true);
128 DisplayRegion *region = m_buffer->make_display_region();
129 if (region == nullptr) {
130 throw vpException(vpException::fatalError, "Could not create display region");
131 }
132 region->set_camera(m_cameraPath);
133 region->set_clear_color(LColor(0.f));
134}
135
137{
138 unsigned int previousH = m_renderParameters.getImageHeight(), previousW = m_renderParameters.getImageWidth();
139 bool resize = previousH != params.getImageHeight() || previousW != params.getImageWidth();
140
141 m_renderParameters = params;
142 if (m_window != nullptr) {
143 GraphicsOutput *buffer = m_inputRenderer->getMainOutputBuffer();
144 m_renderRoot.set_shader_input("dp", LVector2f(1.0 / buffer->get_texture()->get_x_size(), 1.0 / buffer->get_texture()->get_y_size()));
145 }
146 if (resize) {
147 for (GraphicsOutput *buffer: m_buffers) {
148 //buffer->get_type().is_derived_from()
149 GraphicsBuffer *buf = dynamic_cast<GraphicsBuffer *>(buffer);
150 if (buf == nullptr) {
151 throw vpException(vpException::fatalError, "Panda3D: could not cast to GraphicsBuffer when rendering.");
152 }
153 else {
154 buf->set_size(m_renderParameters.getImageWidth(), m_renderParameters.getImageHeight());
155 }
156 }
157 }
158}
159
161{
162 if (!m_isOutput) {
163 throw vpException(vpException::fatalError, "Tried to fetch output of a postprocessing filter that was configured as an intermediate output");
164 }
165
166 I.resize(m_renderParameters.getImageHeight(), m_renderParameters.getImageWidth());
167 const unsigned numComponents = m_texture->get_num_components();
168 int rowIncrement = I.getWidth() * numComponents; // we ask for only 8 bits image, but we may get an rgb image
169 unsigned char *data = (unsigned char *)(&(m_texture->get_ram_image().front()));
170 // Panda3D stores data upside down
171 data += rowIncrement * (I.getHeight() - 1);
172 rowIncrement = -rowIncrement;
173
174 for (unsigned int i = 0; i < I.getHeight(); ++i) {
175 unsigned char *colorRow = I[i];
176 for (unsigned int j = 0; j < I.getWidth(); ++j) {
177 colorRow[j] = data[j * numComponents];
178 }
179 data += rowIncrement;
180 }
181}
182
184{
185 if (!m_isOutput) {
186 throw vpException(vpException::fatalError, "Tried to fetch output of a postprocessing filter that was configured as an intermediate output");
187 }
188
189 I.resize(m_renderParameters.getImageHeight(), m_renderParameters.getImageWidth());
190 const unsigned numComponents = m_texture->get_num_components();
191 int rowIncrement = I.getWidth() * numComponents; // we ask for only 8 bits image, but we may get an rgb image
192 float *data = (float *)(&(m_texture->get_ram_image().front()));
193 // Panda3D stores data upside down
194 data += rowIncrement * (I.getHeight() - 1);
195 rowIncrement = -rowIncrement;
196
197 for (unsigned int i = 0; i < I.getHeight(); ++i) {
198 vpRGBf *colorRow = I[i];
199 for (unsigned int j = 0; j < I.getWidth(); ++j) {
200 colorRow[j].B = data[j * numComponents];
201 colorRow[j].G = data[j * numComponents + 1];
202 colorRow[j].R = data[j * numComponents + 2];
203 }
204 data += rowIncrement;
205 }
206}
207
208END_VISP_NAMESPACE
209
210#elif !defined(VISP_BUILD_SHARED_LIBS)
211// Work around to avoid warning: libvisp_ar.a(vpPanda3DPostProcessFilter.cpp.o) has no symbols
212void dummy_vpPanda3DPostProcessFilter() { }
213
214#endif
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ fatalError
Fatal error.
Definition vpException.h:72
Definition of the vpImage class member functions.
Definition vpImage.h:131
NodePath m_renderRoot
Rendering parameters.
PointerTo< Camera > m_camera
Node containing all the objects and the camera for this renderer.
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.
std::string m_fragmentShader
Whether this filter is an output to be used and should be copied to ram.
virtual FrameBufferProperties getBufferProperties() const =0
static const std::string FILTER_VERTEX_SHADER
void getRenderBasic(vpImage< unsigned char > &I) const
std::shared_ptr< vpPanda3DBaseRenderer > m_inputRenderer
PointerTo< GraphicsOutput > m_buffer
virtual PointerTo< Texture > setupTexture(const FrameBufferProperties &fbp) const
virtual void setupScene() VP_OVERRIDE
Initialize the scene for this specific renderer.
void setRenderParameters(const vpPanda3DRenderParameters &params) VP_OVERRIDE
Set new rendering parameters. If the scene has already been initialized, the renderer camera is updat...
void setupRenderTarget() VP_OVERRIDE
Initialize buffers and other objects that are required to save the render.
void setupCamera() VP_OVERRIDE
Initialize camera. Should be called when the scene root of this render has already been created.
Rendering parameters for a panda3D simulation.
float B
Blue component.
Definition vpRGBf.h:161
float G
Green component.
Definition vpRGBf.h:160
float R
Red component.
Definition vpRGBf.h:159