]> git.treefish.org Git - phys/latlib.git/blob - culooks.cpp
...
[phys/latlib.git] / culooks.cpp
1 #include "culooks.h"
2
3 #include <math.h>
4
5 vector< pair<int,culooks::window*> > culooks::Windows;
6 pthread_t culooks::glThreadId;
7
8 int culooks::windowid = 0;
9
10 int culooks::cube::allid = 0;
11
12 using namespace std;
13
14 void culooks::cube::draw()
15 {
16   glMatrixMode(GL_MODELVIEW);
17   glPushMatrix();
18
19   //cout << zoom << endl;
20
21   glScalef(zoom, zoom, zoom);
22   glRotatef(az, 0, 1, 0);
23   glRotatef(alt, 1, 0, 0);
24
25   /*
26   glBegin(GL_QUADS);
27   glVertex2f(-1, -1); glVertex2f(1, -1); glVertex2f(1, 1); glVertex2f(-1, 1);
28   glEnd();
29   */
30
31   //drawBox();
32   drawAll();
33
34   glPopMatrix();
35 }
36
37 void culooks::cube::drawAll()
38 {
39   glMatrixMode(GL_MODELVIEW);
40   glPushMatrix();
41
42   glTranslatef(-1,-1,-1);
43
44   for (int iz=0; iz<l; iz++) {
45     for (int iy=0; iy<l; iy++) {
46       for (int ix=0; ix<l; ix++) {
47         glPushMatrix();
48         glTranslatef(2.0*ix/l,2.0*iy/l,2.0*iz/l);
49         glScalef(2.0/l,2.0/l,2.0/l);
50
51         /* draw links */
52         glBegin(GL_LINES);
53         glColor4f(link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 0],
54                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 1],
55                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 2],
56                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 3]);
57         glVertex3f(0,0,0); glVertex3f(1,0,0);
58         glColor4f(link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 0],
59                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 1],
60                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 2],
61                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 3]);
62         glVertex3f(0,0,0); glVertex3f(0,1,0);
63         glColor4f(link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 0],
64                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 1],
65                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 2],
66                   link[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 3]);
67         glVertex3f(0,0,0); glVertex3f(0,0,1);
68         glEnd();
69
70         /* draw plaquettes */
71         glColor4f(1,1,1,0.5);
72         glBegin(GL_QUADS);
73         glColor4f(plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 0],
74                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 1],
75                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 2],
76                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 2*4 + 3]);
77         glVertex3f(0, 0, 0); glVertex3f(1, 0, 0); glVertex3f(1, 1, 0); glVertex3f(0, 1, 0);
78         glColor4f(plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 0],
79                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 1],
80                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 2],
81                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 1*4 + 3]);
82         glVertex3f(0, 0, 0); glVertex3f(1, 0, 0); glVertex3f(1, 0, 1); glVertex3f(0, 0, 1);
83         glColor4f(plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 0],
84                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 1],
85                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 2],
86                   plaq[iz*l*l*3*4 + iy*l*3*4 + ix*3*4 + 0*4 + 3]);
87         glVertex3f(0, 0, 0); glVertex3f(0, 1, 0); glVertex3f(0, 1, 1); glVertex3f(0, 0, 1);
88         glEnd();
89
90         glPopMatrix();
91       }
92     }
93   }
94     
95   glPopMatrix();
96 }
97
98 namespace mygl 
99 {
100   int rotcube[3];
101
102   culooks::window* getWin()
103   {
104     for (int iwin=0; iwin<culooks::Windows.size(); iwin++)
105       if ( culooks::Windows.at(iwin).first == glutGetWindow() ) {
106         return culooks::Windows.at(iwin).second;
107       }
108     //cerr << "Something terrible happened: Could not find window-id!" << endl;
109     exit(1);
110   }
111
112   static int getCubeFromPos(int x, int y)
113   {
114     culooks::window *Win = getWin();
115
116     int col = x / ((float)Win->w / Win->layout[0]);
117     int row = Win->layout[1] - y / ((float)Win->h / Win->layout[1]);
118
119     return col + row*Win->layout[0];
120   }
121
122
123   static void motionFunc(int x, int y)
124   {   
125     //cout << x << endl;
126     culooks::window *Win = getWin();
127    
128     Win->cubes.at(rotcube[0]).az += rotcube[1] - x;
129     Win->cubes.at(rotcube[0]).alt += rotcube[2] - y;
130
131     rotcube[1] = x;
132     rotcube[2] = y;
133    
134
135     glutPostRedisplay();
136   }
137
138   static void mouseFunc(int button, int state, int x, int y)
139   {
140     culooks::window *Win = getWin();
141
142     if (button == 0) {
143       rotcube[0] = getCubeFromPos(x,y);
144       rotcube[1] = x;
145       rotcube[2] = y;
146     }
147
148     if (button == 4) {
149       Win->cubes.at(getCubeFromPos(x,y)).zoom *= 1.1;
150       glutPostRedisplay();
151     }
152     else if (button == 3) {
153       Win->cubes.at(getCubeFromPos(x,y)).zoom *= 0.9;
154       glutPostRedisplay();
155     }
156   }
157
158
159   static void reshapeFunc(int w, int h)
160   {
161     culooks::window *Win = getWin();
162     
163     int neww;
164     int newh;
165
166     if ( w == Win->w ) {
167       newh = h;
168       neww = Win->aspect*h;
169     }
170     else if ( h == Win->h ) {
171       neww = w;
172       newh = w / Win->aspect;
173     }
174     else {
175       neww = ( pow(Win->aspect,2)*w + Win->aspect*h ) / ( pow(Win->aspect,2) + 1 );
176       newh = ( Win->aspect*w + h ) / ( pow(Win->aspect,2) + 1 );
177     }
178
179     glutReshapeWindow(neww,newh);
180     glViewport(0,0,neww,newh);
181
182     Win->w = neww;
183     Win->h = newh;
184   }
185
186   static void displayFunc()
187   {
188     //cout << ":" << glutGetWindow() << endl;
189
190     culooks::window *Win = getWin();
191     
192     glClearColor(0,0,0,0);
193     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
194     
195     glMatrixMode(GL_MODELVIEW);
196     glLoadIdentity();
197     
198     glScalef(1.0/Win->layout[0],1.0/Win->layout[1],1.0);
199     glTranslatef(-Win->layout[0]+1, -Win->layout[1]+1, 0);
200     
201     for (int icube=0; icube < Win->cubes.size(); icube++) {
202       //glScalef(1.0/Env->layout[0],1.0/Env->layout[1],1.0);
203       //glRotatef(2, 1, 0, 0);
204       Win->cubes.at(icube).draw();
205       if ((icube+1)%Win->layout[0] == 0) {
206         glTranslatef(-2*Win->layout[0]+2, 2, 0);
207       }
208       else {
209         glTranslatef(2, 0, 0);
210       }
211     }
212     
213     glutSwapBuffers();
214   }
215  
216   static void initWindow(int winid)
217   {
218     glutInitWindowSize(culooks::Windows[winid].second->w, culooks::Windows[winid].second->h);
219     glutInitWindowPosition(winid*100,winid*100);
220     glutCreateWindow( ("culooks / " + culooks::Windows[winid].second->name).c_str() );
221     
222     glutDisplayFunc(&mygl::displayFunc);
223     glutReshapeFunc(&mygl::reshapeFunc);
224     glutMotionFunc(&mygl::motionFunc);
225     glutMouseFunc(&mygl::mouseFunc);
226
227     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
228     glEnable( GL_BLEND );
229
230     culooks::Windows[winid].first = glutGetWindow();
231
232     culooks::Windows[winid].second->initialized = true;
233   }
234
235   static void idleFunc_master()
236   {
237     for (int iwin=0; iwin < culooks::Windows.size(); iwin++)
238       if (!culooks::Windows[iwin].second->initialized)
239         initWindow(iwin);
240   }
241
242   static void* glutThread(void *_wincon)
243   {
244     culooks::wincontext *wincon = (culooks::wincontext *)_wincon;
245     glXMakeCurrent( wincon->gDisplay, wincon->gDrawable, wincon->gContext );
246     initWindow(0);
247     glutIdleFunc(&idleFunc_master);
248     glutMainLoop();
249   }
250 };
251
252
253 culooks::culooks (const char* name, const int& xcubes, const int& ycubes, const int& l, int *argc, char **argv)
254 {
255   window *Win = new window;
256   int winsize[2];
257   wincontext wincon;
258
259   if (windowid == 0) {
260     glutInit(argc, argv);
261     glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
262   }
263
264   Win->layout[0] = xcubes;
265   Win->layout[1] = ycubes;
266   Win->aspect = (double)xcubes/ycubes;
267   for (int icube=0; icube<xcubes*ycubes; icube++) {
268     cube newCube(l);
269     Win->cubes.push_back(newCube);
270   }
271
272   if( Win->layout[0] >= Win->layout[1] ) {
273     winsize[0] = 640;
274     winsize[1] = (640.0/Win->layout[0])*Win->layout[1];
275   }
276   else {
277     winsize[1] = 640;
278     winsize[0] = (640.0/Win->layout[1])*Win->layout[0];
279   }
280
281   Win->w = winsize[0];
282   Win->h = winsize[1];
283
284   Win->name = name;
285
286   Win->initialized = false;
287
288   Windows.push_back( pair<int,culooks::window*>(0, Win) );
289   
290   if (windowid == 0) {
291     wincon.gContext = glXGetCurrentContext();
292     wincon.gDisplay = glXGetCurrentDisplay();
293     wincon.gDrawable = glXGetCurrentDrawable();
294
295     glXMakeCurrent(0,0,0);
296
297     pthread_create(&glThreadId, 0, &mygl::glutThread, &wincon);
298   }
299
300   mywid = windowid;
301   windowid++;
302 }
303
304 culooks::cube::cube(int _l)
305 {
306   l = _l;
307   link = new float[l*l*l*3 * 4];
308   plaq = new float[l*l*l*3 * 4];
309   az = 30;
310   alt = -20;
311   zoom = 0.6;
312   id = allid;
313   allid++;
314
315   for (int i=0; i<l*l*l*3; i++) {
316     link[i*4+0]=1; link[i*4+3]=0.6;
317     plaq[i*4+1]=1; plaq[i*4+3]=0.2;
318   }
319 }