void VideoSource::draw() { // to draw the border/text/common stuff, also calls animateValues RectangleBase::draw(); // set up our position glPushMatrix(); glRotatef( xAngle, 1.0, 0.0, 0.0 ); glRotatef( yAngle, 0.0, 1.0, 0.0 ); glRotatef( zAngle, 0.0, 0.0, 1.0 ); glTranslatef(x,y,z); //glDepthMask( GL_FALSE ); //glDepthRange (0.0, 0.9); //glPolygonOffset( 0.2, 0.8 ); float s = 1.0; float t = 1.0; // if the texture id hasn't been initialized yet, this must be the // first draw call init = (texid == 0); // allocate the buffer if it's the first time or if it's been resized if ( init || vwidth != videoSink->getImageWidth() || vheight != videoSink->getImageHeight() ) { resizeBuffer(); } s = (float)vwidth/(float)tex_width; //if ( videoSink->getImageFormat() == VIDEO_FORMAT_YUV420 ) // t = (float)(3*vheight/2)/(float)tex_height; //else t = (float)vheight/(float)tex_height; // X & Y distances from center to edge float Xdist = aspect*scaleX/2; float Ydist = scaleY/2; glBindTexture( GL_TEXTURE_2D, texid ); glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); glPixelStorei( GL_UNPACK_ROW_LENGTH, vwidth ); // only do this texture stuff if rendering is enabled if ( enableRendering ) { videoSink->lockImage(); // only bother doing a texture push if there's a new frame if ( videoSink->haveNewFrameAvailable() ) { if ( videoSink->getImageFormat() == VIDEO_FORMAT_RGB24 ) { glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, vwidth, vheight, GL_RGB, GL_UNSIGNED_BYTE, videoSink->getImageData() ); } // if we're doing yuv420, do the texture mapping for all 3 channels // so the shader can properly work its magic else if ( videoSink->getImageFormat() == VIDEO_FORMAT_YUV420 ) { // experimental single-push method /*glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, vwidth, 3*vheight/2, GL_LUMINANCE, GL_UNSIGNED_BYTE, videoSink->getImageData() );*/ // 3 pushes separate glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, vwidth, vheight, GL_LUMINANCE, GL_UNSIGNED_BYTE, videoSink->getImageData() ); // now map the U & V to the bottom chunk of the image // each is 1/4 of the size of the Y (half width, half height) glPixelStorei(GL_UNPACK_ROW_LENGTH, vwidth/2); glTexSubImage2D( GL_TEXTURE_2D, 0, 0, vheight, vwidth/2, vheight/2, GL_LUMINANCE, GL_UNSIGNED_BYTE, (GLubyte*)videoSink->getImageData() + (vwidth*vheight) ); glTexSubImage2D( GL_TEXTURE_2D, 0, vwidth/2, vheight, vwidth/2, vheight/2, GL_LUMINANCE, GL_UNSIGNED_BYTE, (GLubyte*)videoSink->getImageData() + 5*(vwidth*vheight)/4 ); } } videoSink->unlockImage(); } // draw video texture, regardless of whether we just pushed something // new or not if ( GLUtil::getInstance()->areShadersAvailable() ) { glUseProgram( GLUtil::getInstance()->getYUV420Program() ); glUniform1f( GLUtil::getInstance()->getYUV420xOffsetID(), s ); glUniform1f( GLUtil::getInstance()->getYUV420yOffsetID(), t ); if ( useAlpha ) { glUniform1f( GLUtil::getInstance()->getYUV420alphaID(), borderColor.A ); } } // use alpha of border color for video if set if ( useAlpha ) { glColor4f( 1.0f, 1.0f, 1.0f, borderColor.A ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } else { glColor3f( 1.0f, 1.0f, 1.0f ); } glEnable( GL_TEXTURE_2D ); glBegin( GL_QUADS ); // now draw the actual quad that has the texture on it // size of the video in world space will be equivalent to getWidth x // getHeight, which is the same as (aspect*scaleX) x scaleY glTexCoord2f( 0.0, 0.0 ); glVertex3f( -Xdist, -Ydist, 0.0 ); glTexCoord2f( 0.0, t ); glVertex3f( -Xdist, Ydist, 0.0 ); glTexCoord2f( s, t ); glVertex3f( Xdist, Ydist, 0.0 ); glTexCoord2f( s, 0.0 ); glVertex3f( Xdist, -Ydist, 0.0 ); glEnd(); glDisable( GL_TEXTURE_2D ); if ( GLUtil::getInstance()->areShadersAvailable() ) glUseProgram( 0 ); if ( vwidth == 0 || vheight == 0 ) { glPushMatrix(); glTranslatef( -(getWidth()*0.275f), getHeight()*0.3f, 0.0f ); float scaleFactor = getTextScale(); glScalef( scaleFactor, scaleFactor, scaleFactor ); std::string waitingMessage( "Waiting for video..." ); font->Render( waitingMessage.c_str() ); glPopMatrix(); } // draw a basic X in the top-left corner for signifying that rendering is // disabled, differentiating between muting and just having the texture // push disabled via the color if ( !enableRendering ) { float dist = getWidth() * 0.1f; glBegin( GL_LINES ); glLineWidth( 3.0f ); glColor4f( secondaryColor.R, secondaryColor.G, secondaryColor.B, secondaryColor.A ); glVertex3f( -Xdist, Ydist - dist, 0.0f ); glVertex3f( -Xdist + dist, Ydist, 0.0f ); glVertex3f( -Xdist, Ydist, 0.0f ); glVertex3f( -Xdist + dist, Ydist - dist, 0.0f ); glEnd(); } // see above if ( useAlpha ) { glDisable( GL_BLEND ); } glPopMatrix(); }
int main(int argc,char *argv[]) { struct sigaction nvt,old; memset(&nvt,0,sizeof(nvt)); nvt.sa_handler = &handlerInt; sigaction(SIGINT,&nvt,&old); signal(SIGINT,&handlerInt); struct sockaddr_in emetteur_addr,receveur_addr; int unixSocket, socketEmetteur,socketRecepteur; struct hostent *hp; int ttl; struct ip_mreq imr; struct sockaddr_in serv_addr; struct sockaddr_un unixAddr; char *data; char sendbuf[1500]; struct timeb tp; socklen_t len=sizeof(serv_addr); int serverSocket, servlen,n, retread,s; char fromServer[MAXLINE]; char fromUser[MAXLINE]; struct addrinfo *result,*rp; struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = PF_INET; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ hints.ai_flags = 0; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ if (argc != 3){ usage(); exit(1); } s = getaddrinfo(argv[1], argv[2], &hints, &result); if( s != 0){ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); exit(1); } /* Verifier le nombre de paramètre en entrée */ /* clientTCP <hostname> <numero_port> */ for (rp = result; rp != NULL; rp = rp->ai_next) { serverSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (serverSocket == -1) continue; if (connect(serverSocket, rp->ai_addr, rp->ai_addrlen) != -1) break; /* Success */ close(serverSocket); } if (rp == NULL) { /* No address succeeded */ fprintf(stderr, "Could not connect\n"); exit(EXIT_FAILURE); } serverSocketInt = serverSocket; freeaddrinfo(result); /**socket pour multicast cote emetteur**/ /* * Remplir la structure serv_addr avec l'adresse du serveur */ memset( (char *) &emetteur_addr,0, sizeof(emetteur_addr) ); emetteur_addr.sin_family = PF_INET; emetteur_addr.sin_addr.s_addr = inet_addr(GROUP); emetteur_addr.sin_port = htons(PORT); hp = (struct hostent *)gethostbyname (GROUP); if (hp == NULL) { exit(1); } // bcopy( (char *) hp->h_addr, (char *)& serv_addr.sin_addr, hp->h_length); memcpy( &emetteur_addr.sin_addr , hp->h_addr, hp->h_length); //printf ("IP address: %s\n", inet_ntoa (serv_addr.sin_addr)); /* * Ouvrir socket UDP */ if ((socketEmetteur = socket(PF_INET, SOCK_DGRAM, 0)) <0) { perror ("erreur socket"); exit (1); } ttl=1; if (setsockopt(socketEmetteur, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) <0){ perror ("setsockopt"); exit (1); } /**-------------FIN initialisation emetteur----------**/ /**socket pour multicast cote recepteur**/ memset( (char *) &receveur_addr,0, sizeof(receveur_addr) ); receveur_addr.sin_family = PF_INET; receveur_addr.sin_addr.s_addr = htonl(INADDR_ANY); receveur_addr.sin_port = htons(PORT); /*creation socket*/ if ((socketRecepteur = socket(PF_INET, SOCK_DGRAM, 0)) <0) { perror ("erreur socket"); exit (1); } imr.imr_multiaddr.s_addr = inet_addr(GROUP); imr.imr_interface.s_addr =INADDR_ANY; if (setsockopt(socketRecepteur,IPPROTO_IP,IP_ADD_MEMBERSHIP, &imr, sizeof(imr)) <0){ perror ("setsockopt1"); exit (1); } // en cas de reutilisation d'un port unsigned int on=1; if (setsockopt(socketRecepteur,SOL_SOCKET,SO_REUSEADDR, &on, sizeof(on)) <0){ perror ("setsockopt2"); exit (1); } if (bind(socketRecepteur,(struct sockaddr *) &receveur_addr,sizeof(receveur_addr))<0){ perror ("setsockopt3"); exit (1); } /**-------------FIN initialisation recepteur----------**/ disconnected=0; /**instruction**/ printf("now you are connected to the server\n"); printf("====INSTRUCTION====\n"); printf("press 'p' to participate to the lecturer\n"); printf("press 'l' to let the token\n"); printf("press 'd' to deconnect to the server\n"); int count=0; for(;;){ if (!participate){ if(disconnected){ quitApp(serverSocket,socketRecepteur,socketEmetteur); }else { participateRequest(serverSocket,socketRecepteur,&jeton,imr); } }else{ if (!jeton){ //si tu n'as pas de jeton tu ne parles pas tu attends un message waitingMessage(socketRecepteur,serverSocket, receveur_addr,imr); } else if (jeton){ //si tu as un jeton tu parles sendMessage(socketEmetteur,serverSocket,emetteur_addr); } } } close (serverSocket); }