1 module des.gui.sdlgl.canvas;
2 
3 import des.gui.sdlgl.base;
4 
5 alias iRect=Region!(2,int);
6 
7 struct ViewPair
8 {
9     iRect crd;
10     iRect vis;
11 }
12 
13 class DiGLCanvas : DiCanvas
14 {
15     DrawRectControl drc;
16 
17     this() { drc = new DrawRectControl; }
18 
19     void prepare()
20     {
21         glEnable( GL_SCISSOR_TEST );
22     }
23 
24     void resize( ivec2 sz ) { drc.setOrigin( sz ); }
25 
26     void preDraw()
27     {
28         auto w = drc.origin.size.w;
29         auto h = drc.origin.size.h;
30         glClearColor( 0,0,0,0 );
31         setView( drc.stack[0] );
32         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
33     }
34 
35     void postDraw() { }
36 
37     DiRect pushDrawRect( DiRect r )
38     {
39         auto ret = drc.push( iRect( r ) );
40         setInvView( drc.last );
41         return ret;
42     }
43 
44     void popDrawRect()
45     {
46         drc.pop();
47         //setInvView( drc.last );
48     }
49 
50 protected:
51 
52     void setInvView( in ViewPair np )
53     {
54         auto p = invYCoord( np );
55         setView( p );
56     }
57 
58     ViewPair invYCoord( in ViewPair vp )
59     { return ViewPair( invYCoord(vp.crd), invYCoord(vp.vis) ); }
60 
61     iRect invYCoord( in iRect r )
62     {
63         auto h = drc.origin.size.y;
64         return iRect( r.pos.x, h - r.pos.y - r.size.y, r.size );
65     }
66 
67     void setView( in ViewPair p )
68     {
69         glViewport( p.crd.pos.x, p.crd.pos.y, p.crd.size.w, p.crd.size.h );
70         glScissor( p.vis.pos.x, p.vis.pos.y, p.vis.size.w, p.vis.size.h  );
71     }
72 }
73 
74 class DrawRectControl
75 {
76     iRect origin;
77 
78     ViewPair[] stack;
79 
80     this() { origin.pos = ivec2(0); }
81 
82     void setOrigin( ivec2 sz )
83     {
84         origin.size = sz;
85         stack.length = 0;
86         stack ~= ViewPair( origin, origin );
87     }
88 
89     iRect push( in iRect rr )
90     {
91         auto r = iRect( rr.pos + last.crd.pos, rr.size );
92         auto o = last.vis.overlap(r);
93         stack ~= ViewPair( r, o );
94         return iRect( o.pos - last.crd.pos, o.size );
95     }
96 
97     void pop() { stack.length--; }
98 
99     ref const(ViewPair) last() const @property
100     { return stack[$-1]; }
101 }