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