mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	ENABLE_SEAMS_USING_INSTANCED_MODELS -> WIP: Render models using glDrawElementsInstanced
This commit is contained in:
		
							parent
							
								
									34da899c66
								
							
						
					
					
						commit
						2980418706
					
				
					 8 changed files with 229 additions and 31 deletions
				
			
		
							
								
								
									
										12
									
								
								resources/shaders/gouraud_light_instanced.fs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								resources/shaders/gouraud_light_instanced.fs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | #version 110 | ||||||
|  | 
 | ||||||
|  | uniform vec4 uniform_color; | ||||||
|  | uniform float emission_factor; | ||||||
|  | 
 | ||||||
|  | // x = tainted, y = specular; | ||||||
|  | varying vec2 intensity; | ||||||
|  | 
 | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  |     gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); | ||||||
|  | } | ||||||
							
								
								
									
										57
									
								
								resources/shaders/gouraud_light_instanced.vs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								resources/shaders/gouraud_light_instanced.vs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | ||||||
|  | #version 110 | ||||||
|  | 
 | ||||||
|  | #define INTENSITY_CORRECTION 0.6 | ||||||
|  | 
 | ||||||
|  | // normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) | ||||||
|  | const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); | ||||||
|  | #define LIGHT_TOP_DIFFUSE    (0.8 * INTENSITY_CORRECTION) | ||||||
|  | #define LIGHT_TOP_SPECULAR   (0.125 * INTENSITY_CORRECTION) | ||||||
|  | #define LIGHT_TOP_SHININESS  20.0 | ||||||
|  | 
 | ||||||
|  | // normalized values for (1./1.43, 0.2/1.43, 1./1.43) | ||||||
|  | const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); | ||||||
|  | #define LIGHT_FRONT_DIFFUSE  (0.3 * INTENSITY_CORRECTION) | ||||||
|  | 
 | ||||||
|  | #define INTENSITY_AMBIENT    0.3 | ||||||
|  | 
 | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  | // vertex attributes | ||||||
|  | in vec3 v_position; | ||||||
|  | in vec3 v_normal; | ||||||
|  | // instance attributes | ||||||
|  | in vec3 i_offset; | ||||||
|  | in vec2 i_scales; | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  | 
 | ||||||
|  | // x = tainted, y = specular; | ||||||
|  | varying vec2 intensity; | ||||||
|  | 
 | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  |     // First transform the normal into camera space and normalize the result. | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  |     vec3 eye_normal = normalize(gl_NormalMatrix * v_normal); | ||||||
|  | //    vec3 eye_normal = normalize(gl_NormalMatrix * gl_Normal); | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  |      | ||||||
|  |     // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. | ||||||
|  |     // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. | ||||||
|  |     float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); | ||||||
|  | 
 | ||||||
|  |     intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  |     vec4 world_position = vec4(v_position * vec3(vec2(i_scales.x), i_scales.y) + i_offset, 1.0); | ||||||
|  |     vec3 eye_position = (gl_ModelViewMatrix * world_position).xyz; | ||||||
|  | //    vec3 eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  |     intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); | ||||||
|  | 
 | ||||||
|  |     // Perform the same lighting calculation for the 2nd light source (no specular applied). | ||||||
|  |     NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); | ||||||
|  |     intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; | ||||||
|  | 
 | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  |     gl_Position = gl_ProjectionMatrix * vec4(eye_position, 1.0); | ||||||
|  | //    gl_Position = ftransform(); | ||||||
|  | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||||||
|  | } | ||||||
|  | @ -50,10 +50,6 @@ | ||||||
| // Enable rendering seams (and other options) in preview using models
 | // Enable rendering seams (and other options) in preview using models
 | ||||||
| #define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA0) | #define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA0) | ||||||
| // Enable rendering seams (and other options) in preview using instanced models
 | // Enable rendering seams (and other options) in preview using instanced models
 | ||||||
| // references:
 |  | ||||||
| // https://ogldev.org/www/tutorial33/tutorial33.html
 |  | ||||||
| // https://docs.gl/gl3/glDrawElementsInstanced
 |  | ||||||
| // https://www.khronos.org/opengl/wiki/Vertex_Rendering#Instancing
 |  | ||||||
| #define ENABLE_SEAMS_USING_INSTANCED_MODELS (1 && ENABLE_SEAMS_USING_MODELS) | #define ENABLE_SEAMS_USING_INSTANCED_MODELS (1 && ENABLE_SEAMS_USING_MODELS) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -102,7 +102,8 @@ void GCodeViewer::InstanceVBuffer::reset() | ||||||
|     if (vbo > 0) |     if (vbo > 0) | ||||||
|         glsafe(::glDeleteBuffers(1, &vbo)); |         glsafe(::glDeleteBuffers(1, &vbo)); | ||||||
|     s_ids.clear(); |     s_ids.clear(); | ||||||
|     render_range = { 0, 0 }; |     buffer.clear(); | ||||||
|  |     render_ranges.clear(); | ||||||
| } | } | ||||||
| #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
| 
 | 
 | ||||||
|  | @ -803,7 +804,11 @@ void GCodeViewer::render() | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
|                 if (wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) { |                 if (wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) { | ||||||
|                     buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model; |                     buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model; | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |                     buffer.shader = "gouraud_light_instanced"; | ||||||
|  | #else | ||||||
|                     buffer.shader = "gouraud_light"; |                     buffer.shader = "gouraud_light"; | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|                     buffer.model.model.init_from(diamond(16)); |                     buffer.model.model.init_from(diamond(16)); | ||||||
|                     buffer.model.color = option_color(type); |                     buffer.model.color = option_color(type); | ||||||
|                 } |                 } | ||||||
|  | @ -1764,7 +1769,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | ||||||
| 
 | 
 | ||||||
| #if ENABLE_GCODE_VIEWER_STATISTICS | #if ENABLE_GCODE_VIEWER_STATISTICS | ||||||
|                 m_statistics.total_instances_gpu_size += static_cast<int64_t>(size_bytes); |                 m_statistics.total_instances_gpu_size += static_cast<int64_t>(size_bytes); | ||||||
|                 m_statistics.max_instance_vbuffer_gpu_size = std::max(m_statistics.max_instance_vbuffer_gpu_size, static_cast<int64_t>(size_bytes)); |  | ||||||
| #endif // ENABLE_GCODE_VIEWER_STATISTICS
 | #endif // ENABLE_GCODE_VIEWER_STATISTICS
 | ||||||
| 
 | 
 | ||||||
|                 GLuint id = 0; |                 GLuint id = 0; | ||||||
|  | @ -1774,6 +1778,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | ||||||
|                 glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); |                 glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); | ||||||
| 
 | 
 | ||||||
|                 t_buffer.model.instances2.vbo = id; |                 t_buffer.model.instances2.vbo = id; | ||||||
|  |                 t_buffer.model.instances2.buffer = inst_buffer; | ||||||
|                 t_buffer.model.instances2.s_ids = instances_ids[i]; |                 t_buffer.model.instances2.s_ids = instances_ids[i]; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -2467,21 +2472,36 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool | ||||||
|         if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) |         if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) | ||||||
|             continue; |             continue; | ||||||
| 
 | 
 | ||||||
|         buffer.model.instances2.render_range = { 0, 0 }; |         buffer.model.instances2.render_ranges.clear(); | ||||||
| 
 | 
 | ||||||
|         if (!buffer.visible) |         if (!buffer.visible) | ||||||
|             continue; |             continue; | ||||||
| 
 | 
 | ||||||
|  |         buffer.model.instances2.render_ranges.push_back({ 0, 0, buffer.model.color }); | ||||||
|  |         bool has_second_range = top_layer_only && m_sequential_view.current.last != m_sequential_view.global.last; | ||||||
|  |         if (has_second_range) | ||||||
|  |             buffer.model.instances2.render_ranges.push_back({ 0, 0, Neutral_Color }); | ||||||
|  | 
 | ||||||
|         if (m_sequential_view.current.first <= buffer.model.instances2.s_ids.back() && buffer.model.instances2.s_ids.front() <= m_sequential_view.current.last) { |         if (m_sequential_view.current.first <= buffer.model.instances2.s_ids.back() && buffer.model.instances2.s_ids.front() <= m_sequential_view.current.last) { | ||||||
|             for (size_t id : buffer.model.instances2.s_ids) { |             for (size_t id : buffer.model.instances2.s_ids) { | ||||||
|                 if (id <= m_sequential_view.current.first) { |                 if (has_second_range) { | ||||||
|                     buffer.model.instances2.render_range.offset += buffer.model.instances2.instance_size_bytes(); |                     if (id <= m_sequential_view.endpoints.first) { | ||||||
|                     buffer.model.instances2.render_range.count = 0; |                         buffer.model.instances2.render_ranges.front().offset += buffer.model.instances2.instance_size_bytes(); | ||||||
|  |                         ++buffer.model.instances2.render_ranges.back().count; | ||||||
|  |                     } | ||||||
|  |                     else if (id <= m_sequential_view.current.last) | ||||||
|  |                         ++buffer.model.instances2.render_ranges.front().count; | ||||||
|  |                     else | ||||||
|  |                         break; | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     if (id <= m_sequential_view.current.first) | ||||||
|  |                         buffer.model.instances2.render_ranges.front().offset += buffer.model.instances2.instance_size_bytes(); | ||||||
|  |                     else if (id <= m_sequential_view.current.last) | ||||||
|  |                         ++buffer.model.instances2.render_ranges.front().count; | ||||||
|  |                     else | ||||||
|  |                         break; | ||||||
|                 } |                 } | ||||||
|                 else if (id <= m_sequential_view.current.last) |  | ||||||
|                     ++buffer.model.instances2.render_range.count; |  | ||||||
|                 else |  | ||||||
|                     break; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -2616,7 +2636,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool | ||||||
|         } |         } | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
| #if ENABLE_SEAMS_USING_INSTANCED_MODELS | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |         statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.buffer, float); | ||||||
|         statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.s_ids, size_t); |         statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.s_ids, size_t); | ||||||
|  |         statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.render_ranges, InstanceVBuffer::RenderRange); | ||||||
| #else | #else | ||||||
|         statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); |         statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); | ||||||
| #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|  | @ -2711,7 +2733,18 @@ void GCodeViewer::render_toolpaths() | ||||||
| 
 | 
 | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
|     auto render_as_instanced_model = [this] |     auto render_as_instanced_model = [this] | ||||||
|         (TBuffer & buffer, GLShaderProgram & shader) { |         (TBuffer& buffer, GLShaderProgram & shader) { | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |         if (buffer.model.instances2.vbo > 0) { | ||||||
|  |             for (const InstanceVBuffer::RenderRange& range : buffer.model.instances2.render_ranges) { | ||||||
|  |                 buffer.model.model.set_color(-1, range.color); | ||||||
|  |                 buffer.model.model.render_instanced(buffer.model.instances2.vbo, range.count); | ||||||
|  | #if ENABLE_GCODE_VIEWER_STATISTICS | ||||||
|  |                 ++m_statistics.gl_instanced_models_calls_count; | ||||||
|  | #endif // ENABLE_GCODE_VIEWER_STATISTICS
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | #else | ||||||
|         for (const TBuffer::Model::Instance& inst : buffer.model.instances) { |         for (const TBuffer::Model::Instance& inst : buffer.model.instances) { | ||||||
|             bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; |             bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; | ||||||
|             bool visible = top_layer_only ? |             bool visible = top_layer_only ? | ||||||
|  | @ -2732,6 +2765,7 @@ void GCodeViewer::render_toolpaths() | ||||||
| #endif // ENABLE_GCODE_VIEWER_STATISTICS
 | #endif // ENABLE_GCODE_VIEWER_STATISTICS
 | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|     }; |     }; | ||||||
| #endif // ENABLE_SEAMS_USING_MODELS
 | #endif // ENABLE_SEAMS_USING_MODELS
 | ||||||
| 
 | 
 | ||||||
|  | @ -3800,7 +3834,11 @@ void GCodeViewer::render_statistics() | ||||||
|         add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count); |         add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count); | ||||||
|         add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count); |         add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count); | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |         add_counter(std::string("Instanced models:"), m_statistics.gl_instanced_models_calls_count); | ||||||
|  | #else | ||||||
|         add_counter(std::string("Models:"), m_statistics.gl_models_calls_count); |         add_counter(std::string("Models:"), m_statistics.gl_models_calls_count); | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
| #endif // ENABLE_SEAMS_USING_MODELS
 | #endif // ENABLE_SEAMS_USING_MODELS
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -3824,9 +3862,6 @@ void GCodeViewer::render_statistics() | ||||||
|         ImGui::Separator(); |         ImGui::Separator(); | ||||||
|         add_memory(std::string("Max VBuffer:"), m_statistics.max_vbuffer_gpu_size); |         add_memory(std::string("Max VBuffer:"), m_statistics.max_vbuffer_gpu_size); | ||||||
|         add_memory(std::string("Max IBuffer:"), m_statistics.max_ibuffer_gpu_size); |         add_memory(std::string("Max IBuffer:"), m_statistics.max_ibuffer_gpu_size); | ||||||
| #if ENABLE_SEAMS_USING_INSTANCED_MODELS |  | ||||||
|         add_memory(std::string("Max instance VBuffer:"), m_statistics.max_instance_vbuffer_gpu_size); |  | ||||||
| #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (ImGui::CollapsingHeader("Other")) { |     if (ImGui::CollapsingHeader("Other")) { | ||||||
|  |  | ||||||
|  | @ -105,8 +105,9 @@ class GCodeViewer | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| #if ENABLE_SEAMS_USING_INSTANCED_MODELS | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|     // vbo buffer containing instances data used to render a toolpaths using instanced models
 |     // buffer containing instances data used to render a toolpaths using instanced models
 | ||||||
|     // record format: 5 floats -> position.x|position.y|position.z|width|height
 |     // instance record format: 5 floats -> position.x|position.y|position.z|width|height
 | ||||||
|  |     // which is sent to the shader as -> vec3 (offset) + vec2 (scales) in GLModel::render_instanced()
 | ||||||
|     struct InstanceVBuffer |     struct InstanceVBuffer | ||||||
|     { |     { | ||||||
|         struct RenderRange |         struct RenderRange | ||||||
|  | @ -115,13 +116,18 @@ class GCodeViewer | ||||||
|             unsigned int offset; |             unsigned int offset; | ||||||
|             // count of instances to render
 |             // count of instances to render
 | ||||||
|             unsigned int count; |             unsigned int count; | ||||||
|  |             // Color to apply to the instances
 | ||||||
|  |             Color color; | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         // vbo id
 |         // vbo id
 | ||||||
|         unsigned int vbo{ 0 }; |         unsigned int vbo{ 0 }; | ||||||
|         // move ids
 |         // cpu-side buffer containing all instances data
 | ||||||
|  |         InstanceBuffer buffer; | ||||||
|  |         // indices of the moves for all instances
 | ||||||
|         std::vector<size_t> s_ids; |         std::vector<size_t> s_ids; | ||||||
|         RenderRange render_range; |         // ranges used to render only subparts of the intances
 | ||||||
|  |         std::vector<RenderRange> render_ranges; | ||||||
| 
 | 
 | ||||||
|         size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); } |         size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); } | ||||||
| 
 | 
 | ||||||
|  | @ -518,7 +524,11 @@ class GCodeViewer | ||||||
|         int64_t gl_multi_triangles_calls_count{ 0 }; |         int64_t gl_multi_triangles_calls_count{ 0 }; | ||||||
|         int64_t gl_triangles_calls_count{ 0 }; |         int64_t gl_triangles_calls_count{ 0 }; | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |         int64_t gl_instanced_models_calls_count{ 0 }; | ||||||
|  | #else | ||||||
|         int64_t gl_models_calls_count{ 0 }; |         int64_t gl_models_calls_count{ 0 }; | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
| #endif // ENABLE_SEAMS_USING_MODELS
 | #endif // ENABLE_SEAMS_USING_MODELS
 | ||||||
|         // memory
 |         // memory
 | ||||||
|         int64_t results_size{ 0 }; |         int64_t results_size{ 0 }; | ||||||
|  | @ -529,9 +539,6 @@ class GCodeViewer | ||||||
| #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|         int64_t max_vbuffer_gpu_size{ 0 }; |         int64_t max_vbuffer_gpu_size{ 0 }; | ||||||
|         int64_t max_ibuffer_gpu_size{ 0 }; |         int64_t max_ibuffer_gpu_size{ 0 }; | ||||||
| #if ENABLE_SEAMS_USING_INSTANCED_MODELS |  | ||||||
|         int64_t max_instance_vbuffer_gpu_size{ 0 }; |  | ||||||
| #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 |  | ||||||
|         int64_t paths_size{ 0 }; |         int64_t paths_size{ 0 }; | ||||||
|         int64_t render_paths_size{ 0 }; |         int64_t render_paths_size{ 0 }; | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
|  | @ -570,7 +577,11 @@ class GCodeViewer | ||||||
|             gl_multi_triangles_calls_count = 0; |             gl_multi_triangles_calls_count = 0; | ||||||
|             gl_triangles_calls_count = 0; |             gl_triangles_calls_count = 0; | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |             gl_instanced_models_calls_count = 0; | ||||||
|  | #else | ||||||
|             gl_models_calls_count = 0; |             gl_models_calls_count = 0; | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
| #endif // ENABLE_SEAMS_USING_MODELS
 | #endif // ENABLE_SEAMS_USING_MODELS
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -583,9 +594,6 @@ class GCodeViewer | ||||||
| #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|             max_vbuffer_gpu_size = 0; |             max_vbuffer_gpu_size = 0; | ||||||
|             max_ibuffer_gpu_size = 0; |             max_ibuffer_gpu_size = 0; | ||||||
| #if ENABLE_SEAMS_USING_INSTANCED_MODELS |  | ||||||
|             max_instance_vbuffer_gpu_size = 0; |  | ||||||
| #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 |  | ||||||
|             paths_size = 0; |             paths_size = 0; | ||||||
|             render_paths_size = 0; |             render_paths_size = 0; | ||||||
| #if ENABLE_SEAMS_USING_MODELS | #if ENABLE_SEAMS_USING_MODELS | ||||||
|  |  | ||||||
|  | @ -207,6 +207,85 @@ void GLModel::render() const | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  | void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const | ||||||
|  | { | ||||||
|  |     if (instances_vbo == 0) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     GLShaderProgram* shader = wxGetApp().get_current_shader(); | ||||||
|  |     assert(shader == nullptr || boost::algorithm::iends_with(shader->get_name(), "_instanced")); | ||||||
|  | 
 | ||||||
|  |     // vertex attributes
 | ||||||
|  |     GLint position_id = (shader != nullptr) ? shader->get_attrib_location("v_position") : -1; | ||||||
|  |     GLint normal_id = (shader != nullptr) ? shader->get_attrib_location("v_normal") : -1; | ||||||
|  |     assert(position_id != -1 && normal_id != -1); | ||||||
|  | 
 | ||||||
|  |     // instance attributes
 | ||||||
|  |     GLint offset_id = (shader != nullptr) ? shader->get_attrib_location("i_offset") : -1; | ||||||
|  |     GLint scales_id = (shader != nullptr) ? shader->get_attrib_location("i_scales") : -1; | ||||||
|  |     assert(offset_id != -1 && scales_id != -1); | ||||||
|  | 
 | ||||||
|  |     glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo)); | ||||||
|  |     if (offset_id != -1) { | ||||||
|  |         glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)0)); | ||||||
|  |         glsafe(::glEnableVertexAttribArray(offset_id)); | ||||||
|  |         glsafe(::glVertexAttribDivisor(offset_id, 1)); | ||||||
|  |     } | ||||||
|  |     if (scales_id != -1) { | ||||||
|  |         glsafe(::glVertexAttribPointer(scales_id, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)(3 * sizeof(float)))); | ||||||
|  |         glsafe(::glEnableVertexAttribArray(scales_id)); | ||||||
|  |         glsafe(::glVertexAttribDivisor(scales_id, 1)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (const RenderData& data : m_render_data) { | ||||||
|  |         if (data.vbo_id == 0 || data.ibo_id == 0) | ||||||
|  |             continue; | ||||||
|  | 
 | ||||||
|  |         GLenum mode; | ||||||
|  |         switch (data.type) | ||||||
|  |         { | ||||||
|  |         default: | ||||||
|  |         case PrimitiveType::Triangles: { mode = GL_TRIANGLES; break; } | ||||||
|  |         case PrimitiveType::Lines:     { mode = GL_LINES; break; } | ||||||
|  |         case PrimitiveType::LineStrip: { mode = GL_LINE_STRIP; break; } | ||||||
|  |         case PrimitiveType::LineLoop:  { mode = GL_LINE_LOOP; break; } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (shader != nullptr) | ||||||
|  |             shader->set_uniform("uniform_color", data.color); | ||||||
|  |         else | ||||||
|  |             glsafe(::glColor4fv(data.color.data())); | ||||||
|  | 
 | ||||||
|  |         glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id)); | ||||||
|  |         if (position_id != -1) { | ||||||
|  |             glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)0)); | ||||||
|  |             glsafe(::glEnableVertexAttribArray(position_id)); | ||||||
|  |         } | ||||||
|  |         if (normal_id != -1) { | ||||||
|  |             glsafe(::glVertexAttribPointer(normal_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)(3 * sizeof(float)))); | ||||||
|  |             glsafe(::glEnableVertexAttribArray(normal_id)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id)); | ||||||
|  |         glsafe(::glDrawElementsInstanced(mode, static_cast<GLsizei>(data.indices_count), GL_UNSIGNED_INT, (const void*)0, instances_count)); | ||||||
|  |         glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); | ||||||
|  | 
 | ||||||
|  |         if (normal_id != -1) | ||||||
|  |             glsafe(::glDisableVertexAttribArray(normal_id)); | ||||||
|  |         if (position_id != -1) | ||||||
|  |             glsafe(::glDisableVertexAttribArray(position_id)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (scales_id != -1) | ||||||
|  |         glsafe(::glDisableVertexAttribArray(scales_id)); | ||||||
|  |     if (offset_id != -1) | ||||||
|  |         glsafe(::glDisableVertexAttribArray(offset_id)); | ||||||
|  | 
 | ||||||
|  |     glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); | ||||||
|  | } | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|  | 
 | ||||||
| void GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices) | void GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices) | ||||||
| { | { | ||||||
|     assert(data.vbo_id == 0); |     assert(data.vbo_id == 0); | ||||||
|  |  | ||||||
|  | @ -72,6 +72,9 @@ namespace GUI { | ||||||
| 
 | 
 | ||||||
|         void reset(); |         void reset(); | ||||||
|         void render() const; |         void render() const; | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |         void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const; | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
| 
 | 
 | ||||||
|         bool is_initialized() const { return !m_render_data.empty(); } |         bool is_initialized() const { return !m_render_data.empty(); } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,9 +38,17 @@ std::pair<bool, std::string> GLShadersManager::init() | ||||||
|     // used to render printbed
 |     // used to render printbed
 | ||||||
|     valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); |     valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); | ||||||
|     // used to render options in gcode preview
 |     // used to render options in gcode preview
 | ||||||
|     valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|     if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) |     if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) | ||||||
|         valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); |         valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" }); | ||||||
|  |     else { | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|  |         valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); | ||||||
|  |         if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) | ||||||
|  |             valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); | ||||||
|  | #if ENABLE_SEAMS_USING_INSTANCED_MODELS | ||||||
|  |     } | ||||||
|  | #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS
 | ||||||
|     // used to render extrusion and travel paths as lines in gcode preview
 |     // used to render extrusion and travel paths as lines in gcode preview
 | ||||||
|     valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); |     valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); | ||||||
|     // used to render objects in 3d editor
 |     // used to render objects in 3d editor
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 enricoturri1966
						enricoturri1966