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 void renderer::manage_singleton(context& ctx, const std::string& renderer_name, int& ref_count, int ref_count_change)
11 {
12 switch (ref_count_change) {
13 case 1:
14 if (ref_count == 0) {
15 if (!init(ctx))
16 ctx.error(std::string("unable to initialize ") + renderer_name + " singleton");
17 }
18 ++ref_count;
19 break;
20 case 0:
21 break;
22 case -1:
23 if (ref_count == 0)
24 ctx.error(std::string("attempt to decrease reference count of ") + renderer_name + " singleton below 0");
25 else {
26 if (--ref_count == 0)
27 clear(ctx);
28 }
29 break;
30 default:
31 ctx.error(std::string("invalid change reference count outside {-1,0,1} for ") + renderer_name + " singleton");
32 }
33 }
35 {
36 if (default_render_style)
37 delete default_render_style;
38 default_render_style = nullptr;
39 }
41 {
42 std::string prog_name = get_default_prog_name();
43 if(!prog_name.empty())
44 return prog.build_program(ctx, prog_name, options, true);
45 return false;
46 }
48 bool renderer::has_attribute(const context& ctx, const std::string& name)
49 {
50 return aam_ptr->has_attribute(ctx, get_prog_attribute_location(ctx, name, false));
51 }
54 {
55 aam_ptr = &aam;
56 if (has_attribute(ctx, "position"))
57 has_positions = true;
58 if (has_attribute(ctx, "color"))
59 has_colors = true;
60 }
63 {
64 has_positions = false;
65 has_colors = false;
66 if (ctx.core_profile)
67 aam_ptr = &default_aam;
68 else
69 aam_ptr = 0;
70 }
72 {
73 if (_aam_ptr)
74 enable_attribute_array_manager(ctx, *_aam_ptr);
75 else
77 }
78 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)
79 {
80 int loc = get_prog_attribute_location(ctx, name);
81 if(loc < 0)
82 return false;
83 if (aam_ptr)
84 return aam_ptr->set_attribute_array(ctx, loc, element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
85 enabled_attribute_arrays.insert(loc);
86 return attribute_array_binding::set_global_attribute_array(ctx, loc, element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
87 }
88 bool renderer::remove_attribute_array(const context& ctx, const std::string& name)
89 {
90 int loc = get_prog_attribute_location(ctx, name);
91 if(loc < 0)
92 return false;
93 if(aam_ptr) {
94 aam_ptr->remove_attribute_array(ctx, loc);
95 return true;
96 }
97 enabled_attribute_arrays.erase(loc);
98 return true;
99 }
100 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)
101 {
102 has_positions = true;
103 set_attribute_array(ctx, "position", element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
104 }
106 has_positions = false;
107 remove_attribute_array(ctx, "position");
108 }
109 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)
110 {
111 has_colors = true;
112 set_attribute_array(ctx, "color", element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
113 }
115 has_colors = false;
116 remove_attribute_array(ctx, "color");
117 }
119 {
120 if (!has_indices())
121 return;
122 if (aam_ptr)
123 aam_ptr->remove_indices(ctx);
124 index_buffer_ptr = 0;
125 indices = 0;
126 index_count = 0;
127 index_type = cgv::type::info::TI_UNDEF;
128 }
130 {
131 // validate set attributes
132 if (!has_positions) {
133 ctx.error("renderer::enable() position attribute not set");
134 return false;
135 }
136 return true;
137 }
140 {
141 rs = &_rs;
142 }
143
146 {
147 auto* tmp = rs;
148 rs = &_rs;
151 bool res = build_shader_program(ctx, prog, options);
152 rs = tmp;
153 return res;
154 }
155
158 {
159 if (rs)
160 return rs;
161 if (default_render_style)
162 return default_render_style;
163 default_render_style = create_render_style();
164 return default_render_style;
165 }
168 {
169 prog_ptr = &one_shot_prog;
170 }
171
173 {
174 if (ctx.core_profile) {
175 default_aam.init(ctx);
176 if (!aam_ptr)
177 aam_ptr = &default_aam;
178 }
179
180 if (!default_render_style)
181 default_render_style = create_render_style();
182
183 if (!rs)
184 rs = default_render_style;
185
186 if(prog_ptr == &prog) {
187 update_shader_program_options(prog_options);
188 if(!build_shader_program(ctx, prog, prog_options))
189 return false;
190 last_prog_options = prog_options;
191 }
192 return default_render_style != 0;
193 }
194
197 {
198 if (validate_attributes(ctx))
199 return enable(ctx);
200 return false;
201 }
202
204 {
205 if(prog_ptr == &prog) {
206 update_shader_program_options(prog_options);
207 if(prog_options != last_prog_options) {
208 if(prog.is_created())
209 prog.destruct(ctx);
210 if(!build_shader_program(ctx, prog, prog_options))
211 return false;
212#ifndef _DEBUG
213 }
214#else
215 if(current_prog_render_count < 10)
216 std::cerr << "Performance warning: shader is rebuild! Consider using multiple instances of the renderer." << std::endl;
217 current_prog_render_count = 0;
218 }
219 ++current_prog_render_count;
220#endif
221 last_prog_options = prog_options;
222 }
223 bool res = ref_prog().enable(ctx);
224 if (aam_ptr)
225 res = aam_ptr->enable(ctx);
226 return res;
227 }
228
229 bool renderer::disable(context& ctx)
230 {
231 bool res = true;
232 if (aam_ptr)
233 res = aam_ptr->disable(ctx);
234 if (!has_aam()) {
235 if (ctx.core_profile) {
236 for (int loc : enabled_attribute_arrays)
237 res = default_aam.aab.disable_array(ctx, loc) && res;
238 }
239 else {
240 for (int loc : enabled_attribute_arrays)
241 res = attribute_array_binding::disable_global_array(ctx, loc) && res;
242 }
243 enabled_attribute_arrays.clear();
244 has_colors = false;
245 has_positions = false;
246 index_count = 0;
247 }
248 res = ref_prog().disable(ctx) && res;
249 prog_ptr = &prog;
250 return res;
251 }
252 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)
253 {
254 if (use_strips && has_indices()) {
255 glPrimitiveRestartIndex(strip_restart_index);
256 glEnable(GL_PRIMITIVE_RESTART);
257 }
258 if (type == PT_LINES) {
259 if (use_adjacency)
260 if (use_strips)
261 type = PT_LINE_STRIP_ADJACENCY;
262 else
263 type = PT_LINES_ADJACENCY;
264 else
265 if (use_strips)
266 type = PT_LINE_STRIP;
267 }
268 else if (type == PT_TRIANGLES)
269 if (use_adjacency)
270 if (use_strips)
271 type = PT_TRIANGLE_STRIP_ADJACENCY;
272 else
273 type = PT_TRIANGLES_ADJACENCY;
274 else
275 if (use_strips)
276 type = PT_TRIANGLE_STRIP;
277
278 GLenum pt = gl::map_to_gl(type);
279 if (has_indices()) {
280 bool aam_has_index_buffer = aam_ptr && aam_ptr->has_index_buffer();
281 bool use_index_buffer = index_buffer_ptr && !aam_has_index_buffer;
282 bool use_indices = !index_buffer_ptr && !aam_has_index_buffer;
283 if (use_index_buffer)
284 index_buffer_ptr->bind(ctx, VBT_INDICES);
285 const void* offset = reinterpret_cast<const uint8_t*>(use_indices ? indices : 0)
286 + start * cgv::type::info::get_type_size(index_type);
287 glDrawElements(pt, (GLsizei)count, gl::map_to_gl(index_type), offset);
288 if (use_index_buffer)
289 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
290 }
291 else
292 glDrawArrays(pt, (GLint)start, (GLsizei)count);
293 }
294 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)
295 {
296 if (use_strips && has_indices()) {
297 glPrimitiveRestartIndex(strip_restart_index);
298 glEnable(GL_PRIMITIVE_RESTART);
299 }
300 if (type == PT_LINES) {
301 if (use_adjacency)
302 if (use_strips)
303 type = PT_LINE_STRIP_ADJACENCY;
304 else
305 type = PT_LINES_ADJACENCY;
306 else
307 if (use_strips)
308 type = PT_LINE_STRIP;
309 }
310 else if (type == PT_TRIANGLES)
311 if (use_adjacency)
312 if (use_strips)
313 type = PT_TRIANGLE_STRIP_ADJACENCY;
314 else
315 type = PT_TRIANGLES_ADJACENCY;
316 else
317 if (use_strips)
318 type = PT_TRIANGLE_STRIP;
319
320 GLenum pt = gl::map_to_gl(type);
321 if (has_indices()) {
322 bool aam_has_index_buffer = aam_ptr && aam_ptr->has_index_buffer();
323 bool use_index_buffer = index_buffer_ptr && !aam_has_index_buffer;
324 bool use_indices = !index_buffer_ptr && !aam_has_index_buffer;
325 if (use_index_buffer)
326 index_buffer_ptr->bind(ctx, VBT_INDICES);
327 const void* offset = reinterpret_cast<const uint8_t*>(use_indices ? indices : 0)
328 + start * cgv::type::info::get_type_size(index_type);
329 glDrawElementsInstanced(pt, (GLsizei)count, gl::map_to_gl(index_type), offset, (GLsizei)instance_count);
330 if (use_index_buffer)
331 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
332 }
333 else
334 glDrawArraysInstanced(pt, (GLint)start, (GLsizei)count, (GLsizei)instance_count);
335 }
336 void renderer::draw(context& ctx, size_t start, size_t count,
337 bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
338 {
339 draw_impl(ctx, PT_TRIANGLES, start, count, use_strips, use_adjacency, strip_restart_index);
340 }
341 bool renderer::render(context& ctx, size_t start, size_t count, bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
342 {
343 if (!validate_and_enable(ctx))
344 return false;
345 draw(ctx, start, count, use_strips, use_adjacency, strip_restart_index);
346 return disable(ctx);
347 }
348 void renderer::clear(const cgv::render::context& ctx)
349 {
350 prog.destruct(ctx);
351 }
352 }
353}
354
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:672
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
Definition context.cxx:306
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2188
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:10
void remove_color_array(const context &ctx)
remove the color attribute
Definition renderer.cxx:114
bool has_attribute(const context &ctx, const std::string &name)
check for attribute
Definition renderer.cxx:48
virtual bool enable(context &ctx)
enables renderer
Definition renderer.cxx:203
bool validate_and_enable(context &ctx)
validate attributes and if successful, enable renderer
Definition renderer.cxx:196
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:172
virtual ~renderer()
destructor deletes default renderer style
Definition renderer.cxx:34
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:40
bool build_program(context &ctx, shader_program &prog, const render_style &rs)
build shader program for specific render style
Definition renderer.cxx:145
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:53
void remove_position_array(const context &ctx)
remove the position attribute
Definition renderer.cxx:105
virtual void clear(const context &ctx)
the clear function destructs the shader program
Definition renderer.cxx:348
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:62
const render_style * get_style_ptr() const
access to render style
Definition renderer.cxx:157
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:129
void set_render_style(const render_style &rs)
reference given render style
Definition renderer.cxx:139
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:71
void set_prog(shader_program &one_shot_prog)
set external shader program up to next call to disable() or render()
Definition renderer.cxx:167
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:118
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:279
@ VBT_INDICES
The buffer contains indices and will be bound to GL_ELEMENT_ARRAY_BUFFER.
Definition context.h:473
unsigned int get_type_size(TypeId tid)
function that returns the size of a type specified through TypeId
Definition type_id.cxx:18
the cgv namespace
Definition print.h:11
bool core_profile
default: true
Definition context.h:611
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:59