1 | #include <iostream> |
2 | #include <sstream> |
3 | #include <fstream> |
4 | #include <bitset> |
5 | |
6 | #include <fastuidraw/util/util.hpp> |
7 | #include <fastuidraw/painter/painter.hpp> |
8 | #include <fastuidraw/painter/backend/painter_header.hpp> |
9 | #include <fastuidraw/painter/backend/painter_item_matrix.hpp> |
10 | #include <fastuidraw/painter/backend/painter_clip_equations.hpp> |
11 | #include <fastuidraw/painter/attribute_data/stroked_point.hpp> |
12 | #include <fastuidraw/painter/attribute_data/arc_stroked_point.hpp> |
13 | |
14 | #include "sdl_painter_demo.hpp" |
15 | |
16 | using namespace fastuidraw; |
17 | |
18 | typedef std::bitset<32> bitset; |
19 | |
20 | c_string |
21 | shader_extension(GLenum shader_type) |
22 | { |
23 | switch (shader_type) |
24 | { |
25 | case GL_FRAGMENT_SHADER: return "frag" ; |
26 | case GL_VERTEX_SHADER: return "vert" ; |
27 | case GL_GEOMETRY_SHADER: return "geom" ; |
28 | case GL_TESS_CONTROL_SHADER: return "tesc" ; |
29 | case GL_TESS_EVALUATION_SHADER: return "tese" ; |
30 | case GL_COMPUTE_SHADER: return "comp" ; |
31 | default: return "unknown" ; |
32 | } |
33 | } |
34 | |
35 | c_string |
36 | label_sampler_type(GLenum type) |
37 | { |
38 | #define EASY(X) case X: return #X |
39 | |
40 | #ifndef FASTUIDRAW_GL_USE_GLES |
41 | #define SUFFIX_1D(X) \ |
42 | EASY(X##1D_ARRAY); \ |
43 | EASY(X##1D); \ |
44 | EASY(X##2D_RECT); |
45 | #else |
46 | #define SUFFIX_1D(X) ; |
47 | #endif |
48 | |
49 | #define SUFFIX_MS(X) \ |
50 | EASY(X##2D_MULTISAMPLE); \ |
51 | EASY(X##2D_MULTISAMPLE_ARRAY); |
52 | |
53 | #define SUFFIX(X) \ |
54 | SUFFIX_1D(X); \ |
55 | EASY(X##2D); \ |
56 | EASY(X##3D); \ |
57 | EASY(X##CUBE); \ |
58 | EASY(X##2D_ARRAY); \ |
59 | EASY(X##BUFFER); |
60 | |
61 | #define PREFIX(X) \ |
62 | SUFFIX(GL_##X##_); \ |
63 | SUFFIX(GL_INT_##X##_); \ |
64 | SUFFIX(GL_UNSIGNED_INT_##X##_); \ |
65 | |
66 | #define PREFIX_MS(X) \ |
67 | SUFFIX_MS(GL_##X##_); \ |
68 | SUFFIX_MS(GL_INT_##X##_); \ |
69 | SUFFIX_MS(GL_UNSIGNED_INT_##X##_); \ |
70 | |
71 | switch(type) |
72 | { |
73 | PREFIX(SAMPLER); |
74 | PREFIX_MS(SAMPLER); |
75 | PREFIX(IMAGE); |
76 | #ifndef FASTUIDRAW_GL_USE_GLES |
77 | PREFIX_MS(IMAGE); |
78 | #endif |
79 | } |
80 | |
81 | return nullptr; |
82 | |
83 | #undef PREFIX_MS |
84 | #undef SUFFIX_MS |
85 | #undef PREFIX |
86 | #undef SUFFIX |
87 | #undef SUFFIX_1D |
88 | #undef EASY |
89 | } |
90 | |
91 | class painter_test:public sdl_painter_demo |
92 | { |
93 | public: |
94 | painter_test(void): |
95 | sdl_painter_demo("" , true) |
96 | {} |
97 | |
98 | protected: |
99 | |
100 | void |
101 | log_helper(const reference_counted_ptr<gl::Program> &pr, |
102 | c_string prefix_1, c_string prefix_2, GLenum shader_type) |
103 | { |
104 | unsigned int cnt; |
105 | c_string label; |
106 | |
107 | cnt = pr->num_shaders(shader_type); |
108 | if (cnt == 0) |
109 | { |
110 | return; |
111 | } |
112 | |
113 | label = gl::Shader::gl_shader_type_label(shader_type); |
114 | std::cout << label << "'s written to:\n" ; |
115 | |
116 | for(unsigned int i = 0; i < cnt; ++i) |
117 | { |
118 | std::ostringstream name, name_glsl, name_log; |
119 | |
120 | name << "painter." << prefix_1 << "." ; |
121 | if (prefix_2) |
122 | { |
123 | name << prefix_2 << "." ; |
124 | } |
125 | name << i << "." << shader_extension(shader_type); |
126 | name_glsl << name.str() << ".glsl" ; |
127 | name_log << name.str() << ".log" ; |
128 | |
129 | std::ofstream file(name_glsl.str().c_str()); |
130 | file << pr->shader_src_code(shader_type, i); |
131 | std::cout << "\tSource #" << i << ":" << name.str() << "\n" ; |
132 | |
133 | std::ofstream file_log(name_log.str().c_str()); |
134 | file_log << pr->shader_compile_log(shader_type, i); |
135 | std::cout << "\tCompile Log #" << i << ":" << name_log.str() << "\n" ; |
136 | } |
137 | } |
138 | |
139 | void |
140 | log_program(const reference_counted_ptr<gl::Program> &pr, |
141 | c_string prefix_1, c_string prefix_2) |
142 | { |
143 | if (!pr) |
144 | { |
145 | return; |
146 | } |
147 | else |
148 | { |
149 | std::ostringstream name; |
150 | |
151 | name << "painter." << prefix_1; |
152 | if (prefix_2) |
153 | { |
154 | name << "." << prefix_2; |
155 | } |
156 | name << ".program.log" ; |
157 | |
158 | std::ofstream file(name.str().c_str()); |
159 | |
160 | file << pr->log(); |
161 | |
162 | /* query the program for the values of all texture types */ |
163 | if (pr->link_success()) |
164 | { |
165 | pr->use_program(); |
166 | gl::Program::block_info default_block(pr->default_uniform_block()); |
167 | for (unsigned int v = 0, endv = default_block.number_variables(); v < endv; ++v) |
168 | { |
169 | gl::Program::shader_variable_info sh(default_block.variable(v)); |
170 | const char *sampler_type; |
171 | |
172 | sampler_type = label_sampler_type(sh.glsl_type()); |
173 | if (sampler_type) |
174 | { |
175 | file << sh.name() << " of type " << sampler_type << "\n" ; |
176 | for (unsigned c = 0, endc = sh.count(); c < endc; ++c) |
177 | { |
178 | GLint value; |
179 | fastuidraw_glGetUniformiv(pr->name(), sh.location(c), &value); |
180 | file << "\t[" << c << "] bound at " << value << " binding point\n" ; |
181 | } |
182 | } |
183 | } |
184 | } |
185 | |
186 | std::cout << "\n\nProgram Log and contents written to " |
187 | << name.str() << "\n" ; |
188 | } |
189 | |
190 | log_helper(pr, prefix_1, prefix_2, GL_VERTEX_SHADER); |
191 | log_helper(pr, prefix_1, prefix_2, GL_FRAGMENT_SHADER); |
192 | log_helper(pr, prefix_1, prefix_2, GL_GEOMETRY_SHADER); |
193 | log_helper(pr, prefix_1, prefix_2, GL_TESS_EVALUATION_SHADER); |
194 | log_helper(pr, prefix_1, prefix_2, GL_TESS_CONTROL_SHADER); |
195 | |
196 | if (pr->link_success()) |
197 | { |
198 | std::cout << "Link success\n" ; |
199 | pr->use_program(); |
200 | } |
201 | else |
202 | { |
203 | std::cout << "Link Failed\n" ; |
204 | } |
205 | } |
206 | |
207 | void |
208 | derived_init(int, int) |
209 | { |
210 | fastuidraw::c_string program_labels[gl::PainterEngineGL::number_program_types] = |
211 | { |
212 | [gl::PainterEngineGL::program_all] = "program_all" , |
213 | [gl::PainterEngineGL::program_without_discard] = "program_without_discard" , |
214 | [gl::PainterEngineGL::program_with_discard] = "program_with_discard" , |
215 | }; |
216 | |
217 | fastuidraw::c_string blend_labels[PainterBlendShader::number_types] = |
218 | { |
219 | [PainterBlendShader::single_src] = "single_src" , |
220 | [PainterBlendShader::dual_src] = "dual_src" , |
221 | [PainterBlendShader::framebuffer_fetch] = "framebuffer_fetch" , |
222 | }; |
223 | |
224 | for (int pr = 0; pr < gl::PainterEngineGL::number_program_types; ++pr) |
225 | { |
226 | for (int b = 0; b < PainterBlendShader::number_types; ++b) |
227 | { |
228 | reference_counted_ptr<gl::Program> program; |
229 | program = m_backend->program(static_cast<enum gl::PainterEngineGL::program_type_t>(pr), |
230 | static_cast<enum PainterBlendShader::shader_type>(b)); |
231 | log_program(program, program_labels[pr], blend_labels[b]); |
232 | } |
233 | } |
234 | log_program(m_backend->program_deferred_coverage_buffer(), "deferred_coverage_buffer" , nullptr); |
235 | |
236 | std::cout << "\nUseful command to see shader after pre-processor:\n" |
237 | << "\tsed 's/#version/@version/g' file.glsl | sed 's/#extension/@extension/g'" |
238 | << " | cpp | grep -v \"#\" | sed '/^\\s*$/d'" |
239 | << " | sed 's/@version/#version/g' | sed 's/@extension/#extension/g'\n" ; |
240 | } |
241 | |
242 | void |
243 | draw_frame(void) |
244 | { |
245 | end_demo(0); |
246 | } |
247 | |
248 | void |
249 | handle_event(const SDL_Event &ev) |
250 | { |
251 | switch(ev.type) |
252 | { |
253 | case SDL_QUIT: |
254 | end_demo(0); |
255 | break; |
256 | |
257 | case SDL_KEYUP: |
258 | switch(ev.key.keysym.sym) |
259 | { |
260 | case SDLK_ESCAPE: |
261 | end_demo(0); |
262 | break; |
263 | } |
264 | break; |
265 | }; |
266 | } |
267 | |
268 | private: |
269 | |
270 | }; |
271 | |
272 | int |
273 | main(int argc, char **argv) |
274 | { |
275 | FASTUIDRAWassert(StrokedPoint::number_offset_types < FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS(StrokedPoint::offset_type_num_bits)); |
276 | std::cout << std::setw(45) << "header_size = " << PainterHeader::header_size << "\n" |
277 | << std::setw(45) << "clip_equations_data_size = " << PainterClipEquations::clip_data_size << "\n" |
278 | << std::setw(45) << "item_matrix_data_size = " << PainterItemMatrix::matrix_data_size << "\n" |
279 | << std::setw(45) << "brush image_data_size = " << PainterImageBrushShaderData::shader_data_size << "\n" |
280 | << std::setw(45) << "brush repeat_window_data_size = " << PainterBrush::repeat_window_data_size << "\n" |
281 | << std::setw(45) << "brush transformation_matrix_data_size = " << PainterBrush::transformation_matrix_data_size << "\n" |
282 | << std::setw(45) << "brush transformation_translation_data_size = " << PainterBrush::transformation_translation_data_size << "\n" |
283 | << "\n" |
284 | |
285 | << std::setw(45) << "brush image_mask = " << bitset(PainterBrush::image_mask) << "\n" |
286 | << std::setw(45) << "brush image_mipmap_mask = " << bitset(PainterImageBrushShader::mipmap_mask << PainterBrush::image_bit0) << "\n" |
287 | << std::setw(45) << "brush gradient_mask = " << bitset(PainterBrush::gradient_mask) << "\n" |
288 | << std::setw(45) << "brush repeat_window_mask = " << bitset(PainterBrush::repeat_window_mask) << "\n" |
289 | << std::setw(45) << "brush repeat_window_x_spread_type_mask = " << bitset(PainterBrush::repeat_window_x_spread_type_mask) << "\n" |
290 | << std::setw(45) << "brush repeat_window_y_spread_type_mask = " << bitset(PainterBrush::repeat_window_y_spread_type_mask) << "\n" |
291 | << std::setw(45) << "brush transformation_translation_mask = " << bitset(PainterBrush::transformation_translation_mask) << "\n" |
292 | << std::setw(45) << "brush transformation_matrix_mask = " << bitset(PainterBrush::transformation_matrix_mask) << "\n" |
293 | << std::setw(45) << "brush image_type_mask = " << bitset(PainterImageBrushShader::type_mask << PainterBrush::image_bit0) << "\n" |
294 | << std::setw(45) << "brush image_format_mask = " << bitset(PainterImageBrushShader::format_mask << PainterBrush::image_bit0) << "\n" |
295 | << std::setw(45) << "brush number_feature_bits = " << PainterBrush::number_feature_bits << "\n" |
296 | |
297 | << std::setw(45) << "stroked_number_offset_types = " << StrokedPoint::number_offset_types << "\n" |
298 | << std::setw(45) << "stroked_offset_type_bit0 = " << StrokedPoint::offset_type_bit0 << "\n" |
299 | << std::setw(45) << "stroked_offset_type_num_bits = " << StrokedPoint::offset_type_num_bits << "\n" |
300 | << std::setw(45) << "stroked_boundary_bit = " << StrokedPoint::boundary_bit << "\n" |
301 | << std::setw(45) << "stroked_depth_bit0 = " << StrokedPoint::depth_bit0 << "\n" |
302 | << std::setw(45) << "stroked_depth_num_bits = " << StrokedPoint::depth_num_bits << "\n" |
303 | << std::setw(45) << "stroked_join_bit = " << StrokedPoint::join_bit << "\n" |
304 | << std::setw(45) << "stroked_number_common_bits = " << StrokedPoint::number_common_bits << "\n" |
305 | << std::setw(45) << "stroked_normal0_y_sign_bit = " << StrokedPoint::normal0_y_sign_bit << "\n" |
306 | << std::setw(45) << "stroked_normal1_y_sign_bit = " << StrokedPoint::normal1_y_sign_bit << "\n" |
307 | << std::setw(45) << "stroked_sin_sign_bit = " << StrokedPoint::sin_sign_bit << "\n" |
308 | << std::setw(45) << "stroked_adjustable_cap_ending_bit = " << StrokedPoint::adjustable_cap_ending_bit << "\n" |
309 | << std::setw(45) << "stroked_bevel_edge_bit = " << StrokedPoint::bevel_edge_bit << "\n" ; |
310 | |
311 | painter_test P; |
312 | return P.main(argc, argv); |
313 | |
314 | } |
315 | |