… | |
… | |
232 | struct lvalue_i : fragment_i |
232 | struct lvalue_i : fragment_i |
233 | { |
233 | { |
234 | }; |
234 | }; |
235 | |
235 | |
236 | // a simple predeclared variable with unspecified type |
236 | // a simple predeclared variable with unspecified type |
237 | struct glvar_i : lvalue_i |
237 | struct gluvar_i : lvalue_i |
238 | { |
238 | { |
239 | const char *name; |
239 | const char *name; |
240 | void build (shader_builder &b); |
240 | void build (shader_builder &b); |
241 | glvar_i (const char *name) : name (name) { } |
241 | gluvar_i (const char *name) : name (name) { } |
242 | }; |
242 | }; |
243 | |
243 | |
244 | typedef auto_lvalue_ref1<glvar_i, const char *> glvar; |
244 | typedef auto_lvalue_ref1<gluvar_i, const char *> gluvar; |
245 | |
245 | |
246 | struct var_i : lvalue_i |
246 | struct var_i : lvalue_i |
247 | { |
247 | { |
248 | static unsigned int next_id; |
248 | static unsigned int next_id; |
249 | |
249 | |
… | |
… | |
258 | }; |
258 | }; |
259 | |
259 | |
260 | struct uniform_i : var_i |
260 | struct uniform_i : var_i |
261 | { |
261 | { |
262 | bool dirty; |
262 | bool dirty; |
|
|
263 | GLint location; |
263 | |
264 | |
264 | virtual void update () = 0; |
265 | virtual void update () = 0; |
265 | |
266 | |
266 | void build (shader_builder &b); |
267 | void build (shader_builder &b); |
267 | void build_decl (ostringstream &b); |
268 | void build_decl (ostringstream &b); |
|
|
269 | |
|
|
270 | void update_location (GLint program) |
|
|
271 | { |
|
|
272 | location = glGetUniformLocationARB (program, name); |
|
|
273 | } |
|
|
274 | |
268 | uniform_i (const char *strtype); |
275 | uniform_i (const char *strtype); |
269 | }; |
276 | }; |
270 | |
277 | |
271 | template<int dimension, typename gltype, const char *strtype, void (*upd)(CGparameter, const gltype *)> |
278 | template<int dimension, typename gltype, const char *strtype, void (*upd)(GLint, GLsizei, const gltype *)> |
272 | struct uniform2_i : uniform_i |
279 | struct uniform2_i : uniform_i |
273 | { |
280 | { |
274 | gltype data[dimension]; |
281 | gltype data[dimension]; |
275 | |
282 | |
276 | void update () |
283 | void update () |
277 | { |
284 | { |
278 | if (dirty) |
285 | if (dirty) |
279 | { |
286 | { |
280 | //upd (param, data); |
287 | if (location >= 0) |
|
|
288 | upd (location, dimension, data); |
|
|
289 | |
281 | dirty = false; |
290 | dirty = false; |
282 | } |
291 | } |
283 | } |
292 | } |
284 | |
293 | |
285 | uniform2_i () : uniform_i (strtype) { } |
294 | uniform2_i () : uniform_i (strtype) { } |
286 | }; |
295 | }; |
287 | |
296 | |
288 | template<int dimension, const char *strtype, void (*update)(CGparameter, const GLfloat *)> |
297 | template<int dimension, const char *strtype, void (*update)(GLint, GLsizei, const GLfloat *)> |
289 | struct uniform_f_i : uniform2_i<dimension, GLfloat, strtype, update> |
298 | struct uniform_f_i : uniform2_i<dimension, GLfloat, strtype, update> |
290 | { |
299 | { |
291 | }; |
300 | }; |
292 | |
301 | |
293 | struct uniform_1f_i : uniform_f_i<1, str_float, cgGLSetParameter1fv> { |
302 | struct uniform_1f_i : uniform_f_i<1, str_float, glUniform1fvARB> { |
294 | void operator =(GLfloat v) |
303 | void operator =(GLfloat v) |
295 | { |
304 | { |
296 | data[0] = v; |
305 | data[0] = v; |
297 | dirty = true; |
306 | dirty = true; |
298 | } |
307 | } |
299 | }; |
308 | }; |
300 | |
309 | |
301 | struct uniform_2f_i : uniform_f_i<2, str_vec2, cgGLSetParameter2fv> { }; |
310 | struct uniform_2f_i : uniform_f_i<2, str_vec2, glUniform2fvARB> { }; |
302 | |
311 | |
303 | struct uniform_3f_i : uniform_f_i<3, str_vec3, cgGLSetParameter3fv> { |
312 | struct uniform_3f_i : uniform_f_i<3, str_vec3, glUniform3fvARB> { |
304 | void operator =(const vec3 &v) |
313 | void operator =(const vec3 &v) |
305 | { |
314 | { |
306 | data[0] = v.x; |
315 | data[0] = v.x; |
307 | data[1] = v.y; |
316 | data[1] = v.y; |
308 | data[2] = v.z; |
317 | data[2] = v.z; |
309 | dirty = true; |
318 | dirty = true; |
310 | } |
319 | } |
311 | }; |
320 | }; |
312 | |
321 | |
313 | struct uniform_4f_i : uniform_f_i<4, str_vec4, cgGLSetParameter4fv> { |
322 | struct uniform_4f_i : uniform_f_i<4, str_vec4, glUniform4fvARB> { |
314 | #if 0 |
323 | #if 0 |
315 | void operator =(const gl::matrix &m) |
324 | void operator =(const gl::matrix &m) |
316 | { |
325 | { |
317 | memcpy (data, m.data, 16 * sizeof (GLfloat)); |
326 | memcpy (data, m.data, 16 * sizeof (GLfloat)); |
318 | dirty = true; |
327 | dirty = true; |
319 | } |
328 | } |
320 | #endif |
329 | #endif |
321 | }; |
330 | }; |
322 | |
331 | |
|
|
332 | inline void UniformMatrix2fv (GLint l, GLsizei s, const GLfloat *m) { glUniformMatrix2fvARB (l, s, 0, m); } |
|
|
333 | inline void UniformMatrix3fv (GLint l, GLsizei s, const GLfloat *m) { glUniformMatrix3fvARB (l, s, 0, m); } |
|
|
334 | inline void UniformMatrix4fv (GLint l, GLsizei s, const GLfloat *m) { glUniformMatrix4fvARB (l, s, 0, m); } |
|
|
335 | |
323 | struct uniform_matrix_2f_i : uniform_f_i< 4, str_mat2, cgGLSetMatrixParameterfc> { }; |
336 | struct uniform_matrix_2f_i : uniform_f_i< 4, str_mat2, UniformMatrix2fv> { }; |
324 | struct uniform_matrix_3f_i : uniform_f_i< 9, str_mat3, cgGLSetMatrixParameterfc> { }; |
337 | struct uniform_matrix_3f_i : uniform_f_i< 9, str_mat3, UniformMatrix3fv> { }; |
325 | struct uniform_matrix_4f_i : uniform_f_i<16, str_mat4, cgGLSetMatrixParameterfc> { }; |
338 | struct uniform_matrix_4f_i : uniform_f_i<16, str_mat4, UniformMatrix4fv> { }; |
326 | |
339 | |
327 | template<class var_i> |
340 | template<class var_i> |
328 | struct var_ref : ref<var_i> |
341 | struct var_ref : ref<var_i> |
329 | { |
342 | { |
330 | var_ref (const char *glname = 0) |
343 | var_ref (const char *glname = 0) |
… | |
… | |
417 | temp_ref () |
430 | temp_ref () |
418 | : ref<temporary_i> (*new temporary_i (strtype)) |
431 | : ref<temporary_i> (*new temporary_i (strtype)) |
419 | { |
432 | { |
420 | } |
433 | } |
421 | |
434 | |
|
|
435 | #if 0 |
|
|
436 | template<typename expr> |
|
|
437 | temp_ref (const expr &e) |
|
|
438 | : ref<temporary_i> (*new temporary_i (strtype)) |
|
|
439 | { |
|
|
440 | (*this) = e; |
|
|
441 | } |
|
|
442 | #endif |
|
|
443 | |
422 | template<typename expr> |
444 | template<typename expr> |
423 | const temp_ref &operator =(const expr &e) const; |
445 | const temp_ref &operator =(const expr &e) const; |
424 | }; |
446 | }; |
425 | |
447 | |
426 | typedef temp_ref<str_float> temp_1f; |
448 | typedef temp_ref<str_float> temp_1f; |
… | |
… | |
432 | typedef temp_ref<str_mat4> temp_matrix_4f; |
454 | typedef temp_ref<str_mat4> temp_matrix_4f; |
433 | |
455 | |
434 | template<GLenum gltype, const char *strtype> |
456 | template<GLenum gltype, const char *strtype> |
435 | struct sampler_i : uniform_i |
457 | struct sampler_i : uniform_i |
436 | { |
458 | { |
437 | GLuint texture; |
459 | GLuint unit; |
438 | |
460 | |
439 | void update () |
461 | void update () |
440 | { |
462 | { |
441 | if (dirty) |
463 | if (dirty) |
442 | { |
464 | { |
… | |
… | |
445 | } |
467 | } |
446 | } |
468 | } |
447 | |
469 | |
448 | void begin () |
470 | void begin () |
449 | { |
471 | { |
450 | cgGLEnableTextureParameter (texture); |
472 | cgGLEnableTextureParameter (unit); |
451 | } |
473 | } |
452 | |
474 | |
453 | sampler_i (GLuint texturename) : uniform_i (strtype), texture (texturename) { } |
475 | sampler_i (GLuint textureunit) : uniform_i (strtype), unit (textureunit) { } |
454 | }; |
476 | }; |
455 | |
477 | |
456 | struct sampler_1d_i : sampler_i<CG_SAMPLER1D, str_sampler_1d> |
478 | struct sampler_1d_i : sampler_i<CG_SAMPLER1D, str_sampler_1d> |
457 | { |
479 | { |
458 | sampler_1d_i (GLuint texturename) : sampler_i<CG_SAMPLER1D, str_sampler_1d> (texturename) { } |
480 | sampler_1d_i (GLuint textureunit) : sampler_i<CG_SAMPLER1D, str_sampler_1d> (textureunit) { } |
459 | }; |
481 | }; |
460 | |
482 | |
461 | struct sampler_1d_shadow_i : sampler_i<CG_SAMPLER1D, str_sampler_1d_shadow> |
483 | struct sampler_1d_shadow_i : sampler_i<CG_SAMPLER1D, str_sampler_1d_shadow> |
462 | { |
484 | { |
463 | sampler_1d_shadow_i (GLuint texturename) : sampler_i<CG_SAMPLER1D, str_sampler_1d_shadow> (texturename) { } |
485 | sampler_1d_shadow_i (GLuint textureunit) : sampler_i<CG_SAMPLER1D, str_sampler_1d_shadow> (textureunit) { } |
464 | }; |
486 | }; |
465 | |
487 | |
466 | struct sampler_2d_i : sampler_i<CG_SAMPLER2D, str_sampler_2d> |
488 | struct sampler_2d_i : sampler_i<CG_SAMPLER2D, str_sampler_2d> |
467 | { |
489 | { |
468 | sampler_2d_i (GLuint texturename) : sampler_i<CG_SAMPLER2D, str_sampler_2d> (texturename) { } |
490 | sampler_2d_i (GLuint textureunit) : sampler_i<CG_SAMPLER2D, str_sampler_2d> (textureunit) { } |
469 | }; |
491 | }; |
470 | |
492 | |
471 | struct sampler_2d_shadow_i : sampler_i<CG_SAMPLER2D, str_sampler_2d_shadow> |
493 | struct sampler_2d_shadow_i : sampler_i<CG_SAMPLER2D, str_sampler_2d_shadow> |
472 | { |
494 | { |
473 | sampler_2d_shadow_i (GLuint texturename) : sampler_i<CG_SAMPLER2D, str_sampler_2d_shadow> (texturename) { } |
495 | sampler_2d_shadow_i (GLuint textureunit) : sampler_i<CG_SAMPLER2D, str_sampler_2d_shadow> (textureunit) { } |
474 | }; |
496 | }; |
475 | |
497 | |
476 | struct sampler_2d_rect_i : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect> |
498 | struct sampler_2d_rect_i : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect> |
477 | { |
499 | { |
478 | sampler_2d_rect_i (GLuint texturename) : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect> (texturename) { } |
500 | sampler_2d_rect_i (GLuint textureunit) : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect> (textureunit) { } |
479 | }; |
501 | }; |
480 | |
502 | |
481 | struct sampler_2d_rect_shadow_i : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect_shadow> |
503 | struct sampler_2d_rect_shadow_i : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect_shadow> |
482 | { |
504 | { |
483 | sampler_2d_rect_shadow_i (GLuint texturename) : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect_shadow> (texturename) { } |
505 | sampler_2d_rect_shadow_i (GLuint textureunit) : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect_shadow> (textureunit) { } |
484 | }; |
506 | }; |
485 | |
507 | |
486 | struct sampler_3d_i : sampler_i<CG_SAMPLER3D, str_sampler_3d> |
508 | struct sampler_3d_i : sampler_i<CG_SAMPLER3D, str_sampler_3d> |
487 | { |
509 | { |
488 | sampler_3d_i (GLuint texturename) : sampler_i<CG_SAMPLER3D, str_sampler_3d> (texturename) { } |
510 | sampler_3d_i (GLuint textureunit) : sampler_i<CG_SAMPLER3D, str_sampler_3d> (textureunit) { } |
489 | }; |
511 | }; |
490 | |
512 | |
491 | struct sampler_3d_rect_i : sampler_i<CG_SAMPLER3D, str_sampler_3d_rect> |
513 | struct sampler_3d_rect_i : sampler_i<CG_SAMPLER3D, str_sampler_3d_rect> |
492 | { |
514 | { |
493 | sampler_3d_rect_i (GLuint texturename) : sampler_i<CG_SAMPLER3D, str_sampler_3d_rect> (texturename) { } |
515 | sampler_3d_rect_i (GLuint textureunit) : sampler_i<CG_SAMPLER3D, str_sampler_3d_rect> (textureunit) { } |
494 | }; |
516 | }; |
495 | |
517 | |
496 | struct sampler_cube_i : sampler_i<CG_SAMPLERCUBE, str_sampler_cube> |
518 | struct sampler_cube_i : sampler_i<CG_SAMPLERCUBE, str_sampler_cube> |
497 | { |
519 | { |
498 | sampler_cube_i (GLuint texturename) : sampler_i<CG_SAMPLERCUBE, str_sampler_cube> (texturename) { } |
520 | sampler_cube_i (GLuint textureunit) : sampler_i<CG_SAMPLERCUBE, str_sampler_cube> (textureunit) { } |
499 | }; |
521 | }; |
500 | |
522 | |
501 | typedef auto_ref1<sampler_1d_i, GLuint> sampler_1d; |
523 | typedef auto_ref1<sampler_1d_i, GLuint> sampler_1d; |
502 | typedef auto_ref1<sampler_1d_shadow_i, GLuint> sampler_1d_shadow; |
524 | typedef auto_ref1<sampler_1d_shadow_i, GLuint> sampler_1d_shadow; |
503 | typedef auto_ref1<sampler_2d_i, GLuint> sampler_2d; |
525 | typedef auto_ref1<sampler_2d_i, GLuint> sampler_2d; |
… | |
… | |
552 | |
574 | |
553 | void append_string (const char *s) |
575 | void append_string (const char *s) |
554 | { |
576 | { |
555 | push_back (*new fragment_string_i (s)); |
577 | push_back (*new fragment_string_i (s)); |
556 | } |
578 | } |
557 | |
|
|
558 | #if 0 |
|
|
559 | fragment_vector_i &operator <<(statement_i &f) |
|
|
560 | { |
|
|
561 | push_back (*new fragment_const_string_i (" ")); |
|
|
562 | |
|
|
563 | for (vector<fragment>::iterator i = f.begin (); i != f.end (); i++) |
|
|
564 | push_back (*i); |
|
|
565 | |
|
|
566 | push_back (*new fragment_const_string_i (";\n")); |
|
|
567 | return *this; |
|
|
568 | } |
|
|
569 | #endif |
|
|
570 | }; |
579 | }; |
571 | |
580 | |
572 | typedef ref<fragment_vector_i> fragment_vector; |
581 | typedef ref<fragment_vector_i> fragment_vector; |
573 | |
582 | |
574 | struct shader_object_i : fragment_vector_i |
583 | struct shader_object_i : fragment_vector_i |
… | |
… | |
596 | } |
605 | } |
597 | }; |
606 | }; |
598 | |
607 | |
599 | typedef shader_object<GL_VERTEX_SHADER_ARB> vertex_shader; |
608 | typedef shader_object<GL_VERTEX_SHADER_ARB> vertex_shader; |
600 | typedef shader_object<GL_FRAGMENT_SHADER_ARB> fragment_shader; |
609 | typedef shader_object<GL_FRAGMENT_SHADER_ARB> fragment_shader; |
|
|
610 | |
|
|
611 | struct program_object |
|
|
612 | { |
|
|
613 | GLuint id; |
|
|
614 | |
|
|
615 | vertex_shader vsh; |
|
|
616 | fragment_shader fsh; |
|
|
617 | |
|
|
618 | program_object (); |
|
|
619 | ~program_object (); |
|
|
620 | |
|
|
621 | void link (); |
|
|
622 | }; |
601 | |
623 | |
602 | template<typename T> |
624 | template<typename T> |
603 | struct sl_append |
625 | struct sl_append |
604 | { |
626 | { |
605 | T t; |
627 | T t; |
… | |
… | |
727 | return sl_append< var_ref<V> > (v); |
749 | return sl_append< var_ref<V> > (v); |
728 | } |
750 | } |
729 | }; |
751 | }; |
730 | |
752 | |
731 | template<> |
753 | template<> |
732 | struct sl_convert<glvar> |
754 | struct sl_convert<gluvar> |
733 | { |
755 | { |
734 | typedef sl_expr< sl_append<glvar> > T; |
756 | typedef sl_expr< sl_append<gluvar> > T; |
735 | static inline const T convert (const glvar &v) |
757 | static inline const T convert (const gluvar &v) |
736 | { |
758 | { |
737 | return sl_append<glvar> (v); |
759 | return sl_append<gluvar> (v); |
738 | } |
760 | } |
739 | }; |
761 | }; |
740 | |
762 | |
741 | template<> |
763 | template<> |
742 | template<const char *strtype> |
764 | template<const char *strtype> |
… | |
… | |
809 | { |
831 | { |
810 | cur->push_back (str); |
832 | cur->push_back (str); |
811 | } |
833 | } |
812 | }; |
834 | }; |
813 | |
835 | |
|
|
836 | extern const sl_append_const_string str_lpar; |
|
|
837 | extern const sl_append_const_string str_rpar; |
|
|
838 | |
|
|
839 | template<class A, class B, class C> |
|
|
840 | struct sl_binop |
|
|
841 | { |
|
|
842 | const A a; const B b; const C c; |
|
|
843 | sl_binop (const A &a, const B &b, const C &c) : a(a), b(b), c(c) { } |
|
|
844 | void operator ()() const { str_lpar (); a (); b (); c (); str_rpar (); } |
|
|
845 | }; |
|
|
846 | |
814 | # define SHADER_BINOP(op, str) \ |
847 | # define SHADER_BINOP(op, str) \ |
815 | extern const sl_append_const_string str_ ## str; \ |
848 | extern const sl_append_const_string str_ ## str; \ |
816 | template<typename A, typename B> \ |
849 | template<typename A, typename B> \ |
817 | inline const sl_expr< sl_concat3< typename sl_convert<A>::T, \ |
850 | inline const sl_expr< sl_binop< typename sl_convert<A>::T, \ |
818 | sl_append_const_string, \ |
851 | sl_append_const_string, \ |
819 | typename sl_convert<B>::T > > \ |
852 | typename sl_convert<B>::T > > \ |
820 | operator op(const A &a, const B &b) \ |
853 | operator op(const A &a, const B &b) \ |
821 | { \ |
854 | { \ |
|
|
855 | return sl_binop< typename sl_convert<A>::T, sl_append_const_string, typename sl_convert<B>::T > \ |
822 | return concat (sl_convert<A>::convert (a), str_ ## str, sl_convert<B>::convert (b)); \ |
856 | (sl_convert<A>::convert (a), str_ ## str, sl_convert<B>::convert (b)); \ |
823 | } |
857 | } |
824 | |
858 | |
825 | SHADER_BINOP (+, plus); |
859 | SHADER_BINOP (+, plus); |
826 | SHADER_BINOP (-, minus); |
860 | SHADER_BINOP (-, minus); |
827 | SHADER_BINOP (*, mul); |
861 | SHADER_BINOP (*, mul); |
828 | SHADER_BINOP (/, div); |
862 | SHADER_BINOP (/, div); |
829 | SHADER_BINOP (%, div); |
863 | SHADER_BINOP (%, mod); |
830 | |
864 | |
831 | # undef SHADER_BINOP |
865 | # undef SHADER_BINOP |
832 | |
866 | |
833 | void swizzle_mask (sl_string<7> &s, int mask); |
867 | void swizzle_mask (sl_string<7> &s, int mask); |
834 | |
|
|
835 | extern const sl_append_const_string str_lpar; |
|
|
836 | extern const sl_append_const_string str_rpar; |
|
|
837 | |
868 | |
838 | template<typename T> |
869 | template<typename T> |
839 | inline const sl_expr< sl_concat3< sl_append_const_string, |
870 | inline const sl_expr< sl_concat3< sl_append_const_string, |
840 | typename sl_convert<T>::T, |
871 | typename sl_convert<T>::T, |
841 | sl_string<7> |
872 | sl_string<7> |