source: branches/nanovis2/packages/vizservers/nanovis/socket/RenderClient.cpp @ 3305

Last change on this file since 3305 was 3305, checked in by ldelgass, 11 years ago

sync with trunk

  • Property svn:eol-style set to native
File size: 15.9 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/* ======================================================================
3 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
4 *           Purdue Rendering and Perceptualization Lab (PURPL)
5 *
6 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
7 *
8 *  See the file "license.terms" for information on usage and
9 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 * ======================================================================
11 */
12#include <stdlib.h>
13#include <sstream>
14#include <string.h>
15#include <time.h>
16#include <iostream>
17#include <assert.h>
18
19#include <GL/glut.h>
20
21#include "RenderClient.h"
22#include "Event.h"
23
24using namespace std;
25
26Event* event[5000];
27int cur_event = 0;
28
29int width, height;
30
31RenderClient::RenderClient()
32{
33}
34
35RenderClient::RenderClient(std::string& remote_host, int port_num)
36{
37    //screen_size = sizeof(float)*4*512*512;    //float
38    screen_size = 3*width*height;       //unsigned byte
39    screen_buffer = new char[screen_size];
40
41    socket_num = port_num;
42    host = remote_host;
43
44    //init socket server
45    std::cout << "client running....\n";
46
47    try {
48        // Create the socket
49        client_socket = new ClientSocket(host, socket_num);
50        //client_socket->set_non_blocking(true);
51        fprintf(stderr, "client socket initialized\n");
52    } catch (SocketException& e) {
53        std::cout << "Exception was caught:" << e.description() << "\nExiting.\n";
54    }
55}
56
57void RenderClient::send(std::string& msg)
58{
59    try {
60        //printf("client: send()\n");
61        *client_socket << msg;
62    } catch (SocketException&) {
63    }
64}
65
66void RenderClient::receive(std::string& msg)
67{
68    std::string buf="";
69    try {
70        fprintf(stderr, "client: receive()\n");
71        fflush(stdout);
72        *client_socket >> buf;
73        msg = buf;
74    } catch (SocketException&){
75    }
76}
77
78bool RenderClient::receive(char* s, int size)
79{
80    try {
81        //printf("client: receive()\n");
82        bool ret = client_socket->recv(s, size);
83        return true;
84    } catch (SocketException&) {
85        return false;
86    }
87}
88
89bool RenderClient::send(char* s, int size)
90{
91    try {
92        //printf("client: receive()\n");
93        bool ret = client_socket->send(s, size);
94        return true;
95    } catch (SocketException&) {
96        return false;
97    }
98}
99
100RenderClient* client;
101
102bool loaded = false;
103
104float live_rot_x = 0.;
105float live_rot_y = 0.;
106float live_rot_z = 0.;
107
108float live_obj_x = 0.;
109float live_obj_y = 0.;
110float live_obj_z = -3.;
111
112int left_last_x, left_last_y, right_last_x, right_last_y;
113bool left_down, right_down;
114bool render_done = true;
115
116/* GLUT callback Handlers */
117void resize(int _width, int _height)
118{
119    delete[] client->screen_buffer;
120    client->screen_size = 3*_width*_height;
121    client->screen_buffer = new char[client->screen_size];
122
123    width = _width;
124    height = _height;
125
126    glViewport(0, 0, width, height);
127    glMatrixMode(GL_PROJECTION);
128    glLoadIdentity();
129    gluPerspective(60, float(width)/height, 0.1, 50.0);
130    //glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
131
132    glMatrixMode(GL_MODELVIEW);
133    glLoadIdentity() ;
134    glTranslatef(live_obj_x, live_obj_y, live_obj_z);
135    glRotated(live_rot_x, 1., 0., 0.);
136    glRotated(live_rot_y, 0., 1., 0.);
137    glRotated(live_rot_z, 0., 0., 1.);
138}
139
140void draw_buttons()
141{
142    glPushMatrix();
143
144    glViewport(0, 0, width, height);
145    glMatrixMode(GL_PROJECTION);
146    glLoadIdentity();
147    glOrtho(0, width, 0, height, -0.09, 1);
148    glMatrixMode(GL_MODELVIEW);
149    glLoadIdentity();
150
151    glDisable(GL_BLEND);
152    glEnable(GL_BLEND);
153
154    //loaddata button
155    glColor4f(0.5, 0.5, 0.5, 0.5);
156    glBegin(GL_QUADS);
157    glVertex2d(10, 10);
158    glVertex2d(60, 10);
159    glVertex2d(60, 40);
160    glVertex2d(10, 40);
161    glEnd();
162
163    glDisable(GL_BLEND);
164    glPopMatrix();
165}
166
167void display()
168{
169
170    if (loaded) {
171        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
172        //glDrawPixels(width, height, GL_RGBA, GL_FLOAT, client->screen_buffer);       
173        //bzero(client->screen_buffer, client->screen_size);
174        glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, client->screen_buffer);   
175        glFlush();
176        glutSwapBuffers();
177        return;
178    }
179 
180    render_done = false;
181
182    //const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
183
184    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
185
186    glViewport(0, 0, width, height);
187    glMatrixMode(GL_PROJECTION);
188    glLoadIdentity();
189    gluPerspective(60, float(width)/height, 0.1, 50.0);
190    //glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
191
192    glMatrixMode(GL_MODELVIEW);
193    glLoadIdentity() ;
194    glTranslatef(live_obj_x, live_obj_y, live_obj_z);
195    glRotated(live_rot_x, 1., 0., 0.);
196    glRotated(live_rot_y, 0., 1., 0.);
197    glRotated(live_rot_z, 0., 0., 1.);
198
199    glEnable(GL_DEPTH_TEST);
200
201    glEnable(GL_LIGHTING);
202    //glutSolidCone(1,1,slices,stacks);
203    glutSolidCube(1.);
204    glDisable(GL_LIGHTING);
205
206    //draw buttons
207    //draw_buttons();
208
209    glFlush();
210    glutSwapBuffers();
211
212    render_done = true;
213}
214
215void key(unsigned char key, int x, int y)
216{
217    cerr << "client: key()" << endl;
218    std::stringstream msgstream;
219    std::string msg;
220    std::string msg2;
221
222    switch (key) {
223    case 27 :
224    case 'q':
225        exit(0);
226        break;
227
228    case 'l':
229        cerr << "client: load" << endl;
230        //msgstream << "command=0" << endl;
231        msgstream << "load" << endl;
232        msg = msgstream.str();
233        client->send(msg);
234        loaded = true;
235        break;
236
237    case 'o':
238        msgstream << "command=" << "1" << endl;
239        msg = msgstream.str();
240        client->send(msg);
241        break;
242
243    case '+':
244        msgstream << "command=" << "4" << endl;
245        msg = msgstream.str();
246        client->send(msg);
247        break;
248
249    case '-':
250        msgstream << "command=" << "5" << endl;
251        msg = msgstream.str();
252        client->send(msg);
253        break;
254
255    case 'x':
256        //msgstream << "and=" << "5" << endl;
257        msgstream << "cut x " << "off" << endl;
258        msg = msgstream.str();
259        cerr << "client: " << msg << endl;
260        client->send(msg);
261        break;
262
263    case 'X':
264        msgstream << "cut x " << " on" << endl;
265        msg = msgstream.str();
266        cerr << "client: " << msg << endl;
267        client->send(msg);
268        break;
269
270    case 'y':
271        msgstream << "cut y " << "off" << endl;
272        msg = msgstream.str();
273        cerr << "client: " << msg << endl;
274        client->send(msg);
275        break;
276
277    case 'Y':
278        msgstream << "cut y " << "on" << endl;
279        msg = msgstream.str();
280        cerr << "client: " << msg << endl;
281        client->send(msg);
282        break;
283
284    case 'z':
285        msgstream << "cut z " << "off" << endl;
286        msg = msgstream.str();
287        cerr << "client: " << msg << endl;
288        client->send(msg);
289        break;
290
291    case 'Z':
292        msgstream << "cut z " << "on" << endl;
293        msg = msgstream.str();
294        cerr << "client: " << msg << endl;
295        client->send(msg);
296        break;
297
298    default:
299        return;
300    }
301   
302    /*
303      for(int j=0; j<512; j=j+1){
304      cerr << "client read: " << j << endl;
305      client->receive(client->screen_buffer + j*4*512, 4*512);  //unsigned byte
306      }
307    */
308
309    client->receive(client->screen_buffer, client->screen_size);        //unsigned byte
310
311    //cin >> msg;
312    //strncpy(client->screen_buffer, msg.c_str(), 512*512*4);
313
314    display();
315    //glutPostRedisplay();
316
317    cerr << "client: key() done" << endl;
318}
319
320void update_rot(int delta_x, int delta_y)
321{
322    live_rot_x += delta_x;
323    live_rot_y += delta_y;
324
325    if (live_rot_x > 360.0)
326        live_rot_x -= 360.0;   
327    else if (live_rot_x < -360.0)
328        live_rot_x += 360.0;
329
330    if (live_rot_y > 360.0)
331        live_rot_y -= 360.0;   
332    else if (live_rot_y < -360.0)
333        live_rot_y += 360.0;
334}
335
336void update_trans(int delta_x, int delta_y, int delta_z)
337{
338    live_obj_x += delta_x*0.01;
339    live_obj_y += delta_y*0.01;
340    live_obj_z += delta_z*0.01;
341}
342
343bool test_in_box(int box_x0, int box_y0, int box_x1, int box_y1, int x, int y)
344{
345    return (box_x0<=x && box_x1>=x && box_y0<=y && box_y1>=y);
346}
347
348void mouse(int button, int state, int x, int y)
349{
350    if (button == GLUT_LEFT_BUTTON) {
351        left_last_x = x;
352        left_last_y = y;
353
354        if (state == GLUT_DOWN) {
355            left_down = true;
356            right_down = false;
357        } else {
358            left_down = false;
359            right_down = true;
360        }
361    } else {
362        right_last_x = x;
363        right_last_y = y;
364
365        if (state == GLUT_DOWN) {
366            left_down = false;
367            right_down = true;
368        } else {
369            left_down = true;
370            right_down = false;
371        }
372    }
373}
374
375void motion(int x, int y)
376{
377    cerr << "client: motion() " << endl;
378
379    if (render_done) {
380        int old_x, old_y;       
381
382        if (left_down) {
383            old_x = left_last_x;
384            old_y = left_last_y;   
385        } else {
386            old_x = right_last_x;
387            old_y = right_last_y;   
388        }
389
390        int delta_x = x - old_x;
391        int delta_y = y - old_y;
392
393        //more coarse event handling
394        if (abs(delta_x)<5 && abs(delta_y)<5)
395            return;
396
397        if (left_down) {
398            left_last_x = x;
399            left_last_y = y;
400
401            update_rot(delta_y, delta_x);
402            std::stringstream msgstream;
403            //msgstream << "command=" << "2" << "&delta_x=" << delta_y << "&delta_y=" << delta_x << endl;
404            msgstream << "camera " << live_rot_x << " " << live_rot_y << " " << live_rot_z << " " << live_obj_z << endl;
405            std::string msg;
406            msg = msgstream.str();
407            std::cout << "client msg: " << msg <<"\n";
408            //client->send(msg);
409            client->send((char*) msg.c_str(), (int) strlen(msg.c_str()));
410        } else {
411            right_last_x = x;
412            right_last_y = y;
413
414            update_trans(0, 0, delta_y);
415            std::stringstream msgstream;
416            //msgstream << "command=" << "3" << "&delta_x=" << delta_y << "&delta_y=" << delta_x << endl;
417            msgstream << "camera " << live_rot_x << " " << live_rot_y << " " << live_rot_z << " " << live_obj_z << endl;
418            std::string msg;
419            msg = msgstream.str();
420            std::cout << "client msg: " << msg <<"\n";
421            //client->send(msg);
422            client->send((char*) msg.c_str(), (int) strlen(msg.c_str()));
423        }
424
425        client->receive(client->screen_buffer, client->screen_size);
426
427        /*
428          for (int j=0; j<512; j=j+4) {
429              unsigned int r,g,b,a;
430              r = client->screen_buffer[j];
431              g = client->screen_buffer[j+1];
432              b = client->screen_buffer[j+2];
433              a = client->screen_buffer[j+3];
434              //fprintf(stderr, "(%d %d %d %d) ", r,g,b,a);     //unsigned byte
435              fprintf(stderr, "(%X %X %X %X) ", r,g,b,a);       //unsigned byte
436          }
437        */
438
439        display();
440        cerr << "client: motion() done " << endl;
441    }
442}
443
444void idle()
445{
446    /*
447      struct timespec ts;
448      ts.tv_sec = 0;
449      ts.tv_nsec = 100000000;
450
451      nanosleep(&ts, 0);
452    */
453
454    //send requests
455    Event* cur = event[cur_event];
456    std::stringstream msgstream;
457    std::string msg;
458
459    switch (cur->type) {
460    case 0: //rotate
461        msgstream << "camera " << cur->parameter[0] << " "
462                  << cur->parameter[1] << " "
463                  << cur->parameter[2] << " " << endl;
464        break;
465
466    case 1: //move
467        msgstream << "move " << cur->parameter[0] << " "
468                  << cur->parameter[1] << " "
469                  << cur->parameter[2] << " " << endl;
470        break;
471
472    case 2: //other
473        msgstream << "refresh " << cur->parameter[0] << " "
474                  << cur->parameter[1] << " "
475                  << cur->parameter[2] << " " << endl;
476        break;
477
478    default:
479        return;
480    }
481
482    msg = msgstream.str();
483    //std::cout << "client msg: " << msg <<"\n";
484
485    //start timer
486    client->send((char*) msg.c_str(), (int) strlen(msg.c_str()));
487    client->receive(client->screen_buffer, client->screen_size);
488    //end timer
489}
490
491const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
492const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
493const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
494const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
495
496const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
497const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
498const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
499const GLfloat high_shininess[] = { 100.0f };
500
501void init_client(char* host, char* port, char* file)
502{
503    //load the event file
504    FILE* fd = fopen(file, "r");
505    //load 5000 events
506    for (int i=0; i<5000; i++) {
507        int type;
508        float param[3];
509        fscanf(fd, "%d %f %f %f\n", &type, param, param+1, param+2);
510        event[i] = new Event(type, param, 0);
511        fprintf(stderr, "%d %f %f %f\n", type, param[0], param[1], param[2]);
512    }
513    fclose(fd);
514
515    //std::string host = "localhost";
516    //hostname -i
517    //std::string host = "128.46.137.192";
518 
519    std::string hostname = host;
520    client = new RenderClient(hostname, atoi(port));
521
522    //point stdin stdout to socket
523    /*
524      close(0);
525      close(1);
526      dup2(client->Socket::m_sock, 0);
527      dup2(client->Socket::m_sock, 1);
528    */
529 
530    std::string msg1 = "hello";
531    std::string msg2 = " ";
532
533    //cout << msg1;
534    //cin >> msg2;
535
536    client->send(msg1);
537    client->receive(msg2);
538 
539    cerr << "client: msg received - " << msg2 << endl;
540    cerr << "connection to server established" << endl;
541}
542
543void print_gl_info()
544{
545    fprintf(stderr, "OpenGL vendor: %s %s\n", glGetString(GL_VENDOR), glGetString(GL_VERSION));
546    fprintf(stderr, "OpenGL renderer: %s\n", glGetString(GL_RENDERER));
547}
548
549void menu_cb(int entry)
550{
551    std::stringstream msgstream;
552    std::string msg;
553    std::string msg2;
554    switch (entry) {
555    case 0:
556        msgstream << "command=" << "0";
557        msgstream >> msg;
558        client->send(msg);
559
560        client->receive(msg2);
561       
562        loaded = true;
563        break;
564
565    case 1:
566        msgstream << "command=" << "1";
567        msgstream >> msg;
568        client->send(msg);
569
570        client->receive(msg2);
571        break;
572
573    case 2:
574        msgstream << "command=" << "2";
575        msgstream >> msg;
576        client->send(msg);
577
578        client->receive(msg2);
579        break;
580    }
581}
582
583void help(const char *argv0)
584{
585    fprintf(stderr,
586            "Syntax: %s addr port eventfile\n",
587            argv0);
588    exit(1);
589}
590
591/* Program entry point */
592int main(int argc, char *argv[])
593{
594    //parameters:  hostip and port and event file
595    if (argc!=4)
596        help(argv[0]);
597
598    width =512; height=512;
599
600    init_client(argv[1], argv[2], argv[3]);
601
602    glutInit(&argc, argv);
603    glutInitWindowSize(width,height);
604    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
605
606    glutCreateWindow("Client");
607
608    /*
609      glutCreateMenu(menu_cb);
610      glutAddMenuEntry("load data ", 0);
611      glutAddMenuEntry("toggle mode (on/off screen)", 1);
612      glutAttachMenu(GLUT_RIGHT_BUTTON);
613    */
614
615    glutReshapeFunc(resize);
616    glutDisplayFunc(display);
617    glutMouseFunc(mouse);
618    glutMotionFunc(motion);
619    glutKeyboardFunc(key);
620    glutIdleFunc(idle);
621
622    glClearColor(0.,0.,0.,0.);
623
624    glDepthFunc(GL_LESS);
625    glDepthRange(0,1);
626    glDisable(GL_DEPTH_TEST);
627
628    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
629    glDisable(GL_BLEND);
630
631    glDisable(GL_ALPHA_TEST);
632
633    glEnable(GL_LIGHT0);
634    glEnable(GL_LIGHTING);
635
636    glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
637    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
638    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
639    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
640
641    glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
642    glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
643    glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
644    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
645
646    print_gl_info();
647
648    left_down = false;
649    right_down = false;
650
651    glutMainLoop();
652
653    return 0;
654}
655
Note: See TracBrowser for help on using the repository browser.