cgv
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 // initialize to the threshold count to prevent outputting warnings for the very first render procedure
12 current_prog_render_count = 10;
13 has_colors = false;
14 has_positions = false;
15 rs = default_render_style = 0;
16 aam_ptr = 0;
17 indices = 0;
18 index_buffer_ptr = 0;
19 index_type = cgv::type::info::TI_UNDEF;
20 index_count = 0;
21 prog_ptr = &prog;
22 }
23 void renderer::manage_singleton(context& ctx, const std::string& renderer_name, int& ref_count, int ref_count_change)
24 {
25 switch (ref_count_change) {
26 case 1:
27 if (ref_count == 0) {
28 if (!init(ctx))
29 ctx.error(std::string("unable to initialize ") + renderer_name + " singleton");
30 }
31 ++ref_count;
32 break;
33 case 0:
34 break;
35 case -1:
36 if (ref_count == 0)
37 ctx.error(std::string("attempt to decrease reference count of ") + renderer_name + " singleton below 0");
38 else {
39 if (--ref_count == 0)
40 clear(ctx);
41 }
42 break;
43 default:
44 ctx.error(std::string("invalid change reference count outside {-1,0,1} for ") + renderer_name + " singleton");
45 }
46 }
48 {
49 if (default_render_style)
50 delete default_render_style;
51 default_render_style = 0;
52 }
55 {
56 aam_ptr = &aam;
57 if (has_attribute(ctx, "position"))
58 has_positions = true;
59 if (has_attribute(ctx, "color"))
60 has_colors = true;
61 }
64 {
65 has_positions = false;
66 has_colors = false;
67 if (ctx.core_profile)
68 aam_ptr = &default_aam;
69 else
70 aam_ptr = 0;
71 }
73 {
74 if (_aam_ptr)
75 enable_attribute_array_manager(ctx, *_aam_ptr);
76 else
78 }
79 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)
80 {
81 int loc = get_prog_attribute_location(ctx, name);
82 if(loc < 0)
83 return false;
84 if (aam_ptr)
85 return aam_ptr->set_attribute_array(ctx, loc, element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
86 enabled_attribute_arrays.insert(loc);
87 return attribute_array_binding::set_global_attribute_array(ctx, loc, element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
88 }
89 bool renderer::remove_attribute_array(const context& ctx, const std::string& name)
90 {
91 int loc = get_prog_attribute_location(ctx, name);
92 if(loc < 0)
93 return false;
94 if(aam_ptr) {
95 aam_ptr->remove_attribute_array(ctx, loc);
96 return true;
97 }
98 enabled_attribute_arrays.erase(loc);
99 return true;
100 }
101 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)
102 {
103 has_positions = true;
104 set_attribute_array(ctx, "position", element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
105 }
107 has_positions = false;
108 remove_attribute_array(ctx, "position");
109 }
110 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)
111 {
112 has_colors = true;
113 set_attribute_array(ctx, "color", element_type, vbo, offset_in_bytes, nr_elements, stride_in_bytes);
114 }
116 has_colors = false;
117 remove_attribute_array(ctx, "color");
118 }
120 {
121 if (!has_indices())
122 return;
123 if (aam_ptr)
124 aam_ptr->remove_indices(ctx);
125 index_buffer_ptr = 0;
126 indices = 0;
127 index_count = 0;
128 index_type = cgv::type::info::TI_UNDEF;
129 }
131 {
132 // validate set attributes
133 if (!has_positions) {
134 ctx.error("renderer::enable() position attribute not set");
135 return false;
136 }
137 return true;
138 }
141 {
142 rs = &_rs;
143 }
144
147 {
148 shader_define_map defines;
149 auto* tmp = rs;
150 rs = &_rs;
151 update_defines(defines);
152 bool res = build_shader_program(ctx, prog, defines);
153 rs = tmp;
154 return res;
155 }
156
159 {
160 if (rs)
161 return rs;
162 if (default_render_style)
163 return default_render_style;
164 default_render_style = create_render_style();
165 return default_render_style;
166 }
169 {
170 prog_ptr = &one_shot_prog;
171 }
172
174 {
175 if (ctx.core_profile) {
176 default_aam.init(ctx);
177 if (!aam_ptr)
178 aam_ptr = &default_aam;
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_defines(defines);
188 if (!build_shader_program(ctx, prog, defines))
189 return false;
190 last_defines = defines;
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_defines(defines);
207 if(defines != last_defines) {
208 if(prog.is_created())
209 prog.destruct(ctx);
210 if(!build_shader_program(ctx, prog, defines))
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_defines = defines;
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 (has_aam())
233 res = aam_ptr->disable(ctx);
234 else {
235 if (ctx.core_profile) {
236 default_aam.disable(ctx);
237 for (int loc : enabled_attribute_arrays)
238 res = default_aam.aab.disable_array(ctx, loc) && res;
239 }
240 else {
241 for (int loc : enabled_attribute_arrays)
242 res = attribute_array_binding::disable_global_array(ctx, loc) && res;
243 }
244 enabled_attribute_arrays.clear();
245 has_colors = false;
246 has_positions = false;
247 index_count = 0;
248 }
249 res = ref_prog().disable(ctx) && res;
250 prog_ptr = &prog;
251 return res;
252 }
253 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)
254 {
255 if (use_strips && has_indices()) {
256 glPrimitiveRestartIndex(strip_restart_index);
257 glEnable(GL_PRIMITIVE_RESTART);
258 }
259 if (type == PT_LINES) {
260 if (use_adjacency)
261 if (use_strips)
262 type = PT_LINE_STRIP_ADJACENCY;
263 else
264 type = PT_LINES_ADJACENCY;
265 else
266 if (use_strips)
267 type = PT_LINE_STRIP;
268 }
269 else if (type == PT_TRIANGLES)
270 if (use_adjacency)
271 if (use_strips)
272 type = PT_TRIANGLE_STRIP_ADJACENCY;
273 else
274 type = PT_TRIANGLES_ADJACENCY;
275 else
276 if (use_strips)
277 type = PT_TRIANGLE_STRIP;
278
279 GLenum pt = gl::map_to_gl(type);
280 if (has_indices()) {
281 bool aam_has_index_buffer = aam_ptr && aam_ptr->has_index_buffer();
282 bool use_index_buffer = index_buffer_ptr && !aam_has_index_buffer;
283 bool use_indices = !index_buffer_ptr && !aam_has_index_buffer;
284 if (use_index_buffer)
285 index_buffer_ptr->bind(ctx, VBT_INDICES);
286 const void* offset = reinterpret_cast<const uint8_t*>(use_indices ? indices : 0)
287 + start * cgv::type::info::get_type_size(index_type);
288 glDrawElements(pt, (GLsizei)count, gl::map_to_gl(index_type), offset);
289 if (use_index_buffer)
290 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
291 }
292 else
293 glDrawArrays(pt, (GLint)start, (GLsizei)count);
294 }
295 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)
296 {
297 if (use_strips && has_indices()) {
298 glPrimitiveRestartIndex(strip_restart_index);
299 glEnable(GL_PRIMITIVE_RESTART);
300 }
301 if (type == PT_LINES) {
302 if (use_adjacency)
303 if (use_strips)
304 type = PT_LINE_STRIP_ADJACENCY;
305 else
306 type = PT_LINES_ADJACENCY;
307 else
308 if (use_strips)
309 type = PT_LINE_STRIP;
310 }
311 else if (type == PT_TRIANGLES)
312 if (use_adjacency)
313 if (use_strips)
314 type = PT_TRIANGLE_STRIP_ADJACENCY;
315 else
316 type = PT_TRIANGLES_ADJACENCY;
317 else
318 if (use_strips)
319 type = PT_TRIANGLE_STRIP;
320
321 GLenum pt = gl::map_to_gl(type);
322 if (has_indices()) {
323 bool aam_has_index_buffer = aam_ptr && aam_ptr->has_index_buffer();
324 bool use_index_buffer = index_buffer_ptr && !aam_has_index_buffer;
325 bool use_indices = !index_buffer_ptr && !aam_has_index_buffer;
326 if (use_index_buffer)
327 index_buffer_ptr->bind(ctx, VBT_INDICES);
328 const void* offset = reinterpret_cast<const uint8_t*>(use_indices ? indices : 0)
329 + start * cgv::type::info::get_type_size(index_type);
330 glDrawElementsInstanced(pt, (GLsizei)count, gl::map_to_gl(index_type), offset, (GLsizei)instance_count);
331 if (use_index_buffer)
332 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
333 }
334 else
335 glDrawArraysInstanced(pt, (GLint)start, (GLsizei)count, (GLsizei)instance_count);
336 }
337 void renderer::draw(context& ctx, size_t start, size_t count,
338 bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
339 {
340 draw_impl(ctx, PT_TRIANGLES, start, count, use_strips, use_adjacency, strip_restart_index);
341 }
342 bool renderer::render(context& ctx, size_t start, size_t count, bool use_strips, bool use_adjacency, uint32_t strip_restart_index)
343 {
344 if (!validate_and_enable(ctx))
345 return false;
346 draw(ctx, start, count, use_strips, use_adjacency, strip_restart_index);
347 return disable(ctx);
348 }
349 void renderer::clear(const cgv::render::context& ctx)
350 {
351 prog.destruct(ctx);
352 }
353 }
354}
355
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
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
Definition context.cxx:219
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2046
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:23
void remove_color_array(const context &ctx)
remove the color attribute
Definition renderer.cxx:115
bool has_attribute(const context &ctx, const std::string &name)
check for attribute
Definition renderer.h:60
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 bool init(context &ctx)
call init() once before using renderer
Definition renderer.cxx:173
virtual ~renderer()
destructor deletes default renderer style
Definition renderer.cxx:47
bool build_program(context &ctx, shader_program &prog, const render_style &rs)
build shader program for specific render style
Definition renderer.cxx:146
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:54
void remove_position_array(const context &ctx)
remove the position attribute
Definition renderer.cxx:106
virtual void clear(const context &ctx)
the clear function destructs the shader program
Definition renderer.cxx:349
renderer()
construct and init attribute tracking flags
Definition renderer.cxx:9
bool has_colors
track whether color attribute is defined
Definition renderer.h:83
bool has_positions
track whether position attribute is defined
Definition renderer.h:85
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:63
const render_style * get_style_ptr() const
access to render style
Definition renderer.cxx:158
virtual render_style * create_render_style() const =0
virtual method that creates 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:176
virtual bool validate_attributes(const context &ctx) const
call to validate, whether essential position attribute is defined
Definition renderer.cxx:130
void set_render_style(const render_style &rs)
reference given render style
Definition renderer.cxx:140
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:192
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:72
void set_prog(shader_program &one_shot_prog)
set external shader program up to next call to disable() or render()
Definition renderer.cxx:168
bool has_indices() const
return whether indices have been defined
Definition renderer.h:266
virtual bool build_shader_program(context &ctx, shader_program &prog, const shader_define_map &defines)
overload to build shader program based on the passed defines
Definition renderer.h:70
void remove_indices(const context &ctx)
remove previously set indices
Definition renderer.cxx:119
virtual void update_defines(shader_define_map &defines)
overload to update the shader defines based on the current render style; only called if internal shad...
Definition renderer.h:68
a shader program combines several shader code fragments to a complete definition of the shading pipel...
void destruct(const context &ctx)
destruct shader program
a vertex buffer is an unstructured memory block on the GPU.
std::map< std::string, std::string > shader_define_map
typedef for shader define map data structure
Definition shader_code.h:52
PrimitiveType
different primitive types
Definition context.h:225
@ VBT_INDICES
The buffer contains indices and will be bound to GL_ELEMENT_ARRAY_BUFFER.
Definition context.h:417
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:560
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:47