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 }
50
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 }
55
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 }
64
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 }
141
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 }
169
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
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)
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 }
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...
static bool disable_global_array(const context &ctx, int loc)
disable attribute array of given location
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:670
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
Definition context.cxx:307
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
void draw_impl_instanced(context &ctx, PrimitiveType type, size_t start, size_t count, size_t instance_count, bool use_strips=false, bool use_adjacency=false, uint32_t strip_restart_index=-1)
default implementation of instanced draw method with support for indexed rendering and different prim...
Definition renderer.cxx:297
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
shader_program & ref_prog()
derived renderer classes have access to shader program
Definition renderer.h:129
virtual ~renderer()
destructor deletes default renderer style
Definition renderer.cxx:37
virtual void draw(context &ctx, size_t start, size_t count, bool use_strips=false, bool use_adjacency=false, uint32_t strip_restart_index=-1)
Draw a range of vertices or indexed elements.
Definition renderer.cxx:339
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
bool has_aam() const
check for attribute array manager
Definition renderer.h:112
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
virtual bool render(context &ctx, size_t start, size_t count, bool use_strips=false, bool use_adjacency=false, uint32_t strip_restart_index=-1)
Convenience function that draws vertex or indexed element with this renderer.
Definition renderer.cxx:344
virtual bool disable(context &ctx)
disable renderer
Definition renderer.cxx:232
void draw_impl(context &ctx, PrimitiveType pt, size_t start, size_t count, bool use_strips=false, bool use_adjacency=false, uint32_t strip_restart_index=-1)
default implementation of draw method with support for indexed rendering and different primitive type...
Definition renderer.cxx:255
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
a shader program combines several shader code fragments to a complete definition of the shading pipel...
a vertex buffer is an unstructured memory block on the GPU.
namespace for api independent GPU programming
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:477
unsigned int get_type_size(TypeId tid)
function that returns the size of a type specified through TypeId
Definition type_id.cxx:18
namespace for compile time type information
Definition bool32_t.h:7
this header is dependency free
Definition print.h:11
bool core_profile
default: true
Definition context.h:609
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