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