]> git.treefish.org Git - phys/latlib.git/blob - culooks.cpp
...
[phys/latlib.git] / culooks.cpp
1 #include "culooks.h"
2
3 #include <vector>
4 #include <GL/glut.h>
5 #include <GL/glx.h>
6 #include <GL/gl.h>
7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h>
9
10 #include <iostream>
11 #include <math.h>
12
13 vector< pair<int,culooks::window*> > culooks::Windows;
14 pthread_t culooks::glThreadId;
15
16 int culooks::windowid = 0;
17
18 using namespace std;
19
20 namespace mygl 
21 {
22   int rotcube[3];
23
24   culooks::window* getWin()
25   {
26     for (int iwin=0; iwin<culooks::Windows.size(); iwin++)
27       if ( culooks::Windows.at(iwin).first == glutGetWindow() ) {
28         return culooks::Windows.at(iwin).second;
29       }
30     //cerr << "Something terrible happened: Could not find window-id!" << endl;
31     exit(1);
32   }
33
34   static int getCubeFromPos(int x, int y)
35   {
36     culooks::window *Win = getWin();
37
38     int col = x / ((float)Win->w / Win->layout[0]);
39     int row = Win->layout[1] - y / ((float)Win->h / Win->layout[1]);
40
41     return col + row*Win->layout[0];
42   }
43
44
45   static void motionFunc(int x, int y)
46   {   
47     //cout << x << endl;
48     culooks::window *Win = getWin();
49    
50     Win->cubes.at(rotcube[0]).az += rotcube[1] - x;
51     Win->cubes.at(rotcube[0]).alt += rotcube[2] - y;
52
53     rotcube[1] = x;
54     rotcube[2] = y;
55    
56
57     glutPostRedisplay();
58   }
59
60   static void mouseFunc(int button, int state, int x, int y)
61   {
62     culooks::window *Win = getWin();
63
64     if (button == 0) {
65       rotcube[0] = getCubeFromPos(x,y);
66       rotcube[1] = x;
67       rotcube[2] = y;
68     }
69
70     if (button == 4) {
71       Win->cubes.at(getCubeFromPos(x,y)).zoom *= 1.1;
72       glutPostRedisplay();
73     }
74     else if (button == 3) {
75       Win->cubes.at(getCubeFromPos(x,y)).zoom *= 0.9;
76       glutPostRedisplay();
77     }
78   }
79
80
81   static void reshapeFunc(int w, int h)
82   {
83     culooks::window *Win = getWin();
84     
85     int neww;
86     int newh;
87
88     if ( w == Win->w ) {
89       newh = h;
90       neww = Win->aspect*h;
91     }
92     else if ( h == Win->h ) {
93       neww = w;
94       newh = w / Win->aspect;
95     }
96     else {
97       neww = ( pow(Win->aspect,2)*w + Win->aspect*h ) / ( pow(Win->aspect,2) + 1 );
98       newh = ( Win->aspect*w + h ) / ( pow(Win->aspect,2) + 1 );
99     }
100
101     glutReshapeWindow(neww,newh);
102     glViewport(0,0,neww,newh);
103
104     Win->w = neww;
105     Win->h = newh;
106   }
107
108   static void displayFunc()
109   {
110     //cout << ":" << glutGetWindow() << endl;
111
112     culooks::window *Win = getWin();
113     
114     glClearColor(0,0,0,0);
115     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
116     
117     glMatrixMode(GL_MODELVIEW);
118     glLoadIdentity();
119     
120     glScalef(1.0/Win->layout[0],1.0/Win->layout[1],1.0);
121     glTranslatef(-Win->layout[0]+1, -Win->layout[1]+1, 0);
122     
123     for (int icube=0; icube < Win->cubes.size(); icube++) {
124       //glScalef(1.0/Env->layout[0],1.0/Env->layout[1],1.0);
125       //glRotatef(2, 1, 0, 0);
126       Win->cubes.at(icube).draw();
127       if ((icube+1)%Win->layout[0] == 0) {
128         glTranslatef(-2*Win->layout[0]+2, 2, 0);
129       }
130       else {
131         glTranslatef(2, 0, 0);
132       }
133     }
134     
135     glutSwapBuffers();
136   }
137  
138   static void initWindow(int winid)
139   {
140     glutInitWindowSize(culooks::Windows[winid].second->w, culooks::Windows[winid].second->h);
141     glutInitWindowPosition(winid*100,winid*100);
142     glutCreateWindow( ("culooks / " + culooks::Windows[winid].second->name).c_str() );
143     
144     glutDisplayFunc(&mygl::displayFunc);
145     glutReshapeFunc(&mygl::reshapeFunc);
146     glutMotionFunc(&mygl::motionFunc);
147     glutMouseFunc(&mygl::mouseFunc);
148
149     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
150     glEnable( GL_BLEND );
151
152     culooks::Windows[winid].first = glutGetWindow();
153
154     culooks::Windows[winid].second->initialized = true;
155   }
156
157   static void idleFunc_master()
158   {
159     for (int iwin=0; iwin < culooks::Windows.size(); iwin++)
160       if (!culooks::Windows[iwin].second->initialized)
161         initWindow(iwin);
162   }
163
164   static void* glutThread(void *leer)
165   {
166     initWindow(0);
167     glutIdleFunc(&idleFunc_master);
168     glutMainLoop();
169   }
170 };
171
172
173 culooks::culooks (const char* name, const int& xcubes, const int& ycubes, const int& l, int *argc, char **argv)
174 {
175   window *Win = new window;
176   int winsize[2];
177   wincontext wincon;
178
179   if (windowid == 0) {
180     glutInit(argc, argv);
181     glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
182   }
183
184   Win->layout[0] = xcubes;
185   Win->layout[1] = ycubes;
186   Win->aspect = (double)xcubes/ycubes;
187   for (int icube=0; icube<xcubes*ycubes; icube++) {
188     cube newCube(l);
189     Win->cubes.push_back(newCube);
190   }
191
192   if( Win->layout[0] >= Win->layout[1] ) {
193     winsize[0] = 640;
194     winsize[1] = (640.0/Win->layout[0])*Win->layout[1];
195   }
196   else {
197     winsize[1] = 640;
198     winsize[0] = (640.0/Win->layout[1])*Win->layout[0];
199   }
200
201   Win->w = winsize[0];
202   Win->h = winsize[1];
203
204   Win->name = name;
205
206   Win->initialized = false;
207
208   Windows.push_back( pair<int,culooks::window*>(0, Win) );
209   
210   if (windowid == 0) {
211     glXMakeCurrent(0,0,0);
212     pthread_create(&glThreadId, 0, &mygl::glutThread, NULL);
213   }
214
215   mywid = windowid;
216   windowid++;
217 }
218