../../katie/MandelbrotDy/MandelbrotOGL.cpp | mandelbrotMathlink.c | |||
---|---|---|---|---|
318 lines 7375 bytes Last modified : Tue Jul 22 14:38:04 2008 |
225 lines 5217 bytes Last modified : Tue Jul 22 09:40:09 2008 |
|||
1 | // To compile on Linux: | 1 | // Mandelbrot Mathlink Client | |
2 | // cc -Wall MandelbrotOGL.cpp -o MandelbrotOGL -lGL -lGLU -lglut -lGLEW -lm -lX11 -L /usr/X11R6/lib | |||
3 | // To compile on OSX: | |||
4 | // g++ -framework GLUT -framework OpenGL MandelbrotOGL.cpp -o MandelbrotOGL | |||
5 | // Mandelbrot Client | |||
6 | // Original CUDA program submitted by Mark Granger, NewTek | 2 | // Original CUDA program submitted by Mark Granger, NewTek | |
7 | // Client was written by Abdulmajed Dakkak | 3 | // Client was written by Abdulmajed Dakkak | |
4 | // Mathlink interface was written by Abdulmajed Dakkak | |||
8 | 5 | |||
9 | #include <stdio.h> | 6 | #include <stdio.h> | |
10 | #include <stdlib.h> | 7 | #include <stdlib.h> | |
11 | #include <string.h> | 8 | #include <string.h> | |
12 | #ifdef __APPLE__ | |||
13 | #include <GLUT/glut.h> | |||
14 | #else | |||
15 | #include <GL/glut.h> | |||
16 | #endif | |||
17 | #include <fcntl.h> | 9 | #include <fcntl.h> | |
18 | #include <unistd.h> | 10 | #include <unistd.h> | |
19 | #include <netinet/in.h> | 11 | #include <netinet/in.h> | |
20 | #include <sys/socket.h> | 12 | #include <sys/socket.h> | |
21 | #include <arpa/inet.h> | 13 | #include <arpa/inet.h> | |
22 | 14 | #include "mathlink.h" | ||
23 | #define IMAGE_W 800 | |||
24 | #define IMAGE_H 600 | |||
25 | #define MAX_PASS 4 | |||
26 | 15 | |||
27 | #define INVALIDATE_STEP 3 | 16 | #define INVALIDATE_STEP 3 | |
28 | 17 | |||
29 | #define GETNEWFRAME 0x0 | 18 | #define GETNEWFRAME 0x0 | |
30 | #define ZOOMIN 0x2 | 19 | #define ZOOMIN 0x2 | |
31 | #define ZOOMOUT 0x3 | 20 | #define ZOOMOUT 0x3 | |
32 | #define MOVERIGHT 0x4 | 21 | #define MOVERIGHT 0x4 | |
33 | #define MOVEUP 0x5 | 22 | #define MOVEUP 0x5 | |
34 | #define MOVELEFT 0x6 | 23 | #define MOVELEFT 0x6 | |
35 | #define MOVEDOWN 0x7 | 24 | #define MOVEDOWN 0x7 | |
36 | #define TERMINATE 0x8 | 25 | #define TERMINATE 0x8 | |
37 | #define MOUSE 0x9 | 26 | #define MOUSE 0x9 | |
38 | #define CLICK 0x1 | 27 | #define CLICK 0x1 | |
39 | #define MOTION 0x2 | 28 | #define MOTION 0x2 | |
40 | #define LEFTCLICK 0x0 | 29 | #define LEFTCLICK 0x0 | |
41 | #define RIGHTCLICK 0x1 | 30 | #define RIGHTCLICK 0x1 | |
42 | 31 | |||
43 | //Original image width and height | 32 | //Original image width and height | |
44 | int imageW, imageH, max_pass; | 33 | int imageW, imageH, max_pass; | |
45 | 34 | |||
46 | // Starting position and scale | 35 | // Starting position and scale | |
47 | double xOff = -0.5; | 36 | double xOff = -0.5; | |
48 | double yOff = 0.0; | 37 | double yOff = 0.0; | |
49 | double scale = 3.2; | 38 | double scale = 3.2; | |
50 | 39 | |||
51 | // Starting stationary position and scale motion | 40 | // Starting stationary position and scale motion | |
52 | double xdOff = 0.0; | 41 | double xdOff = 0.0; | |
53 | double ydOff = 0.0; | 42 | double ydOff = 0.0; | |
54 | 43 | |||
55 | // SOCKET ID | 44 | // SOCKET ID | |
56 | int sockfd; | 45 | int sockfd; | |
57 | 46 | |||
58 | // Request packet | 47 | // Request packet | |
59 | char request[16]; | 48 | char request[16]; | |
60 | 49 | |||
61 | // D_DST Def | 50 | // D_DST Def | |
62 | char d_dst[IMAGE_H * IMAGE_W * 4]; | 51 | char * d_dst; | |
63 | 52 | |||
64 | short invalid_frame = true; | 53 | short invalid_frame = 1; | |
65 | 54 | |||
66 | /**********Network Functions************/ | 55 | /**********Network Functions************/ | |
67 | void connectToServer(int port, char* IP) { | 56 | int connectToServer(int port, char* IP) { | |
68 | fprintf(stderr,"Attempting to connect to server...\n"); | 57 | fprintf(stderr,"Attempting to connect to server...\n"); | |
69 | struct sockaddr_in remote_addr; | 58 | struct sockaddr_in remote_addr; | |
70 | 59 | |||
71 | sockfd=socket(PF_INET,SOCK_STREAM,0); | 60 | sockfd=socket(PF_INET,SOCK_STREAM,0); | |
72 | 61 | |||
73 | remote_addr.sin_family=AF_INET; | 62 | remote_addr.sin_family=AF_INET; | |
74 | remote_addr.sin_port=htons(port); | 63 | remote_addr.sin_port=htons(port); | |
75 | remote_addr.sin_addr.s_addr=inet_addr(IP); | 64 | remote_addr.sin_addr.s_addr=inet_addr(IP); | |
76 | memset(remote_addr.sin_zero, '\0',sizeof remote_addr.sin_zero); | 65 | memset(remote_addr.sin_zero, '\0',sizeof remote_addr.sin_zero); | |
77 | 66 | |||
78 | if(connect(sockfd,(struct sockaddr*)&remote_addr,sizeof remote_addr)==-1){ | 67 | if(connect(sockfd,(struct sockaddr*)&remote_addr,sizeof remote_addr)==-1){ | |
79 | perror("connect"); | 68 | perror("connect"); | |
80 | exit(1); | 69 | exit(1); | |
81 | } | 70 | } | |
82 | 71 | |||
83 | fprintf(stderr,"Connected to server.\n"); | 72 | fprintf(stderr,"Connected to server.\n"); | |
73 | return 1; | |||
84 | } | 74 | } | |
85 | 75 | |||
86 | void sendEnvironmentVariables( ) { | 76 | int sendEnvironmentVariables( ) { | |
87 | int env[3] = {imageW, imageH, MAX_PASS}; | 77 | int env[3] = {imageW, imageH, max_pass}; | |
88 | send(sockfd, env, 3 * sizeof(int), 0); | 78 | send(sockfd, env, 3 * sizeof(int), 0); | |
79 | return 1; | |||
89 | } | 80 | } | |
90 | 81 | |||
91 | void getNewFrame( ) { | 82 | int * getNewFrame( ) { | |
92 | // fprintf(stderr,"Requesting new frame...\n"); | 83 | // fprintf(stderr,"Requesting new frame...\n"); | |
84 | int i; | |||
93 | 85 | |||
94 | request[0]= GETNEWFRAME; | 86 | request[0]= GETNEWFRAME; | |
95 | send(sockfd, request, 16 * sizeof(char), 0); | 87 | send(sockfd, request, 16 * sizeof(char), 0); | |
96 | 88 | |||
97 | int bytesRecieved=recv(sockfd, d_dst, | 89 | int bytesRecieved=recv(sockfd, d_dst, | |
98 | imageW * imageH * 4 * sizeof(char), MSG_WAITALL); | 90 | imageW * imageH * 4 * sizeof(char), MSG_WAITALL); | |
99 | if(bytesRecieved==-1) { perror("recv()"); exit(1); } | 91 | if(bytesRecieved==-1) { perror("recv()"); exit(1); } | |
100 | 92 | |||
93 | int data[imageW * imageH * 4]; | |||
94 | for(i = 0; i < imageW * imageH * 4; i++) { | |||
95 | data[i] = *(d_dst + i); | |||
96 | } | |||
97 | MLPutIntegerList(stdlink, (int *) data, imageW * imageH * 4); | |||
101 | // fprintf(stderr,"Received frame. (%d bytes).\n",bytesRecieved); | 98 | // fprintf(stderr,"Received frame. (%d bytes).\n",bytesRecieved); | |
99 | return ; | |||
102 | } | 100 | } | |
103 | 101 | |||
104 | void sendRequestToZoomIn( ) { | 102 | int sendRequestToZoomIn( ) { | |
105 | request[0] = ZOOMIN; | 103 | request[0] = ZOOMIN; | |
106 | send(sockfd, request, 16 * sizeof(char), 0); | 104 | send(sockfd, request, 16 * sizeof(char), 0); | |
105 | return 1; | |||
107 | } | 106 | } | |
108 | 107 | |||
109 | void sendRequestToZoomOut( ) { | 108 | int sendRequestToZoomOut( ) { | |
110 | request[0] = ZOOMOUT; | 109 | request[0] = ZOOMOUT; | |
111 | send(sockfd, request, 16 * sizeof(char), 0); | 110 | send(sockfd, request, 16 * sizeof(char), 0); | |
111 | return 1; | |||
112 | } | 112 | } | |
113 | 113 | |||
114 | void sendRequestToMoveLeft( ) { | 114 | int sendRequestToMoveLeft( ) { | |
115 | request[0] = MOVELEFT; | 115 | request[0] = MOVELEFT; | |
116 | send(sockfd, request, 16 * sizeof(char), 0); | 116 | send(sockfd, request, 16 * sizeof(char), 0); | |
117 | return 1; | |||
117 | } | 118 | } | |
118 | 119 | |||
119 | void sendRequestToMoveUp( ) { | 120 | int sendRequestToMoveUp( ) { | |
120 | request[0] = MOVEUP; | 121 | request[0] = MOVEUP; | |
121 | send(sockfd, request, 16 * sizeof(char), 0); | 122 | send(sockfd, request, 16 * sizeof(char), 0); | |
123 | return 1; | |||
122 | } | 124 | } | |
123 | 125 | |||
124 | void sendRequestToMoveRight( ) { | 126 | int sendRequestToMoveRight( ) { | |
125 | request[0] = MOVERIGHT; | 127 | request[0] = MOVERIGHT; | |
126 | send(sockfd, request, 16 * sizeof(char), 0); | 128 | send(sockfd, request, 16 * sizeof(char), 0); | |
129 | return 1; | |||
127 | } | 130 | } | |
128 | 131 | |||
129 | void sendRequestToMoveDown( ) { | 132 | int sendRequestToMoveDown( ) { | |
130 | request[0] = MOVEDOWN; | 133 | request[0] = MOVEDOWN; | |
131 | send(sockfd, request, 16 * sizeof(char), 0); | 134 | send(sockfd, request, 16 * sizeof(char), 0); | |
135 | return 1; | |||
132 | } | 136 | } | |
133 | 137 | |||
134 | void sendRequestToTerminate( ) { | 138 | int sendRequestToTerminate( ) { | |
135 | request[0] = TERMINATE; | 139 | request[0] = TERMINATE; | |
136 | send(sockfd, request, 16 * sizeof(char), 0); | 140 | send(sockfd, request, 16 * sizeof(char), 0); | |
141 | return 1; | |||
137 | } | 142 | } | |
138 | 143 | |||
139 | void sendClickEvent(int button_clicked, int x, int y) { | 144 | int sendClickEvent(int button_clicked, int x, int y) { | |
140 | short button; | 145 | short button; | |
141 | if(button_clicked == 0) { | 146 | if(button_clicked == 0) { | |
142 | button = LEFTCLICK; | 147 | button = LEFTCLICK; | |
143 | } | 148 | } | |
144 | else { | 149 | else { | |
145 | button = RIGHTCLICK; | 150 | button = RIGHTCLICK; | |
146 | } | 151 | } | |
147 | 152 | |||
148 | request[0] = MOUSE; | 153 | request[0] = MOUSE; | |
149 | request[1] = CLICK; | 154 | request[1] = CLICK; | |
150 | request[2] = button; | 155 | request[2] = button; | |
151 | int x_y[2] = {x, y}; | 156 | int x_y[2] = {x, y}; | |
152 | memcpy(&request[3], x_y, 2*sizeof(int)); | 157 | memcpy(&request[3], x_y, 2*sizeof(int)); | |
153 | // printf("Sent Click event %d, %d, %d\n", button, x_y[0], x_y[1]); | 158 | // printf("Sent Click event %d, %d, %d\n", button, x_y[0], x_y[1]); | |
154 | send(sockfd, (void*)request, 16 * sizeof(char), 0); | 159 | send(sockfd, (void*)request, 16 * sizeof(char), 0); | |
160 | return 1; | |||
155 | } | 161 | } | |
156 | 162 | |||
157 | void sendMotionEvent(int x, int y) { | 163 | int sendMotionEvent(int x, int y) { | |
158 | request[0] = MOUSE; | 164 | request[0] = MOUSE; | |
159 | request[1] = MOTION; | 165 | request[1] = MOTION; | |
160 | 166 | |||
161 | int x_y[2] = {x, y}; | 167 | int x_y[2] = {x, y}; | |
162 | memcpy(&request[2], x_y, 2*sizeof(int)); | 168 | memcpy(&request[2], x_y, 2*sizeof(int)); | |
163 | 169 | |||
164 | send(sockfd, request, 16 * sizeof(char), 0); | 170 | send(sockfd, request, 16 * sizeof(char), 0); | |
171 | return 1; | |||
165 | } | 172 | } | |
166 | 173 | |||
167 | /*****END**Network Functions**END*******/ | 174 | /*****END**Network Functions**END*******/ | |
168 | 175 | |||
169 | // OpenGL display function | 176 | int setEnvironmentVariables(int image_width, int image_height, | |
170 | void displayFunc(void) | 177 | int iterations_per_frame) { | |
171 | { | 178 | imageW = image_width; | |
172 | int i, j; | 179 | imageH = image_height; | |
173 | char r,g,b,a; | 180 | max_pass = iterations_per_frame; | |
174 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 181 | d_dst = (char *) malloc(image_width * image_height * 4); | |
175 | 182 | sendEnvironmentVariables( ); | ||
176 | glColor3f(0.0, 0.0, 0.0); | 183 | return 1; | |
177 | glBegin(GL_POINTS); | 184 | } | |
178 | for(j = 0; j < imageH; j++) { | |||
179 | for(i = 0; i < imageW; i++) { | |||
180 | r = d_dst[j*4*imageW + i * 4]; | |||
181 | g = d_dst[j*4*imageW + i * 4 + 1]; | |||
182 | b = d_dst[j*4*imageW + i * 4 + 2]; | |||
183 | a = d_dst[j*4*imageW + i * 4 + 3]; | |||
184 | glColor4b(r, g, b, a); | |||
185 | glVertex2f(i, j); | |||
186 | } | |||
187 | } | |||
188 | glEnd( ); | |||
189 | glutSwapBuffers(); | |||
190 | } // displayFunc | |||
191 | 185 | |||
192 | // OpenGL keyboard function | 186 | #if MACINTOSH_MATHLINK | |
193 | void keyboardFunc(unsigned char k, int, int) | |||
194 | { | |||
195 | invalid_frame = true; | |||
196 | switch (k){ | |||
197 | case '\033': | |||
198 | case 'q': | |||
199 | case 'Q': | |||
200 | printf("Sending server terminate request...\n"); | |||
201 | sendRequestToTerminate( ); | |||
202 | printf("Shutdown done.\n"); | |||
203 | exit(0); | |||
204 | break; | |||
205 | ||||
206 | case '?': | |||
207 | printf("xOff = %5.8f\n", xOff); | |||
208 | printf("yOff = %5.8f\n", yOff); | |||
209 | printf("scale = %5.8f\n", scale); | |||
210 | printf("\n"); | |||
211 | break; | |||
212 | ||||
213 | case '4': // Left arrow key | |||
214 | xOff -= 0.05f * scale; | |||
215 | sendRequestToMoveLeft( ); | |||
216 | break; | |||
217 | ||||
218 | case '8': // Up arrow key | |||
219 | yOff += 0.05f * scale; | |||
220 | sendRequestToMoveUp( ); | |||
221 | break; | |||
222 | ||||
223 | case '6': // Right arrow key | |||
224 | xOff += 0.05f * scale; | |||
225 | sendRequestToMoveRight( ); | |||
226 | break; | |||
227 | ||||
228 | case '2': // Down arrow key | |||
229 | yOff -= 0.05f * scale; | |||
230 | sendRequestToMoveDown( ); | |||
231 | break; | |||
232 | ||||
233 | case '+': | |||
234 | scale /= 1.1f; | |||
235 | sendRequestToZoomIn( ); | |||
236 | break; | |||
237 | ||||
238 | case '-': | |||
239 | scale *= 1.1f; | |||
240 | sendRequestToZoomOut( ); | |||
241 | break; | |||
242 | ||||
243 | default: | |||
244 | break; | |||
245 | } | |||
246 | } // keyboardFunc | |||
247 | 187 | |||
248 | // OpenGL mouse click function | 188 | int main( int argc, char* argv[]) | |
249 | void clickFunc(int button, int, int x, int y) | |||
250 | { | 189 | { | |
251 | sendClickEvent(button, x, y); | 190 | /* Due to a bug in some standard C libraries that have shipped with | |
252 | invalid_frame = true; | 191 | * MPW, zero is passed to MLMain below. (If you build this program | |
253 | } // clickFunc | 192 | * as an MPW tool, you can change the zero to argc.) | |
193 | */ | |||
194 | argc = argc; /* suppress warning */ | |||
195 | return MLMain( 0, argv); | |||
196 | } | |||
254 | 197 | |||
255 | // OpenGL mouse motion function | 198 | #elif WINDOWS_MATHLINK | |
256 | void motionFunc(int x, int y) | 199 | ||
257 | { | 200 | #if __BORLANDC__ | |
258 | sendMotionEvent(x, y); | 201 | #pragma argsused | |
259 | invalid_frame = true; | 202 | #endif | |
260 | } // motionFunc | |||
261 | 203 | |||
262 | void idleFunc() | 204 | int PASCAL WinMain( HINSTANCE hinstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow) | |
263 | { | 205 | { | |
264 | if(invalid_frame) { | 206 | char buff[512]; | |
265 | getNewFrame( ); | 207 | char FAR * buff_start = buff; | |
266 | glutPostRedisplay(); | 208 | char FAR * argv[32]; | |
267 | invalid_frame++; | 209 | char FAR * FAR * argv_end = argv + 32; | |
268 | if(invalid_frame == INVALIDATE_STEP) { | 210 | ||
269 | invalid_frame = 0; | 211 | hinstPrevious = hinstPrevious; /* suppress warning */ | |
270 | } | 212 | ||
271 | } | 213 | if( !MLInitializeIcon( hinstCurrent, nCmdShow)) return 1; | |
214 | MLScanString( argv, &argv_end, &lpszCmdLine, &buff_start); | |||
215 | return MLMain( argv_end - argv, argv); | |||
272 | } | 216 | } | |
273 | 217 | |||
218 | #else | |||
274 | 219 | |||
275 | void init_gl( ) | 220 | int main(int argc, char* argv[]) | |
276 | { | 221 | { | |
277 | glClearColor(0.0, 0.0, 0.0, 0.0); | 222 | return MLMain(argc, argv); | |
278 | ||||
279 | glMatrixMode(GL_PROJECTION); | |||
280 | glLoadIdentity(); | |||
281 | gluOrtho2D(0.0, imageW, 0.0, imageH); | |||
282 | ||||
283 | glMatrixMode(GL_MODELVIEW); | |||
284 | glPointSize(2); | |||
285 | } | 223 | } | |
286 | 224 | |||
287 | //////////////////////////////////////////////////////////////////////////////// | 225 | #endif | |
288 | // Main program | |||
289 | //////////////////////////////////////////////////////////////////////////////// | |||
290 | int main(int argc, char **argv) | |||
291 | { | |||
292 | if(argc!=3) { | |||
293 | fprintf(stderr,"Usage: %s <IP address> <port>\n",argv[0]); | |||
294 | exit(1); | |||
295 | } | |||
296 | ||||
297 | ||||
298 | imageW = IMAGE_W; | |||
299 | imageH = IMAGE_H; | |||
300 | max_pass = MAX_PASS; | |||
301 | ||||
302 | connectToServer(atoi(argv[2]),argv[1]); | |||
303 | sendEnvironmentVariables( ); | |||
304 | ||||
305 | glutInit(&argc, argv); | |||
306 | glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); | |||
307 | glutInitWindowSize(imageW, imageH); | |||
308 | glutCreateWindow(argv[0]); | |||
309 | ||||
310 | init_gl( ); | |||
311 | glutDisplayFunc(displayFunc); | |||
312 | glutIdleFunc(idleFunc); | |||
313 | glutKeyboardFunc(keyboardFunc); | |||
314 | glutMouseFunc(clickFunc); | |||
315 | glutMotionFunc(motionFunc); | |||
316 | glutMainLoop(); | |||
317 | ||||
318 | } // main |