cgv
Loading...
Searching...
No Matches
render_info.cxx
1#include <cgv/base/base.h>
2#include "render_info.h"
3#include <cgv_gl/gl/gl.h>
4#include <cgv_gl/gl/gl_tools.h>
5#include <cgv_gl/gl/gl_context.h>
6
7namespace cgv {
8 namespace render {
9
10void attribute_array::add_attribute(type_descriptor element_type, uint32_t vbo_index,
11 size_t byte_offset, size_t element_count, uint32_t stride,
12 VertexAttributeID vertex_attribute_id, std::string name)
13{
15 va.byte_offset = byte_offset;
16 va.element_count = element_count;
17 va.element_type = element_type;
18 va.stride = stride;
19 va.vbo_index = vbo_index;
20 va.vertex_attribute_id = vertex_attribute_id;
21 if (vertex_attribute_id == cgv::render::VA_BY_NAME)
22 va.name = name;
23 vas.push_back(va);
24}
25
27void render_info::draw(context& ctx, const draw_call& dc, const draw_call* prev_dc, const draw_call* next_dc, bool use_materials)
28{
29 // ensure program is enabled
30 bool new_prog = true;
31 if (prev_dc && prev_dc->prog == dc.prog)
32 new_prog = false;
33 bool prog_enabled = false;
34 if (new_prog && dc.prog && ctx.get_current_program() != dc.prog) {
35 dc.prog->enable(ctx);
36 prog_enabled = true;
37 }
38 if ((dc.alpha_mode & AM_MASK) != 0) {
39 dc.prog->set_uniform(ctx, "alpha_test", true);
40 dc.prog->set_uniform(ctx, "alpha_cutoff", dc.alpha_cutoff);
41 }
42 bool blend;
43 GLenum blend_src, blend_dst;
44 if ((dc.alpha_mode & AM_BLEND) != 0) {
45 blend = glIsEnabled(GL_BLEND);
46 glGetIntegerv(GL_BLEND_DST, reinterpret_cast<GLint*>(&blend_dst));
47 glGetIntegerv(GL_BLEND_SRC, reinterpret_cast<GLint*>(&blend_src));
48 glEnable(GL_BLEND);
49 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
50 }
51
52 // ensure material is enabled
53 bool new_material = true;
54 if (prev_dc && prev_dc->material_index == dc.material_index)
55 new_material = false;
56 if (new_prog || (new_material && dc.material_index >= 0 && dc.material_index < materials.size())) {
57 if (dc.material_index != -1 && use_materials)
58 ctx.enable_material(*materials[dc.material_index]);
59 else {
60 if (ctx.get_current_material())
62 }
63 }
64
65 // ensure aab is enabled
66 bool new_aab = true;
67 if (prev_dc && prev_dc->aa_index == dc.aa_index)
68 new_aab = false;
69 if (new_aab && dc.aa_index >= 0 && dc.aa_index < aas.size())
70 aas[dc.aa_index].aab_ptr->enable(ctx);
71
72 // perform render call
73 GLuint pt = gl::map_to_gl(dc.primitive_type);
74 switch (dc.draw_call_type) {
75 case RCT_ARRAYS:
76 glDrawArrays(pt, dc.vertex_offset, dc.count);
77 break;
78 case RCT_INDEXED:
79 glDrawElements(pt, dc.count, gl::map_to_gl(dc.index_type), dc.indices);
80 break;
81 case RCT_ARRAYS_INSTANCED:
82 glDrawArraysInstanced(pt, dc.vertex_offset, dc.count, dc.instance_count);
83 break;
84 case RCT_INDEXED_INSTANCED:
85 glDrawElementsInstanced(pt, dc.count, gl::map_to_gl(dc.index_type), dc.indices, dc.instance_count);
86 break;
87 }
88
89 // disable aab
90 if (!next_dc || next_dc->aa_index != dc.aa_index)
91 aas[dc.aa_index].aab_ptr->disable(ctx);
92
93 // disable material
94 if (dc.material_index != -1 && (!next_dc || next_dc->material_index != dc.material_index))
95 ctx.disable_material(*materials[dc.material_index]);
96
97 // disable program
98 if ((!next_dc || next_dc->prog != dc.prog) && prog_enabled)
99 dc.prog->disable(ctx);
100
101 if ((dc.alpha_mode & AM_BLEND) != 0) {
102 if (!blend)
103 glDisable(GL_BLEND);
104 glBlendFunc(blend_src, blend_dst);
105 }
106 if ((dc.alpha_mode & AM_MASK) != 0)
107 dc.prog->set_uniform(ctx, "alpha_test", false);
108}
109
115
117const std::vector<textured_material*>& render_info::get_materials() const
118{
119 return materials;
120}
121
123const std::vector<vertex_buffer*>& render_info::get_vbos() const
124{
125 return vbos;
126}
127
129const std::vector<attribute_array>& render_info::get_aas() const
130{
131 return aas;
132}
134const std::vector<texture*>& render_info::get_textures() const
135{
136 return textures;
137}
138
140const std::vector<draw_call>& render_info::get_draw_calls() const
141{
142 return draw_calls;
143}
144
146std::vector<textured_material*>& render_info::ref_materials()
147{
148 return materials;
149}
150
152std::vector<vertex_buffer*>& render_info::ref_vbos()
153{
154 return vbos;
155}
156
158std::vector<attribute_array>& render_info::ref_aas()
159{
160 return aas;
161}
163std::vector<texture*>& render_info::ref_textures()
164{
165 return textures;
166}
167
169std::vector<draw_call>& render_info::ref_draw_calls()
170{
171 return draw_calls;
172}
173
175bool render_info::bind(context& ctx, shader_program& prog, bool force_success, int aa_index)
176{
177 int begin = std::max(0, aa_index);
178 int end = aa_index == -1 ? (int)ref_aas().size() : aa_index + 1;
179 int ai;
180 bool success = true;
181 std::vector<int> locs;
182 for (ai = begin; ai < end; ++ai) {
183 attribute_array& aa = ref_aas()[ai];
184
185 // first check whether attributes are available in program
186 for (const auto& va : aa.vas) {
187 int loc = -1;
188 switch (va.vertex_attribute_id) {
189 case VA_POSITION: loc = prog.get_position_index(); break;
190 case VA_NORMAL: loc = prog.get_normal_index(); break;
191 case VA_TEXCOORD: loc = prog.get_texcoord_index(); break;
192 case VA_COLOR: loc = prog.get_color_index(); break;
193 default: loc = prog.get_attribute_location(ctx, va.name); break;
194 }
195 if (loc == -1) {
196 success = false;
197 if (!force_success)
198 return false;
199 }
200 locs.push_back(loc);
201 }
202 }
203 int li = 0;
204 for (ai = begin; ai < end; ++ai) {
205 attribute_array& aa = ref_aas()[ai];
206 // disable all attribute arrays
207 for (int i=0; i<16; ++i)
208 aa.aab_ptr->disable_array(ctx, i);
209
210 for (const auto& va : aa.vas) {
211 if (locs[li] == -1) {
212 ++li;
213 continue;
214 }
215 aa.aab_ptr->set_attribute_array(ctx, locs[li], va.element_type,
216 *ref_vbos()[va.vbo_index], va.byte_offset,
217 va.element_count, va.stride);
218 ++li;
219 }
220 aa.prog = &prog;
221 }
222 for (auto& dc : ref_draw_calls()) {
223 if (aa_index == -1 || dc.aa_index == aa_index)
224 dc.prog = &prog;
225 }
226 return success;
227}
228
230void render_info::draw_all(context& ctx, bool skip_opaque, bool skip_blended, bool use_materials)
231{
232 // extract indices of to be drawn calls
233 std::vector<size_t> dcis;
234 size_t dci = 0;
235 while (dci < draw_calls.size()) {
236 if (skip_opaque)
237 while (dci < draw_calls.size() && (draw_calls[dci].alpha_mode & AM_BLEND) == 0)
238 ++dci;
239 if (skip_blended)
240 while (dci < draw_calls.size() && (draw_calls[dci].alpha_mode & AM_BLEND) != 0)
241 ++dci;
242 if (dci >= draw_calls.size())
243 break;
244 dcis.push_back(dci);
245 ++dci;
246 }
247 // draw extracted calls
248 draw_call* prev_dc = 0;
249 for (size_t i = 0; i < dcis.size(); ++i) {
250 draw_call* next_dc = i + 1 < dcis.size() ? &draw_calls[dcis[i + 1]] : 0;
251 draw(ctx, draw_calls[dcis[i]], prev_dc, next_dc, use_materials);
252 prev_dc = &draw_calls[dcis[i]];
253 }
254}
255
258{
259 // destruct textures
260 for (auto& t : textures) {
261 t->destruct(ctx);
262 delete t;
263 t = 0;
264 }
265 textures.clear();
266
267 // destruct materials
268 for (auto& m : materials) {
269 delete m;
270 m = 0;
271 }
272 materials.clear();
273
274 // destruct aabs
275 for (auto& aa : aas) {
276 aa.aab_ptr->destruct(ctx);
277 delete aa.aab_ptr;
278 aa.aab_ptr = 0;
279 }
280 aas.clear();
281
282 // destruct vbos
283 for (auto& v : vbos) {
284 v->destruct(ctx);
285 delete v;
286 v = 0;
287 }
288 vbos.clear();
289 draw_calls.clear();
290}
291
292
293 }
294}
bool disable_array(const context &ctx, int loc)
disable array for attribute at location loc
bool set_attribute_array(const context &ctx, int loc, const T &array)
set vertex attribute location to given array and enable array
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
shader_program_base * get_current_program() const
check for current program, prepare it for rendering and return pointer to it
Definition context.cxx:440
const cgv::media::illum::surface_material * get_current_material() const
return pointer to current material or nullptr if no current material is available
Definition context.cxx:1605
virtual void set_material(const cgv::media::illum::surface_material &mat)
set the current material
Definition context.cxx:1632
std::vector< texture * > textures
store textures
Definition render_info.h:84
std::vector< vertex_buffer * > & ref_vbos()
give write access to vbos
std::vector< textured_material * > materials
store materials
Definition render_info.h:82
std::vector< texture * > & ref_textures()
give write access to texture
const std::vector< vertex_buffer * > & get_vbos() const
give read access to vbos
virtual bool bind(context &ctx, shader_program &prog, bool force_success, int aa_index=-1)
bind all or specific aa to the passed shader program
std::vector< textured_material * > & ref_materials()
give write access to materials
std::vector< draw_call > & ref_draw_calls()
give write access to draw calls
std::vector< attribute_array > & ref_aas()
give write access to aabs
std::vector< vertex_buffer * > vbos
store buffers
Definition render_info.h:86
std::vector< attribute_array > aas
store attribute bindings
Definition render_info.h:88
const std::vector< textured_material * > & get_materials() const
give read access to materials
const std::vector< draw_call > & get_draw_calls() const
give read access to draw calls
render_info()
set vbo and vbe types
void destruct(cgv::render::context &ctx)
destruct render mesh info and free vertex buffer objects
std::vector< draw_call > draw_calls
store vector of render calls
Definition render_info.h:90
const std::vector< attribute_array > & get_aas() const
give read access to aabs
void draw_all(context &ctx, bool skip_opaque=false, bool skip_blended=false, bool use_materials=true)
execute all draw calls
void draw(context &ctx, const draw_call &dc, const draw_call *prev_dc=0, const draw_call *next_dc=0, bool use_materials=true)
perform a single render call
const std::vector< texture * > & get_textures() const
give read access to texture
a shader program combines several shader code fragments to a complete definition of the shading pipel...
bool enable(context &ctx)
enable the shader program
bool disable(context &ctx)
disable shader program and restore fixed functionality
bool set_uniform(const context &ctx, const std::string &name, const T &value, bool generate_error=false)
Set the value of a uniform by name, where the type can be any of int, unsigned, float,...
int get_attribute_location(const context &ctx, const std::string &name) const
query location index of an attribute
the cgv namespace
Definition print.h:11