| ../../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 |