31 #include <visp3/ar/vpPanda3DRGBRenderer.h>
33 #if defined(VISP_HAVE_PANDA3D)
35 #include "orthographicLens.h"
36 #include "cardMaker.h"
37 #include "texturePool.h"
38 #include "graphicsOutput.h"
39 #include "graphicsEngine.h"
40 #include "windowFramework.h"
44 const std::string vpPanda3DRGBRenderer::COOK_TORRANCE_VERT =
46 "in vec3 p3d_Normal;\n"
47 "in vec4 p3d_Vertex;\n"
49 "out vec4 viewVertex;\n"
50 "uniform mat3 p3d_NormalMatrix;\n"
51 "uniform mat4 p3d_ModelViewMatrix;\n"
52 "uniform mat4 p3d_ModelViewProjectionMatrix;\n"
53 "in vec2 p3d_MultiTexCoord0;\n"
54 "out vec2 texcoords;\n"
56 "uniform struct p3d_MaterialParameters {\n"
62 " // These properties are new in 1.10.\n"
66 " float refractiveIndex;\n"
68 "vec3 computeF0(float ior, float metallic, vec3 baseColor)\n"
70 " float F0f = pow(abs((1.0 - ior) / (1.0 + ior)), 2.0);\n"
71 " vec3 F0 = vec3(F0f, F0f, F0f);\n"
72 " return mix(F0, baseColor, metallic);\n"
76 " gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
77 " oNormal = p3d_NormalMatrix * normalize(p3d_Normal);\n"
78 " viewVertex = p3d_ModelViewMatrix * p3d_Vertex;\n"
79 " texcoords = p3d_MultiTexCoord0;\n"
80 " F0 = computeF0(p3d_Material.refractiveIndex, p3d_Material.metallic, p3d_Material.baseColor.xyz);\n"
83 const std::string vpPanda3DRGBRenderer::COOK_TORRANCE_FRAG =
84 "// Version 330, specified when generating shader\n"
85 "#define M_PI 3.1415926535897932384626433832795\n"
87 "in vec4 viewVertex;\n"
89 "out vec4 p3d_FragData;\n"
93 "uniform struct p3d_LightSourceParameters {\n"
94 " // Primary light color.\n"
96 " // View-space position. If w=0, this is a directional light, with the xyz\n"
97 " // being -direction.\n"
99 " // constant, linear, quadratic attenuation in one vector\n"
100 " vec3 attenuation;\n"
101 "} p3d_LightSource[4];\n"
102 "uniform struct p3d_MaterialParameters {\n"
107 " float shininess;\n"
108 " // These properties are new in 1.10.\n"
110 " float roughness;\n"
112 " float refractiveIndex;\n"
114 "in vec2 texcoords;\n"
115 "#ifdef HAS_TEXTURE\n"
116 "uniform sampler2D p3d_Texture0;\n"
118 "float D(float roughness2, float hn)\n"
120 " return (1.f / (M_PI * roughness2)) * pow(hn, (2.f / roughness2) - 2.f);\n"
122 "float G(float hn, float nv, float nl, float vh)\n"
124 " return min(1.0, min((2.f * hn * nv) / vh, (2.f * hn * nl) / vh));\n"
126 "vec3 F(vec3 F0, float vh)\n"
128 " return F0 + (vec3(1.f, 1.f, 1.f) - F0) * pow(1.f - vh, 5);\n"
132 " vec3 n = normalize(oNormal); // normalized normal vector\n"
133 " vec3 v = normalize(-viewVertex.xyz); // normalized view vector\n"
134 " float nv = max(0.f, dot(n, v));\n"
135 " float roughness2 = clamp(pow(p3d_Material.roughness, 2), 0.01, 0.99);\n"
137 " #ifdef HAS_TEXTURE\n"
138 " vec4 baseColor = texture(p3d_Texture0, texcoords);\n"
139 " vec4 ambientColor = baseColor;\n"
141 " vec4 ambientColor = p3d_Material.ambient;\n"
142 " vec4 baseColor = p3d_Material.baseColor;\n"
144 " p3d_FragData = p3d_LightModel.ambient * baseColor;\n"
145 " for(int i = 0; i < p3d_LightSource.length(); ++i) {\n"
146 " vec3 lf = p3d_LightSource[i].position.xyz - (viewVertex.xyz * p3d_LightSource[i].position.w);\n"
147 " float lightDist = length(lf);\n"
148 " vec3 l = normalize(lf); // normalized light vector\n"
149 " vec3 h = normalize(l + v); // half way vector\n"
150 " float hn = dot(h, n);\n"
151 " float nl = max(0.f, dot(n, l));\n"
152 " float vh = max(0.f, dot(v, h));\n"
153 " vec3 aFac = p3d_LightSource[i].attenuation;\n"
154 " float attenuation = 1.f / (aFac[0] + aFac[1] * lightDist + aFac[2] * lightDist * lightDist);\n"
155 " vec3 FV = F(F0, vh);\n"
156 " vec3 kd = (1.f - p3d_Material.metallic) * (1.f - FV) * (1.f / M_PI);\n"
158 " vec3 specularColor = vec3(0.f, 0.f, 0.f);\n"
159 " if(nl > 0.f && nv > 0.f) {\n"
160 " float DV = D(roughness2, hn);\n"
161 " float GV = G(hn, nv, nl, vh);\n"
162 " vec3 rs = (DV * GV * FV) / (4.f * nl * nv);\n"
163 " specularColor = rs * p3d_Material.specular;\n"
166 " vec3 specularColor = vec3(0.0, 0.0, 0.0);\n"
168 " p3d_FragData += (p3d_LightSource[i].color * attenuation) * nl * (baseColor * vec4(kd, 1.f) + vec4(specularColor, 1.f));\n"
170 " p3d_FragData.bgra = p3d_FragData;\n"
175 std::stringstream ss;
176 ss <<
"#version 330" << std::endl;
178 ss <<
"#define HAS_TEXTURE 1" << std::endl;
181 ss <<
"#define SPECULAR 1" << std::endl;
184 ss <<
"#undef SPECULAR" << std::endl;
186 ss << vpPanda3DRGBRenderer::COOK_TORRANCE_FRAG;
193 objectInScene.set_name(
object.get_name());
194 TextureCollection txs = objectInScene.find_all_textures();
195 bool hasTexture = (
static_cast<unsigned int>(txs.size()) > 0);
198 std::vector<std::string> fallbackNames {
"pbr-fallback",
"normal-fallback",
"emission-fallback" };
199 unsigned int numMatches = 0;
200 for (
const std::string &fallbackName: fallbackNames) {
201 numMatches +=
static_cast<int>(txs.find_texture(fallbackName) !=
nullptr);
203 hasTexture = (
static_cast<unsigned int>(txs.size()) > numMatches);
206 PT(Shader) shader = Shader::make(Shader::ShaderLanguage::SL_GLSL,
210 objectInScene.set_shader(shader);
218 if (m_display2d ==
nullptr) {
219 CardMaker cm(
"card");
220 cm.set_frame_fullscreen_quad();
222 NodePath myCamera2d(
new Camera(
"myCam2d"));
223 PT(OrthographicLens) lens =
new OrthographicLens();
224 lens->set_film_size(2, 2);
225 lens->set_near_far(-1000, 1000);
226 lens->set_film_offset(0, 0);
227 ((Camera *)myCamera2d.node())->set_lens(lens);
229 NodePath myRender2d(
"myRender2d");
230 myRender2d.set_depth_test(
false);
231 myRender2d.set_depth_write(
false);
232 myCamera2d.reparent_to(myRender2d);
233 m_backgroundImage = myRender2d.attach_new_node(cm.generate());
235 m_display2d = m_colorBuffer->make_display_region();
236 m_display2d->set_sort(-100);
237 m_display2d->set_camera(myCamera2d);
239 if (m_backgroundTexture ==
nullptr) {
240 m_backgroundTexture =
new Texture();
242 m_backgroundImage.set_texture(m_backgroundTexture);
243 m_backgroundTexture->setup_2d_texture(background.
getWidth(), background.
getHeight(),
244 Texture::ComponentType::T_unsigned_byte,
245 Texture::Format::F_rgba8);
247 unsigned char *data = (
unsigned char *)m_backgroundTexture->modify_ram_image();
249 for (
unsigned int i = 0; i < background.
getHeight(); ++i) {
251 unsigned char *destRow = data + i * background.
getWidth() * 4;
252 memcpy(destRow, srcRow, background.
getWidth() * 4);
258 I.
resize(m_colorTexture->get_y_size(), m_colorTexture->get_x_size());
259 unsigned char *data = (
unsigned char *)(&(m_colorTexture->get_ram_image().front()));
260 int rowIncrement = I.
getWidth() * 4;
263 data = data + rowIncrement * (I.
getHeight() - 1);
264 rowIncrement = -rowIncrement;
266 for (
unsigned int i = 0; i < I.
getHeight(); ++i) {
269 memcpy((
unsigned char *)(colorRow), data,
sizeof(
unsigned char) * 4 * I.
getWidth());
277 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();
311 m_colorBuffer = engine->make_output(pipe,
"Color Buffer" + std::to_string(
id),
m_renderOrder,
312 fbp, win_prop, flags,
314 m_colorTexture =
new Texture(
"Color texture" + std::to_string(
id));
316 if (m_colorBuffer ==
nullptr) {
321 fbp.setup_color_texture(m_colorTexture);
323 m_colorBuffer->add_render_texture(m_colorTexture, GraphicsOutput::RenderTextureMode::RTM_copy_texture, GraphicsOutput::RenderTexturePlane::RTP_color);
324 m_colorBuffer->set_clear_color(LColor(0.f));
325 m_colorBuffer->set_clear_color_active(
true);
326 DisplayRegion *region = m_colorBuffer->make_display_region();
327 if (region ==
nullptr) {
331 region->set_clear_color(LColor(0.f));
336 #elif !defined(VISP_BUILD_SHARED_LIBS)
338 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.
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
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...
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