cgv
Loading...
Searching...
No Matches
renderer.cxx
1#include "renderer.h"
2#include "gl/gl_tools.h"
3
4namespace cgv {
5 namespace render {
6 render_style::~render_style()
7 {
8 }
10 {
11 aam_ptr = 0;
12 }
13 void renderer::manage_singleton(context& ctx, const std::string& renderer_name, int& ref_count, int ref_count_change)
14 {
15 switch (ref_count_change) {
16 case 1:
17 if (ref_count == 0) {
18 if (!init(ctx))
19 ctx.error(std::string("unable to initialize ") + renderer_name + " singleton");
20 }
21 ++ref_count;
22 break;
23 case 0:
24 break;
25 case -1:
26 if (ref_count == 0)
27 ctx.error(std::string("attempt to decrease reference count of ") + renderer_name + " singleton below 0");
28 else {
29 if (--ref_count == 0)
30 clear(ctx);
31 }
32 break;
33 default:
34 ctx.error(std::string("invalid change reference count outside {-1,0,1} for ") + renderer_name + " singleton");
35 }
36 }
38 {
39 if (default_render_style)
40 delete default_render_style;
41 default_render_style = nullptr;
42 }
44 {
45 std::string prog_name = get_default_prog_name();
46 if(!prog_name.empty())
47 return prog.build_program(ctx, prog_name, options, true);
48 return false;
49 }
51 bool renderer::has_attribute(const context& ctx, const std::string& name)
52 {
53 return aam_ptr->has_attribute(ctx, get_prog_attribute_location(ctx, name, false));
54 }
57 {
58 aam_ptr = &aam;
59 if (has_attribute(ctx, "position"))
60 has_positions = true;
61 if (has_attribute(ctx, "color"))
62 has_colors = true;
63 }
66 {
67 has_positions = false;
68 has_colors = false;
69 if (ctx.core_profile)
70 aam_ptr = &default_aam;
71 else
72 aam_ptr = 0;
73 }
75 {
76 if (_aam_ptr)
77 enable_attribute_array_manager(ctx, *_aam_ptr);
78 else
80 }
81 bool renderer::set_attribute_array(const context& ctx, const std::string& name, type_descriptor element_type, const vertex_buffer& vbo, size_t offset_in_bytes, size_t nr_elements, unsigned stride_in_bytes)
82 {
83 int loc = get_prog_attribute_location(ctx, name);
84 if(loc < 0)
85 return false;
86 if (aam_ptr)
87 return aam_ptr->set_attribute_array(ctx, loc, element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
88 enabled_attribute_arrays.insert(loc);
89 return attribute_array_binding::set_global_attribute_array(ctx, loc, element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
90 }
91 bool renderer::remove_attribute_array(const context& ctx, const std::string& name)
92 {
93 int loc = get_prog_attribute_location(ctx, name);
94 if(loc < 0)
95 return false;
96 if(aam_ptr) {
97 aam_ptr->remove_attribute_array(ctx, loc);
98 return true;
99 }
100 enabled_attribute_arrays.erase(loc);
101 return true;
102 }
103 void renderer::set_position_array(const context& ctx, type_descriptor element_type, const vertex_buffer& vbo, size_t offset_in_bytes, size_t nr_elements, unsigned stride_in_bytes)
104 {
105 has_positions = true;
106 set_attribute_array(ctx, "position", element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
107 }
109 has_positions = false;
110 remove_attribute_array(ctx, "position");
111 }
112 void renderer::set_color_array(const context& ctx, type_descriptor element_type, const vertex_buffer& vbo, size_t offset_in_bytes, size_t nr_elements, unsigned stride_in_bytes)
113 {
114 has_colors = true;
115 set_attribute_array(ctx, "color", element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
116 }
118 has_colors = false;
119 remove_attribute_array(ctx, "color");
120 }
122 {
123 if (!has_indices())
124 return;
125 if (aam_ptr)
126 aam_ptr->remove_indices(ctx);
127 index_buffer_ptr = 0;
128 indices = 0;
129 index_count = 0;
130 index_type = cgv::type::info::TI_UNDEF;
131 }
133 {
134 // validate set attributes
135 if (!has_positions) {
136 ctx.error("renderer::enable() position attribute not set");
137 return false;
138 }
139 return true;
140 }
143 {
144 rs = &_rs;
145 }
146
149 {
150 auto* tmp = rs;
151 rs = &_rs;
154 bool res = build_shader_program(ctx, prog, options);
155 rs = tmp;
156 return res;
157 }
158
161 {
162 if (rs)
163 return rs;
164 if (default_render_style)
165 return default_render_style;
166 default_render_style = create_render_style();
167 return default_render_style;
168 }
171 {
172 prog_ptr = &one_shot_prog;
173 }
174
176 {
177 if (ctx.core_profile) {
178 default_aam.init(ctx);
179 if (!aam_ptr)
180 aam_ptr = &default_aam;
181 }
182
183 if (!default_render_style)
184 default_render_style = create_render_style();
185
186 if (!rs)
187 rs = default_render_style;
188
189 if(prog_ptr == &prog) {
190 update_shader_program_options(prog_options);
191 if(!build_shader_program(ctx, prog, prog_options))
192 return false;
193 last_prog_options = prog_options;
194 }
195 return default_render_style != 0;
196 }
197
200 {
201 if (validate_attributes(ctx))
202 return enable(ctx);
203 return false;
204 }
205
207 {
208 if(prog_ptr == &prog) {
209 update_shader_program_options(prog_options);
210 if(prog_options != last_prog_options) {
211 if(prog.is_created())
212 prog.destruct(ctx);
213 if(!build_shader_program(ctx, prog, prog_options))
214 return false;
215#ifndef _DEBUG
216 }
217#else
218 if(current_prog_render_count < 10)
219 std::cerr << "Performance warning: shader is rebuild! Consider using multiple instances of the renderer." << std::endl;
220 current_prog_render_count = 0;
221 }
222 ++current_prog_render_count;
223#endif
224 last_prog_options = prog_options;
225 }
226 bool res = ref_prog().enable(ctx);
227 if (aam_ptr)
228 res = aam_ptr->enable(ctx);
229 return res;
230 }
231
232 bool renderer::disable(context& ctx)
233 {
234 bool res = true;
235 if (aam_ptr)
236 res = aam_ptr->disable(ctx);
237 if (!has_aam()) {
238 if (ctx.core_profile) {
239 for (int loc : enabled_attribute_arrays)
240 res = default_aam.aab.disable_array(ctx, loc) && res;
241 }
242 else {
243 for (int loc : enabled_attribute_arrays)
244 res = attribute_array_binding::disable_global_array(ctx, loc) && res;
245 }
246 enabled_attribute_arrays.clear();
247 has_colors = false;
248 has_positions = false;
249 index_count = 0;
250 }
251 res = ref_prog().disable(ctx) && res;
252 prog_ptr = &prog;
253 return res;
254 }
255 void renderer::draw_impl(context& ctx, PrimitiveType type, size_t start, size_t count, bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
256 {
257 if (use_strips && has_indices()) {
258 glPrimitiveRestartIndex(strip_restart_index);
259 glEnable(GL_PRIMITIVE_RESTART);
260 }
261 if (type == PT_LINES) {
262 if (use_adjacency)
263 if (use_strips)
264 type = PT_LINE_STRIP_ADJACENCY;
265 else
266 type = PT_LINES_ADJACENCY;
267 else
268 if (use_strips)
269 type = PT_LINE_STRIP;
270 }
271 else if (type == PT_TRIANGLES)
272 if (use_adjacency)
273 if (use_strips)
274 type = PT_TRIANGLE_STRIP_ADJACENCY;
275 else
276 type = PT_TRIANGLES_ADJACENCY;
277 else
278 if (use_strips)
279 type = PT_TRIANGLE_STRIP;
280
281 GLenum pt = gl::map_to_gl(type);
282 if (has_indices()) {
283 bool aam_has_index_buffer = aam_ptr && aam_ptr->has_index_buffer();
284 bool use_index_buffer = index_buffer_ptr && !aam_has_index_buffer;
285 bool use_indices = !index_buffer_ptr && !aam_has_index_buffer;
286 if (use_index_buffer)
287 index_buffer_ptr->bind(ctx, VBT_INDICES);
288 const void* offset = reinterpret_cast<const uint8_t*>(use_indices ? indices : 0)
289 + start * cgv::type::info::get_type_size(index_type);
290 glDrawElements(pt, (GLsizei)count, gl::map_to_gl(index_type), offset);
291 if (use_index_buffer)
292 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
293 }
294 else
295 glDrawArrays(pt, (GLint)start, (GLsizei)count);
296 }
297 void renderer::draw_impl_instanced(context& ctx, PrimitiveType type, size_t start, size_t count, size_t instance_count, bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
298 {
299 if (use_strips && has_indices()) {
300 glPrimitiveRestartIndex(strip_restart_index);
301 glEnable(GL_PRIMITIVE_RESTART);
302 }
303 if (type == PT_LINES) {
304 if (use_adjacency)
305 if (use_strips)
306 type = PT_LINE_STRIP_ADJACENCY;
307 else
308 type = PT_LINES_ADJACENCY;
309 else
310 if (use_strips)
311 type = PT_LINE_STRIP;
312 }
313 else if (type == PT_TRIANGLES)
314 if (use_adjacency)
315 if (use_strips)
316 type = PT_TRIANGLE_STRIP_ADJACENCY;
317 else
318 type = PT_TRIANGLES_ADJACENCY;
319 else
320 if (use_strips)
321 type = PT_TRIANGLE_STRIP;
322
323 GLenum pt = gl::map_to_gl(type);
324 if (has_indices()) {
325 bool aam_has_index_buffer = aam_ptr && aam_ptr->has_index_buffer();
326 bool use_index_buffer = index_buffer_ptr && !aam_has_index_buffer;
327 bool use_indices = !index_buffer_ptr && !aam_has_index_buffer;
328 if (use_index_buffer)
329 index_buffer_ptr->bind(ctx, VBT_INDICES);
330 const void* offset = reinterpret_cast<const uint8_t*>(use_indices ? indices : 0)
331 + start * cgv::type::info::get_type_size(index_type);
332 glDrawElementsInstanced(pt, (GLsizei)count, gl::map_to_gl(index_type), offset, (GLsizei)instance_count);
333 if (use_index_buffer)
334 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
335 }
336 else
337 glDrawArraysInstanced(pt, (GLint)start, (GLsizei)count, (GLsizei)instance_count);
338 }
339 void renderer::draw(context& ctx, size_t start, size_t count,
340 bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
341 {
342 draw_impl(ctx, PT_TRIANGLES, start, count, use_strips, use_adjacency, strip_restart_index);
343 }
344 bool renderer::render(context& ctx, size_t start, size_t count, bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
345 {
346 if (!validate_and_enable(ctx))
347 return false;
348 draw(ctx, start, count, use_strips, use_adjacency, strip_restart_index);
349 return disable(ctx);
350 }
351 void renderer::clear(const cgv::render::context& ctx)
352 {
353 prog.destruct(ctx);
354 }
355 }
356}
357
static bool set_global_attribute_array(const context &ctx, int loc, const vertex_buffer &vbo, type_descriptor td, size_t size, size_t offset, unsigned stride=0)
point array of vertex attribute at location loc to vertex buffer array array stored in CPU memory; in...
attribute array manager used to upload arrays to gpu
bool has_attribute(const context &ctx, int loc) const
check whether the given attribute is available
base class for all drawables, which is independent of the used rendering API.
Definition context.h:668
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
Definition context.cxx:307
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2226
void manage_singleton(context &ctx, const std::string &renderer_name, int &ref_count, int ref_count_change)
used by derived classes to manage singletons
Definition renderer.cxx:13
void remove_color_array(const context &ctx)
remove the color attribute
Definition renderer.cxx:117
bool has_attribute(const context &ctx, const std::string &name)
check for attribute
Definition renderer.cxx:51
virtual bool enable(context &ctx)
enables renderer
Definition renderer.cxx:206
bool validate_and_enable(context &ctx)
validate attributes and if successful, enable renderer
Definition renderer.cxx:199
virtual void update_shader_program_options(shader_compile_options &options) const
overload to update the shader program compile options based on the current render style; only called ...
Definition renderer.h:122
virtual bool init(context &ctx)
call init() once before using renderer
Definition renderer.cxx:175
virtual ~renderer()
destructor deletes default renderer style
Definition renderer.cxx:37
virtual bool build_shader_program(context &ctx, shader_program &prog, const shader_compile_options &options) const
overload to change default behaviour and build a custom shader program based on the passed options
Definition renderer.cxx:43
bool build_program(context &ctx, shader_program &prog, const render_style &rs)
build shader program for specific render style
Definition renderer.cxx:148
virtual void enable_attribute_array_manager(const context &ctx, attribute_array_manager &aam)
call this before setting attribute arrays to manage attribute array in given manager
Definition renderer.cxx:56
void remove_position_array(const context &ctx)
remove the position attribute
Definition renderer.cxx:108
virtual void clear(const context &ctx)
the clear function destructs the shader program
Definition renderer.cxx:351
renderer()
construct and init attribute tracking flags
Definition renderer.cxx:9
bool has_colors
track whether color attribute is defined
Definition renderer.h:140
bool has_positions
track whether position attribute is defined
Definition renderer.h:142
virtual void disable_attribute_array_manager(const context &ctx, attribute_array_manager &aam)
call this after last render/draw call to ensure that no other users of renderer change attribute arra...
Definition renderer.cxx:65
const render_style * get_style_ptr() const
access to render style
Definition renderer.cxx:160
virtual render_style * create_render_style() const =0
implement this method to create a default render style
void set_position_array(const context &ctx, const std::vector< T > &positions)
templated method to set the position attribute from a vector of positions of type T
Definition renderer.h:231
virtual bool validate_attributes(const context &ctx) const
call to validate, whether essential position attribute is defined
Definition renderer.cxx:132
void set_render_style(const render_style &rs)
reference given render style
Definition renderer.cxx:142
virtual std::string get_default_prog_name() const =0
implement this method to return the name of the default shader program; return an empty string if the...
void set_color_array(const context &ctx, const std::vector< T > &colors)
template method to set the color attribute from a vector of colors of type T
Definition renderer.h:247
virtual void set_attribute_array_manager(const context &ctx, attribute_array_manager *_aam_ptr=0)
this function is deprecated, please use enable_attribute_array_manager() and disable_attribute_manage...
Definition renderer.cxx:74
void set_prog(shader_program &one_shot_prog)
set external shader program up to next call to disable() or render()
Definition renderer.cxx:170
bool has_indices() const
return whether indices have been defined
Definition renderer.h:321
void remove_indices(const context &ctx)
remove previously set indices
Definition renderer.cxx:121
Stores preprocessor options used for conditionally compiling shader programs.
Definition shader_code.h:73
void clear()
Clear everything, i.e. remove all defines and snippets.
Definition shader_code.h:83
a shader program combines several shader code fragments to a complete definition of the shading pipel...
void destruct(const context &ctx)
destruct shader program
bool build_program(const context &ctx, const std::string &file_name, bool show_error=false)
successively calls create, attach_program and link.
a vertex buffer is an unstructured memory block on the GPU.
PrimitiveType
different primitive types
Definition context.h:281
@ VBT_INDICES
The buffer contains indices and will be bound to GL_ELEMENT_ARRAY_BUFFER.
Definition context.h:475
unsigned int get_type_size(TypeId tid)
function that returns the size of a type specified through TypeId
Definition type_id.cxx:18
this header is dependency free
Definition print.h:11
bool core_profile
default: true
Definition context.h:607
base class for all render styles
Definition renderer.h:16
compact type description of data that can be sent to the context; convertible to int
Definition context.h:61