6 #include "../core/log.h" 8 #include "renderlist.h" 9 #include "rendertarget.h" 12 #include "uniformbuffer.h" 15 : camera_uniform_buffer((size_t)UniformBindingPoint::camera),
16 material_buffer((size_t)UniformBindingPoint::material),
17 light_buffer((size_t)UniformBindingPoint::lights) {
22 mesh_data.indices.emplace_back(0);
23 mesh_data.indices.emplace_back(2);
24 mesh_data.indices.emplace_back(1);
25 mesh_data.indices.emplace_back(0);
26 mesh_data.indices.emplace_back(3);
27 mesh_data.indices.emplace_back(2);
29 mesh_data.positions.emplace_back(-1, -1, 0);
30 mesh_data.positions.emplace_back(-1, 1, 0);
31 mesh_data.positions.emplace_back(1, 1, 0);
32 mesh_data.positions.emplace_back(1, -1, 0);
34 mesh_data.texcoords.emplace_back(0, 0);
35 mesh_data.texcoords.emplace_back(0, 1);
36 mesh_data.texcoords.emplace_back(1, 1);
37 mesh_data.texcoords.emplace_back(1, 0);
39 screen_quad = std::make_shared<Mesh>(mesh_data);
42 default_shader = std::make_shared<Shader>(
43 "package://" ROS_PACKAGE_NAME
"/shaders/default.vert",
44 "package://" ROS_PACKAGE_NAME
"/shaders/default.frag");
46 blend_shader = std::make_shared<Shader>(
47 "package://" ROS_PACKAGE_NAME
"/shaders/quad.vert",
48 "package://" ROS_PACKAGE_NAME
"/shaders/blend.frag");
51 void Renderer::render(
const RenderList &render_list,
52 const std::vector<RenderCommand> &commands,
55 int previous_double_sided = -1;
57 for (
auto &command : commands) {
59 auto &material = render_list._materials[command.material_index];
61 int double_sided = (command.options.double_sided ? 1 : 0);
62 if (double_sided != previous_double_sided) {
64 V_GL(glDisable(GL_CULL_FACE));
66 V_GL(glEnable(GL_CULL_FACE));
68 previous_double_sided = double_sided;
71 if (command.material_index < 0 ||
72 command.material_index >= render_list._materials.size()) {
73 throw std::runtime_error(
"material index out of range");
76 material_buffer.update(material);
77 material_buffer.bind();
79 V_GL(glActiveTexture(GL_TEXTURE0 + (
int)Samplers::color));
80 V_GL(glBindTexture(GL_TEXTURE_2D, material.color_texture));
82 V_GL(glActiveTexture(GL_TEXTURE0 + (
int)Samplers::normal));
83 V_GL(glBindTexture(GL_TEXTURE_2D, material.normal_texture));
85 V_GL(glBindVertexArray(command.vertex_array_object));
87 if (command.options.primitive_type == GL_POINTS &&
88 command.options.point_size != 1) {
89 V_GL(glPointSize(std::max(1.0f, command.options.point_size)));
96 for (
size_t instance_index = command.first_instance;
97 instance_index < command.first_instance + command.instance_count;
99 auto &instance = render_list._instances[instance_index];
101 V_GL(glVertexAttrib4fv((GLuint)VertexAttributes::pose_x,
102 instance.pose_x.data()));
103 V_GL(glVertexAttrib4fv((GLuint)VertexAttributes::pose_y,
104 instance.pose_y.data()));
105 V_GL(glVertexAttrib4fv((GLuint)VertexAttributes::pose_z,
106 instance.pose_z.data()));
108 if (command.indexed) {
109 V_GL(glDrawElements(command.options.primitive_type,
110 command.element_count, GL_UNSIGNED_INT,
nullptr));
112 V_GL(glDrawArrays(command.options.primitive_type, 0,
113 command.element_count));
121 if (command.options.primitive_type == GL_POINTS &&
122 command.options.point_size != 1) {
123 V_GL(glPointSize(1));
128 void Renderer::prepare(
const CameraBlock &camera_block,
131 V_GL(glEnable(GL_FRAMEBUFFER_SRGB));
132 V_GL(glEnable(GL_DEPTH_TEST));
133 V_GL(glEnable(GL_CULL_FACE));
134 V_GL(glCullFace(GL_BACK));
135 V_GL(glDisable(GL_BLEND));
136 V_GL(glDepthMask(GL_TRUE));
138 glEnable(GL_MULTISAMPLE);
140 camera_uniform_buffer.update(camera_block);
141 camera_uniform_buffer.bind();
143 Eigen::Matrix4f view_to_world = camera_block.view_matrix.inverse();
146 light_array.light_count = std::min(
sizeof(light_array.light_array) /
147 sizeof(light_array.light_array[0]),
148 render_list._lights.size());
149 for (
size_t light_index = 0; light_index < light_array.light_count;
152 auto &light = light_array.light_array[light_index];
154 light_array.light_array[light_index] = render_list._lights[light_index];
156 if (light.type & uint32_t(LightType::ViewSpace)) {
158 p.head(3) = light_array.light_array[light_index].position;
160 p = view_to_world * p;
162 light_array.light_array[light_index].position = p.head(3);
164 light_array.light_array[light_index].pose =
165 light_array.light_array[light_index].pose * camera_block.view_matrix;
168 light.type = (light.type & 0xff);
170 light_buffer.update(light_array);
179 if (x < 0 || y < 0 || x >= render_target._width ||
180 y >= render_target._height) {
184 V_GL(glDisable(GL_FRAMEBUFFER_SRGB));
185 V_GL(glEnable(GL_DEPTH_TEST));
186 V_GL(glEnable(GL_CULL_FACE));
187 V_GL(glCullFace(GL_BACK));
188 V_GL(glDisable(GL_BLEND));
190 prepare(camera_block, render_list);
192 default_shader->use();
193 render_target._pick_framebuffer.bind();
195 V_GL(glClearColor(0, 0, 0, 0));
196 V_GL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
198 render(render_list, render_list._commands,
true);
203 std::array<uint32_t, 4> id;
205 V_GL(glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT,
id.data()));
211 V_GL(glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth));
215 LOG_DEBUG(
"pick " << x <<
" " << y <<
" " << ret.id <<
" " << ret.depth);
217 V_GL(glUseProgram(0));
218 V_GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
227 prepare(camera_block, render_list);
229 default_shader->use();
231 _transparent.clear();
233 for (
auto &command : render_list._commands) {
234 if (command.element_count > 0) {
235 auto &material = render_list._materials[command.material_index];
236 if (command.options.transparent || material.transparent ||
237 material.color.w() < 1.0) {
238 _transparent.push_back(command);
240 _opaque.push_back(command);
245 render_target._transparent_framebuffer_head.bind();
246 V_GL(glClearColor(0, 0, 0, 0));
247 V_GL(glClear(GL_COLOR_BUFFER_BIT));
249 if (camera_block.flags & CameraBlock::SampleShadingFlag) {
250 glEnable(GL_SAMPLE_SHADING);
251 glMinSampleShading(1.0);
253 glDisable(GL_SAMPLE_SHADING);
256 render_target._opaque_framebuffer.bind();
257 V_GL(glDepthMask(GL_TRUE));
258 V_GL(glDisable(GL_BLEND));
259 render(render_list, _opaque);
261 if (_transparent.empty()) {
263 std::lock_guard<std::mutex> lock(render_target._mutex);
265 render_target._front_framebuffer.bind();
266 render_target._front_framebuffer.attach(render_target._front_colorbuffer,
267 GL_COLOR_ATTACHMENT0);
269 V_GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
270 render_target._front_framebuffer.id()));
271 V_GL(glBindFramebuffer(GL_READ_FRAMEBUFFER,
272 render_target._opaque_framebuffer.id()));
273 V_GL(glBlitFramebuffer(0, 0, render_target._width, render_target._height, 0,
274 0, render_target._width, render_target._height,
275 GL_COLOR_BUFFER_BIT, GL_NEAREST));
277 render_target._front_framebuffer.bind();
278 V_GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
279 GL_RENDERBUFFER, 0));
281 V_GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
288 if (camera_block.flags & CameraBlock::TransparentSampleShadingFlag) {
289 glEnable(GL_SAMPLE_SHADING);
290 glMinSampleShading(1.0);
292 glDisable(GL_SAMPLE_SHADING);
295 render_target._transparent_framebuffer_tail.bind();
296 V_GL(glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO,
297 GL_ONE_MINUS_SRC_ALPHA));
298 V_GL(glDisable(GL_CULL_FACE));
299 V_GL(glDepthMask(GL_FALSE));
300 V_GL(glEnable(GL_BLEND));
301 V_GL(glClearColor(0, 0, 0, 1));
302 V_GL(glClear(GL_COLOR_BUFFER_BIT));
303 render(render_list, _transparent);
305 render_target._transparent_framebuffer_head.bind();
306 V_GL(glDepthMask(GL_TRUE));
307 V_GL(glDisable(GL_BLEND));
308 render(render_list, _transparent);
310 V_GL(glEnable(GL_CULL_FACE));
312 std::lock_guard<std::mutex> lock(render_target._mutex);
314 render_target._front_framebuffer.attach(render_target._front_colorbuffer,
315 GL_COLOR_ATTACHMENT0);
316 render_target._front_framebuffer.bind();
318 V_GL(glDepthMask(GL_FALSE));
320 glDisable(GL_SAMPLE_SHADING);
326 V_GL(glUniform1i(glGetUniformLocation(blend_shader->program(),
"opaque"),
328 V_GL(glActiveTexture(GL_TEXTURE1));
329 V_GL(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
330 render_target._opaque_texture.id()));
333 glGetUniformLocation(blend_shader->program(),
"transparent_head"), 2));
334 V_GL(glActiveTexture(GL_TEXTURE2));
335 V_GL(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
336 render_target._transparent_texture_head.id()));
339 glGetUniformLocation(blend_shader->program(),
"transparent_tail_color"),
341 V_GL(glActiveTexture(GL_TEXTURE3));
342 V_GL(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
343 render_target._transparent_texture_tail_color.id()));
346 glGetUniformLocation(blend_shader->program(),
"transparent_tail_alpha"),
348 V_GL(glActiveTexture(GL_TEXTURE4));
349 V_GL(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
350 render_target._transparent_texture_tail_alpha.id()));
352 V_GL(glUniform1i(glGetUniformLocation(blend_shader->program(),
"samples"),
353 render_target._samples));
355 V_GL(glDrawElements(GL_TRIANGLES, screen_quad->data().indices.size(),
356 GL_UNSIGNED_INT,
nullptr));
358 V_GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
360 V_GL(glActiveTexture(GL_TEXTURE1));
361 V_GL(glBindTexture(GL_TEXTURE_2D, 0));
363 V_GL(glActiveTexture(GL_TEXTURE2));
364 V_GL(glBindTexture(GL_TEXTURE_2D, 0));
366 V_GL(glActiveTexture(GL_TEXTURE3));
367 V_GL(glBindTexture(GL_TEXTURE_2D, 0));
369 V_GL(glActiveTexture(GL_TEXTURE4));
370 V_GL(glBindTexture(GL_TEXTURE_2D, 0));
376 glDisable(GL_SAMPLE_SHADING);
378 V_GL(glDepthMask(GL_TRUE));
379 V_GL(glDisable(GL_BLEND));
381 V_GL(glBindVertexArray(0));
382 V_GL(glUseProgram(0));