31 #include <visp3/ar/vpPanda3DRGBRenderer.h>
33 #if defined(VISP_HAVE_PANDA3D)
35 #include "orthographicLens.h"
36 #include "cardMaker.h"
37 #include "texturePool.h"
40 const char *vpPanda3DRGBRenderer::COOK_TORRANCE_VERT =
42 "in vec3 p3d_Normal;\n"
43 "in vec4 p3d_Vertex;\n"
45 "out vec4 viewVertex;\n"
46 "uniform mat3 p3d_NormalMatrix;\n"
47 "uniform mat4 p3d_ModelViewMatrix;\n"
48 "uniform mat4 p3d_ModelViewProjectionMatrix;\n"
49 "in vec2 p3d_MultiTexCoord0;\n"
50 "out vec2 texcoords;\n"
52 "uniform struct p3d_MaterialParameters {\n"
58 " // These properties are new in 1.10.\n"
62 " float refractiveIndex;\n"
64 "vec3 computeF0(float ior, float metallic, vec3 baseColor)\n"
66 " float F0f = pow(abs((1.0 - ior) / (1.0 + ior)), 2.0);\n"
67 " vec3 F0 = vec3(F0f, F0f, F0f);\n"
68 " return mix(F0, baseColor, metallic);\n"
72 " gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
73 " oNormal = p3d_NormalMatrix * normalize(p3d_Normal);\n"
74 " viewVertex = p3d_ModelViewMatrix * p3d_Vertex;\n"
75 " texcoords = p3d_MultiTexCoord0;\n"
76 " F0 = computeF0(p3d_Material.refractiveIndex, p3d_Material.metallic, p3d_Material.baseColor.xyz);\n"
79 const char *vpPanda3DRGBRenderer::COOK_TORRANCE_FRAG =
80 "// Version 330, specified when generating shader\n"
81 "#define M_PI 3.1415926535897932384626433832795\n"
83 "in vec4 viewVertex;\n"
85 "out vec4 p3d_FragData;\n"
89 "uniform struct p3d_LightSourceParameters {\n"
90 " // Primary light color.\n"
92 " // View-space position. If w=0, this is a directional light, with the xyz\n"
93 " // being -direction.\n"
95 " // constant, linear, quadratic attenuation in one vector\n"
96 " vec3 attenuation;\n"
97 "} p3d_LightSource[4];\n"
98 "uniform struct p3d_MaterialParameters {\n"
103 " float shininess;\n"
104 " // These properties are new in 1.10.\n"
106 " float roughness;\n"
108 " float refractiveIndex;\n"
110 "in vec2 texcoords;\n"
111 "#ifdef HAS_TEXTURE\n"
112 "uniform sampler2D p3d_Texture0;\n"
114 "float D(float roughness2, float hn)\n"
116 " return (1.f / (M_PI * roughness2)) * pow(hn, (2.f / roughness2) - 2.f);\n"
118 "float G(float hn, float nv, float nl, float vh)\n"
120 " return min(1.0, min((2.f * hn * nv) / vh, (2.f * hn * nl) / vh));\n"
122 "vec3 F(vec3 F0, float vh)\n"
124 " return F0 + (vec3(1.f, 1.f, 1.f) - F0) * pow(1.f - vh, 5);\n"
128 " vec3 n = normalize(oNormal); // normalized normal vector\n"
129 " vec3 v = normalize(-viewVertex.xyz); // normalized view vector\n"
130 " float nv = max(0.f, dot(n, v));\n"
131 " float roughness2 = clamp(pow(p3d_Material.roughness, 2), 0.01, 0.99);\n"
133 " #ifdef HAS_TEXTURE\n"
134 " vec4 baseColor = texture(p3d_Texture0, texcoords);\n"
135 " vec4 ambientColor = baseColor;\n"
137 " vec4 ambientColor = p3d_Material.ambient;\n"
138 " vec4 baseColor = p3d_Material.baseColor;\n"
140 " p3d_FragData = p3d_LightModel.ambient * baseColor;\n"
141 " for(int i = 0; i < p3d_LightSource.length(); ++i) {\n"
142 " vec3 lf = p3d_LightSource[i].position.xyz - (viewVertex.xyz * p3d_LightSource[i].position.w);\n"
143 " float lightDist = length(lf);\n"
144 " vec3 l = normalize(lf); // normalized light vector\n"
145 " vec3 h = normalize(l + v); // half way vector\n"
146 " float hn = dot(h, n);\n"
147 " float nl = max(0.f, dot(n, l));\n"
148 " float vh = max(0.f, dot(v, h));\n"
149 " vec3 aFac = p3d_LightSource[i].attenuation;\n"
150 " float attenuation = 1.f / (aFac[0] + aFac[1] * lightDist + aFac[2] * lightDist * lightDist);\n"
151 " vec3 FV = F(F0, vh);\n"
152 " vec3 kd = (1.f - p3d_Material.metallic) * (1.f - FV) * (1.f / M_PI);\n"
154 " vec3 specularColor = vec3(0.f, 0.f, 0.f);\n"
155 " if(nl > 0.f && nv > 0.f) {\n"
156 " float DV = D(roughness2, hn);\n"
157 " float GV = G(hn, nv, nl, vh);\n"
158 " vec3 rs = (DV * GV * FV) / (4.f * nl * nv);\n"
159 " specularColor = rs * p3d_Material.specular;\n"
162 " vec3 specularColor = vec3(0.0, 0.0, 0.0);\n"
164 " p3d_FragData += (p3d_LightSource[i].color * attenuation) * nl * (baseColor * vec4(kd, 1.f) + vec4(specularColor, 1.f));\n"
166 " p3d_FragData.bgra = p3d_FragData;\n"
171 std::stringstream ss;
172 ss <<
"#version 330" << std::endl;
174 ss <<
"#define HAS_TEXTURE 1" << std::endl;
177 ss <<
"#define SPECULAR 1" << std::endl;
180 ss <<
"#undef SPECULAR" << std::endl;
182 ss << vpPanda3DRGBRenderer::COOK_TORRANCE_FRAG;
189 objectInScene.set_name(
object.get_name());
190 TextureCollection txs = objectInScene.find_all_textures();
191 bool hasTexture = (
static_cast<unsigned int>(txs.size()) > 0);
194 std::vector<std::string> fallbackNames {
"pbr-fallback",
"normal-fallback",
"emission-fallback" };
195 unsigned int numMatches = 0;
196 for (
const std::string &fallbackName: fallbackNames) {
197 numMatches +=
static_cast<int>(txs.find_texture(fallbackName) !=
nullptr);
199 hasTexture = (
static_cast<unsigned int>(txs.size()) > numMatches);
202 PT(Shader) shader = Shader::make(Shader::ShaderLanguage::SL_GLSL,
206 objectInScene.set_shader(shader);
214 if (m_display2d ==
nullptr) {
215 CardMaker cm(
"card");
216 cm.set_frame_fullscreen_quad();
218 NodePath myCamera2d(
new Camera(
"myCam2d"));
219 PT(OrthographicLens) lens =
new OrthographicLens();
220 lens->set_film_size(2, 2);
221 lens->set_near_far(-1000, 1000);
222 lens->set_film_offset(0, 0);
223 ((Camera *)myCamera2d.node())->set_lens(lens);
225 NodePath myRender2d(
"myRender2d");
226 myRender2d.set_depth_test(
false);
227 myRender2d.set_depth_write(
false);
228 myCamera2d.reparent_to(myRender2d);
229 m_backgroundImage = myRender2d.attach_new_node(cm.generate());
231 m_display2d = m_colorBuffer->make_display_region();
232 m_display2d->set_sort(-100);
233 m_display2d->set_camera(myCamera2d);
235 if (m_backgroundTexture ==
nullptr) {
236 m_backgroundTexture =
new Texture();
238 m_backgroundImage.set_texture(m_backgroundTexture);
239 m_backgroundTexture->setup_2d_texture(background.
getWidth(), background.
getHeight(),
240 Texture::ComponentType::T_unsigned_byte,
241 Texture::Format::F_rgba8);
243 unsigned char *data = (
unsigned char *)m_backgroundTexture->modify_ram_image();
245 for (
unsigned int i = 0; i < background.
getHeight(); ++i) {
247 unsigned char *destRow = data + i * background.
getWidth() * 4;
248 for (
unsigned int j = 0; j < background.
getWidth(); ++j) {
249 destRow[j * 4] = srcRow[j].
B;
250 destRow[j * 4 + 1] = srcRow[j].
G;
251 destRow[j * 4 + 2] = srcRow[j].
R;
252 destRow[j * 4 + 3] = srcRow[j].
A;
259 I.
resize(m_colorTexture->get_y_size(), m_colorTexture->get_x_size());
260 unsigned char *data = (
unsigned char *)(&(m_colorTexture->get_ram_image().front()));
261 int rowIncrement = I.
getWidth() * 4;
264 data = data + rowIncrement * (I.
getHeight() - 1);
265 rowIncrement = -rowIncrement;
267 for (
unsigned int i = 0; i < I.
getHeight(); ++i) {
270 memcpy((
unsigned char *)(colorRow), data,
sizeof(
unsigned char) * 4 * I.
getWidth());
278 data += rowIncrement;
293 FrameBufferProperties fbp;
294 fbp.set_rgb_color(
true);
295 fbp.set_float_depth(
false);
296 fbp.set_float_color(
false);
297 fbp.set_depth_bits(16);
298 fbp.set_rgba_bits(8, 8, 8, 8);
299 fbp.set_srgb_color(
true);
301 WindowProperties win_prop;
305 int flags = GraphicsPipe::BF_refuse_window | GraphicsPipe::BF_resizeable;
306 GraphicsOutput *windowOutput =
m_window->get_graphics_output();
307 GraphicsEngine *engine = windowOutput->get_engine();
308 GraphicsStateGuardian *gsg = windowOutput->get_gsg();
309 GraphicsPipe *pipe = windowOutput->get_pipe();
310 m_colorBuffer = engine->make_output(pipe,
"Color Buffer",
m_renderOrder,
311 fbp, win_prop, flags,
313 if (m_colorBuffer ==
nullptr) {
318 m_colorTexture =
new Texture();
319 fbp.setup_color_texture(m_colorTexture);
321 m_colorBuffer->add_render_texture(m_colorTexture, GraphicsOutput::RenderTextureMode::RTM_copy_texture);
322 m_colorBuffer->set_clear_color(LColor(0.f));
323 m_colorBuffer->set_clear_color_active(
true);
324 DisplayRegion *region = m_colorBuffer->make_display_region();
325 if (region ==
nullptr) {
329 region->set_clear_color(LColor(0.f));
334 #elif !defined(VISP_BUILD_SHARED_LIBS)
336 void dummy_vpPanda3DRGBRenderer() { };
error that can be emitted by ViSP classes.
Implementation of an homogeneous matrix and operations on such kind of matrices.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getHeight() const
virtual void setupScene()
Initialize the scene for this specific renderer.
NodePath m_renderRoot
Rendering parameters.
PointerTo< WindowFramework > m_window
Pointer to the active panda framework.
int m_renderOrder
name of the renderer
virtual void setNodePose(const std::string &name, const vpHomogeneousMatrix &wTo)
Set the pose of a node. This node can be any Panda object (light, mesh, camera). The pose is specifie...
std::vector< GraphicsOutput * > m_buffers
NodePath of the camera.
vpPanda3DRenderParameters m_renderParameters
Pointer to owning window, which can create buffers etc. It is not necessarily visible.
void setLightableScene(NodePath &scene)
virtual std::string makeFragmentShader(bool hasTexture, bool specular)
void getRender(vpImage< vpRGBa > &I) const
Store the render resulting from calling renderFrame() into a vpImage.
void addNodeToScene(const NodePath &object) VP_OVERRIDE
Add a node to the scene. Its pose is set as the identity matrix.
void setBackgroundImage(const vpImage< vpRGBa > &background)
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.
unsigned int getImageWidth() const
unsigned int getImageHeight() const
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
unsigned char A
Additionnal component.