Saturday, August 25, 2012

OpenGL :: Advanced control of the camera (Part 1/2) :: Material 8


OpenGL :: Advanced control of the camera (Part 1/2)  :: Material 8




Principle of a camera trackball

The name trackball has this weird device that replaces the mouse where you turn right into a ball. Here I learned the term free software cross-platform Google Earth

User Image
Google Earth


In Google Earth indeed using the mouse to rotate around the Earth. We will therefore reproduce this principle that we will have a camera to look at an object / part of a scene from all angles.

Rotate the mouse



By holding down the left mouse button, the mouse movements will shoot the scene:
  • a horizontal movement of the mouse provides a horizontal rotation of the stage (thus about its vertical axis).
  • a vertical movement of the mouse provides a vertical rotation of the stage.

These movements are illustrated in the diagrams below:

User Image
Horizontal movement of the mouse


User Image
Vertical movement of the mouse


Note in passing, and we see the equivalent in the code, that is not really the camera turns but the scene , even if it is more or less the same. This is the case for this type of camera. For the camera FreeFly we'll see after this is indeed the camera and not the scene move.


Zoom wheel



To take back or otherwise bring us closer to the object / scene we want to see, we'll just use the wheel. A shot wheel forward to zoom in, a shot back wheel to zoom out, nothing more intuitive:

User Image
Rotate the mouse wheel


Here it is the camera that moves, we see once again how it affects the code.


And keyboard?



It is possible to argue that all the mice do not have a wheel. In this case nothing prevents you to use the keyboard to zoom out.
Here we only use the keyboard for one thing: Reset all the rotation stage with the key User ImageSDLK_HOME SDL).

Some basics of C + +

Now that we know what we do with our camera, must be a little interlude learning C + +.
We are going to use and combine all the features of our camera in a class : TrackBallCamera. Course M @ teo explain the concept classes in detail. Let's look at it as an extension of a structure . remember C struct allowed to store multiple fields in a single type:Code: C-Select






1
2
3
4
5
6
7
struct  NomDeVotreStructure 
{ 
    long  variable1 , 
    long  variable2 , 
    int  autreVariable ; 
    dual  nombreDecimal ; 
}


Class has, in addition to attributes , the methods . These methods are like functions that apply to instances of this class.


Ooh là là many new words! Bodies eg what is it?

Imagine a class named chair. A chair has certain attributes: height, number of feet area.
So write:Code: C + +-Select

1
2
3
4
5
6
7
class  Chair 
{ 
protected : 
        int  height , 
        int  nombre_de_pieds , 
        string  matter ; 
}


Once the class is declared in the c% u0153ur program you want to be able to use (chairs). It thus creates "instances" of the class "chair" by simply declaring a variable of type chair.
Example:Code: C + +-Select

1
Chair  machaise ;


Note that C + + structures and classes are types. So no need to write a typedef Class Chair Chair, for example.


You could see a strange word in my example: protected . Without going into detail, this means that the attributes declared protected can not be accessed from outside the class, but only by its methods.

Methods precisely what is it?


A method is a function but as it applies to a specific instance of the class.
Returning to our example of the chair. Suppose we wanted to remove one foot at our chair.
In C we should use a function enleverPied passing in any chair change. In C + + is called a direct method on an instance of the class. Example: The class declaration chair in Chaise.hCode: C + +-Select






1
2
3
4
5
6
7
8
9
class  Chair 
{ 
public : 
        void  enleverPied (); 
protected : 
        int  height , 
        int  nombre_de_pieds , 
        string  matter ; 
}


The implementation of the methods of the class chair in Chaise.cpp
Code: C + + - Select
1
2
3
4
5
6
# Include "chaise.h"

void  chair :: enleverPied () 
{ 
        nombre_de_pieds - ; 
}


Call in the program body
And now we are interested in the method call enleverPied on an instance:Code: C + +-Select

1
2
Chair  machaise ; 
machaise . enleverPied ();


As you can see it calls a method would be used as an attribute instance . MyMethod ();
When the program enters the code of the method he applies therefore to the desired instance, and uses the attributes of the proceeding.

Note that here I put the method in public and not protected so you can call from outside the class (that is to say from the body of the program).


Two special methods



There are two special methods that are not called directly by the user: the constructor and destructor. The constructor is called when the object is initialized, usually to his statement. This is a method without a return type, which carries the name of the class and initializes the attributes with initial values: Example: Declaration of the Manufacturer in Chaise.hCode: C + +-Select








 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Class  Chair 
{ 
public : 
        Chaise ()  / / constructor not returns nothing, but it may have parameters 
        void  enleverPied (); 
protected : 
        int  height , 
        int  nombre_de_pieds , 
        string  matter ; 
}


Constructor implementation in Chaise.cpp
Code: C + + - Select
1
2
3
4
5
6
Chair :: chair () 
{ 
        height  =  1 ; 
        nombre_de_pieds  =  4 ; 
        matter  =  "black" ; 
}


And so this constructor will be called as soon as you instantiate an object in the main body of the program:Code: C + +-Select


1
2
Chair  machaise ;  / / triggers the constructor call 
machaise . enleverPied ()  / / so I know that she now has a chair for 3 to 4 feet start thanks to constructor


The destructive meanwhile is called automatically when the object is destroyed. In this case I have nothing special to do in the destructor, but if we had allocated memory dynamically (dynamic attributes of the class), it is destructive in that it must be destroyed for not memory leak. As the constructor, the destructor is called the class preceded by the symbol " ~ ". Here I will simply display a message when the destruction: Declaration destructive in Chaise.hCode: C + +-Select



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Class  Chair 
{ 
public : 
        Chaise ()  / / constructor returns nothing, but it may have arguments 
        void  enleverPied (); 
        ~ chair ()  / / destructor returns nothing, has no arguments, and above the symbol ~ 
protected : 
        int  height ; 
        int  nombre_de_pieds , 
        string  matter ; 
}


Implementation of the destructor in Chaise.cpp
Code: C + + - Select
1
2
3
4
5
6
# Include <iostream> 
... 
chair :: ~ chair () 
{ 
        std :: cout  <<  "Goodbye little chair."  <<  std :: endl ; 
}


In the body of the program call the destructor is automatically at the end of the block where the instance is declared.
Example:Code: C + +-Select

1
2
3
4
5
6
7
int  main () 
{ 
        chair  machaise ;  / / constructor call 
        machaise . enleverPied ()  / / the poor that must hurt

        return  0 ;  / / on the left hand block, so it destroys all variables -> Automatic call the destructor of the instance machaise chair. 
}


Dynamic allocation



If you are reading the OpenGL tutorial is that you probably know the dynamic allocation in C:Code: C-Select


1
2
struct  chair  *  machaise ; 
machaise  =  malloc ( sizeof ( struct  chair ));


In C + + operator is generally used new like this:Code: C + +-Select


1
2
Chair  *  machaise ; 
machaise  =  new  Chair ();


We note here the use of () after chair which clearly sought to build an object. Once the allocated memory, the class constructor is called automatically. For Destruction, delete replaces free you know:Code: C + +-Select




1
2
3
4
Chair  *  machaise ; 
machaise  =  new  Chair (); 
machaise -> enleverPied (); 
delete  machaise ;


UML representation



I'm not going to do a course in modeling UML but just show you a graphical way to represent a class. I will use this symbolism throughout the tutorial to briefly summarize the features of a class:

User Image


This gives for example take our beloved chair:

User Image

Implementation of the camera

We implement the trackball camera with the concept of class as we have just seen.
As we have seen above we have to manage three types of events:
  • pressing the left button of the mouse we will activate the mouse movement if this button is pressed;
  • the movement of the mouse to change the orientation of the scene;
  • pressing the HOME key to return the orientation of the scene to its original value.


In the main body of our program SDL (next section) we will have to send the events necessary for the operation of the camera.know how you put a camera manually with gluLookAt . Here is the method look TrackBallCamera our class who will call thegluLookAt for us. In the code for displaying the scene so that we will call this method. We will also add two other methods to configure the sensitivity of our camera:




  • setMotionSensivity: to determine the speed of rotation of the scene according to the movement of the pixel mouse;
  • setScrollSensivity: to determine how much zoom in / out when using the mouse wheel.


All this therefore results in the following UML and C + +:

Simplified UMLStatement C + +
User ImageCode: C + + - Select
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class  TrackBallCamera 
{ 
public : 
    TrackBallCamera ();

    virtual void OnMouseMotion(const SDL_MouseMotionEvent & event);
    virtual void OnMouseButton(const SDL_MouseButtonEvent & event);
    virtual void OnKeyboard(const SDL_KeyboardEvent & event);

    virtual void look();
    virtual void setMotionSensivity(double sensivity);
    virtual void setScrollSensivity(double sensivity);

    virtual ~TrackBallCamera();
protected:
    double _motionSensivity;
    double _scrollSensivity;
    bool _hold;
    double _distance;
    double _angleY;
    double _angleZ;
    SDL_Cursor * _hand1;
    SDL_Cursor * _hand2;
};;


I took the opportunity to add all the attributes that we will use. A little explanation is therefore required:
  • Double _motionSensivity : used to store the camera's sensitivity to movements of the mouse;
  • Double _scrollSensivity : camera sensitivity to mouse scroll ('not' a shift);
  • _hold bool : are we currently hold the left mouse button?
  • Double _distance : distance between the camera and the center of the stage;
  • Double _angleY ​​: tilt angle of the scene (in green in the diagram above);
  • Double _angleZ : horizontal rotation angle of the scene (ie around the vertical blue on the diagram).


The last two attributes are two mouse cursors that we use:
User Image

_hand1 in normal _hand2 when the left mouse button is pressed.

You will notice in the above passage that I class attributes underscore symbol "_". This allows the implementation of methods to identify more quickly temporary variables (or parameters) and attributes. You're obviously not forced to follow this rule.


Builder



In the constructor we simply initialize all attributes to known initial values. Do not leave anything that can be used without having been initialized. portion the less obvious may be the creation of two cursors. To make things easier I relegated all the work in a function added to sdlglutils : cursorFromXPM (included in the final archive).Code: C + +-Select




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
TrackBallCamera :: TrackBallCamera () 
{ 
    const  char  * hand1 []  = 
        { 
            / * width height num_colors chars_per_pixel * / 
            "16 16 3 1" , 
            / * colors * / 
            "X c # 000000" , 
            ". c # ffffff" , 
            " c None " , 
            / * pixels * / 
            "XX" , 
            "XX X.. XXX" , 
            "X.. XX .. X.. X" , 
            "X. X. .. XX. XX" , 
            "X . X.. X.. XX.X " , 
            "X.. X.. X.. X.. X" , 
            "XX X. ...... X.. X" , 
            "X. XX. ......... X " , 
            "X. .. X. ........ X" , 
            "X ........... X" , 
            "X .......... X " , 
            "X ......... X" , 
            "X ........ X" , 
            "X ..... . X " , 
            "X ..... X" , 
            "X X. ....." , 
            "0,0" 
        };

    const  char  * hand2 []  = 
        { 
            / * width height num_colors chars_per_pixel * / 
            "16 16 3 1" , 
            / * colors * / 
            "X c # 000000" , 
            ". c # ffffff" , 
            "c None" , 
            / * pixels * / 
            "" , 
            "" , 
            "" , 
            "" , 
            "XX XX XX" , 
            "X. X.. X.. XX" , 
            "X ....... XX" , 
            "X. ....... X " , 
            "XX ......... X" , 
            "X .......... X" , 
            "X ....... ... X " , 
            "X ......... X" , 
            "X ........ X" , 
            "X ...... X" , 
            "X X ..... " , 
            "X. ..... X" , 
            "0.0" 
        }; 
    _hand1  =  cursorFromXPM ( hand1 )  / / create the normal cursor 
    _hand2  =  cursorFromXPM ( hand2 )  / / creation of cursor used when the button is pressed 
    SDL_SetCursor ( _hand1 )  / / cursor activation normal 
    _hold  =  false ;  / / initially we assume that the button is not held 
    _angleY  ​​=  0 ; 
    _angleZ  =  0 ; 
    _distance  =  2 ;  / / initial distance from the camera to the center stage 
    _motionSensivity  =  0.3 ; 
    _scrollSensivity  =  1 ; 
}


As you can see, the constructor function uses SDL SDL_SetCursor, which should not be performed before creating your SDL window. Thus the camera will be created after initialization of the application.


On Mouse Motion



This method is the most important class and yet one of the shortest. Remember the principle of the camera: when the mouse is moved, if the left mouse button is pressed, then the scene turns. Let's see how this translates into code:Code: C + +-Select


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void  TrackBallCamera :: OnMouseMotion ( const  SDL_MouseMotionEvent  &  event ) 
{ 
    if  ( _hold )  / / if we keep the left mouse button 
    { 
        _angleZ  + =  event . xrel * _motionSensivity ;  / / X movement of the mouse -> change the horizontal rotation 
        _angleY  ​​+ =  event . yrel * _motionSensivity ;  / / Y movement of the mouse -> change the vertical rotation 
        / / to avoid problems, we limit the vertical rotation angles between -90 ° and 90 ° 
        if  ( _angleY  ​​>  90 ) 
            _angleY  ​​=  90 ; 
        else  if  ( _angleY  ​​<  - 90 ) 
            _angleY  ​​=  - 90 ; 
    } 
}


On Mouse Button



This method allows us to manage two things:
  • support and releasing the left mouse button;
  • the movement of the mouse wheel.


When you move the wheel, two successive events are generated: SDL_MOUSEBUTTONDOWN and SDL_MOUSEBUTTONUP .So we will use that first.


Code: C + + - Select
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    

        for the left button 
    { 
        if  (( _hold ) && ( event . kind  ==  SDL_MOUSEBUTTONUP ))  / / release when we were down 
        { 
            _hold  =  false ;  / / the movement of the mouse will move the scene 
            SDL_SetCursor ( _hand1 )  / / we put the normal cursor 
        } 
        else  if  (( ! _hold ) && ( event . kind  ==  SDL_MOUSEBUTTONDOWN ))  / / support when we were released 
        { 
            _hold  =  true ;  / / the movement of the mouse will move scene 
            SDL_SetCursor ( _hand2 )  / / puts the cursor on special 
        } 
    } 
    else  if  (( event . button  ==  SDL_BUTTON_WHEELUP ) && ( event . kind  ==  SDL_MOUSEBUTTONDOWN ))  / / shot wheel up 
    { 
        _distance  - =  _scrollSensivity ,  / / zoom factor, so the camera closer to the center 
        if  ( _distance  <  0.1 )  / / minimum distance, change if needed (with attribute 
              
    
           Wheel down 
    { 
            _distance  + =  _scrollSensivity ,  / / so it zooms away from the camera 
    } 
}


OnKeyboard



The last method is to use events management is the keyboard for pressing the HOME . We simply get back to the rotation of the scene to zero:Code: C + +-Select


1
2
3
4
5
6
7
8
    

          HOME button 
    { 
        _angleY  ​​=  0 ;  / / reset angles 
        _angleZ  =  0 ; 
    } 
}


Look



All this is fine, we know how to change variables with the mouse and keyboard but it does nothing to move the camera in our scene. In fact we have so far not seen any OpenGL commands!
So it's time to get started with the method Look who will replace in your display function, the call to gluLookAt .

Replace gluLookAt ? Because there is something better that thou hast hidden! ?


No no. Look the method calls itself gluLookAt but with parameters that depend on the position of the camera, this is why you do not have to call yourself.
Referring to the diagrams earlier in this chapter explaining the principle of the camera trackball, there are several things:
  • she looks at the center of the stage;
  • this is not the camera, but the stage which is rotated around Y and Z.


It is sufficient to translate all this in code:Code: C + +-Select


1
2
3
4
5
6
7
8
void  TrackBallCamera :: look () 
{ 
    gluLookAt ( _distance , 0 , 0 , 
              0 , 0 , 0 , 
              0 , 0 , 1 ),  / / the camera looks at the center (0,0,0) and is on the X axis at a distance from the center so (_distance, 0.0) 
    glRotated ( _angleY ​​, 0 , 1 , 0 );  / / scene is rotated about the axis Y 
    glRotated ( _angleZ , 0 , 0 , 1 );  / / the stage is rotated about the axis Z 
}


And this really was a no brainer.
The last thing we need to do in the code itself is the camera's own destruction that has been dynamically allocated.

Destructive



The only things are dynamically allocated cursors that we must destroy when the camera is destroyed:Code: C + +-Select


1
2
3
4
5
6
TrackBallCamera :: ~ TrackBallCamera () 
{ 
    SDL_FreeCursor ( _hand1 )  / / destroy the normal cursor 
    SDL_FreeCursor ( _hand2 )  / / destroy the special cursor 
    SDL_SetCursor ( NULL )  / / it returns the default cursor. 
}

Test scene

The class code TrackBallCamera is complete and needs nothing more. However a camera object will not receive any single events, we must give him. We will see a small scene with simple test how to use the camera that we just created. To original and not inspired by Google Earth, we will create a sphere with the texture of the earth. Ahem! By global variables we will use:Code: C + +-Select- °



1
2
GLuint  earth ;  / / the identifier of the texture of the Earth 
TrackBallCamera  *  camera ;  / / a pointer to our camera


Why not a camera directly?


Remember, the manufacturer calls functions that require SDL SDL window that already exists. So do not think the camera is built from the start of the program (which would be the case here if we did not use pointer). So we create dynamically after the window:Code: C + +-Select

1
2
3
4
5
6
7
atexit ( stop )  / / stop () will be called when

           

          
           
        


As the camera was dynamically created is up to us to destroy itself at the end of the program. This is done in the stop function, when called will exit (0); into the body of the program:Code: C + +-Select

1
2
3
4
5
void  stop () 
{ 
    delete  camera ;  / / destroy the camera dynamically allocated 
    SDL_Quit (); 
}


As I have said above, the camera does not receive keyboard events / mouse if you do not give it. That is why our party event management must give the camera the events that are not used:Code: C + +-Select

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

        
            
            
                 
                
                
                 
                 
                
                     
                    
                    
                     
                    
                    
                      used the P key and the ESC key, the rest is given to the camera 
                    camera -> OnKeyboard ( event . key ); 
                } 
                break ; 
                box  SDL_MOUSEMOTION:  / / mouse is moved, it affects only the 
                
                
                 
                 
                 events buttons (up or down) are given to the camera 
                break ; 
            } 
        }


The last thing left to do is draw the scene here is very basic.

We no longer call gluLookAt ourselves but the method Look object of our camera.


Code: C + + - Select
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
void  DrawGL () 
{ 
    glClear (  GL_COLOR_BUFFER_BIT  |  GL_DEPTH_BUFFER_BIT  );

    glMatrixMode (  GL_MODELVIEW  ); 
    glLoadIdentity (  );

    Camera -> look ();

    GLUquadric* params = gluNewQuadric();
    gluQuadricTexture(params,GL_TRUE);
    glBindTexture(GL_TEXTURE_2D,earth);
    gluSphere(params,1,20,20);
    gluDeleteQuadric(params);

    glFlush (); 
    SDL_GL_SwapBuffers (); 
}


User Image




download the required files   


trackball.rar
trackball.avi


No comments:

Post a Comment

Slider

Image Slider By engineerportal.blogspot.in The slide is a linking image  Welcome to Engineer Portal... #htmlcaption

Tamil Short Film Laptaap

Tamil Short Film Laptaap
Laptapp

Labels

About Blogging (1) Advance Data Structure (2) ADVANCED COMPUTER ARCHITECTURE (4) Advanced Database (4) ADVANCED DATABASE TECHNOLOGY (4) ADVANCED JAVA PROGRAMMING (1) ADVANCED OPERATING SYSTEMS (3) ADVANCED OPERATING SYSTEMS LAB (2) Agriculture and Technology (1) Analag and Digital Communication (1) Android (1) Applet (1) ARTIFICIAL INTELLIGENCE (3) aspiration 2020 (3) assignment cse (12) AT (1) AT - key (1) Attacker World (6) Basic Electrical Engineering (1) C (1) C Aptitude (20) C Program (87) C# AND .NET FRAMEWORK (11) C++ (1) Calculator (1) Chemistry (1) Cloud Computing Lab (1) Compiler Design (8) Computer Graphics Lab (31) COMPUTER GRAPHICS LABORATORY (1) COMPUTER GRAPHICS Theory (1) COMPUTER NETWORKS (3) computer organisation and architecture (1) Course Plan (2) Cricket (1) cryptography and network security (3) CS 810 (2) cse syllabus (29) Cyberoam (1) Data Mining Techniques (5) Data structures (3) DATA WAREHOUSING AND DATA MINING (4) DATABASE MANAGEMENT SYSTEMS (8) DBMS Lab (11) Design and Analysis Algorithm CS 41 (1) Design and Management of Computer Networks (2) Development in Transportation (1) Digital Principles and System Design (1) Digital Signal Processing (15) DISCRETE MATHEMATICS (1) dos box (1) Download (1) ebooks (11) electronic circuits and electron devices (1) Embedded Software Development (4) Embedded systems lab (4) Embedded systems theory (1) Engineer Portal (1) ENGINEERING ECONOMICS AND FINANCIAL ACCOUNTING (5) ENGINEERING PHYSICS (1) english lab (7) Entertainment (1) Facebook (2) fact (31) FUNDAMENTALS OF COMPUTING AND PROGRAMMING (3) Gate (3) General (3) gitlab (1) Global warming (1) GRAPH THEORY (1) Grid Computing (11) hacking (4) HIGH SPEED NETWORKS (1) Horizon (1) III year (1) INFORMATION SECURITY (1) Installation (1) INTELLECTUAL PROPERTY RIGHTS (IPR) (1) Internal Test (13) internet programming lab (20) IPL (1) Java (38) java lab (1) Java Programs (28) jdbc (1) jsp (1) KNOWLEDGE MANAGEMENT (1) lab syllabus (4) MATHEMATICS (3) Mechanical Engineering (1) Microprocessor and Microcontroller (1) Microprocessor and Microcontroller lab (11) migration (1) Mini Projects (1) MOBILE AND PERVASIVE COMPUTING (15) MOBILE COMPUTING (1) Multicore Architecute (1) MULTICORE PROGRAMMING (2) Multiprocessor Programming (2) NANOTECHNOLOGY (1) NATURAL LANGUAGE PROCESSING (1) NETWORK PROGRAMMING AND MANAGEMENT (1) NETWORKPROGNMGMNT (1) networks lab (16) News (14) Nova (1) NUMERICAL METHODS (2) Object Oriented Programming (1) ooad lab (6) ooad theory (9) OPEN SOURCE LAB (22) openGL (10) Openstack (1) Operating System CS45 (2) operating systems lab (20) other (4) parallel computing (1) parallel processing (1) PARALLEL PROGRAMMING (1) Parallel Programming Paradigms (4) Perl (1) Placement (3) Placement - Interview Questions (64) PRINCIPLES OF COMMUNICATION (1) PROBABILITY AND QUEUING THEORY (3) PROGRAMMING PARADIGMS (1) Python (3) Question Bank (1) question of the day (8) Question Paper (13) Question Paper and Answer Key (3) Railway Airport and Harbor (1) REAL TIME SYSTEMS (1) RESOURCE MANAGEMENT TECHNIQUES (1) results (3) semester 4 (5) semester 5 (1) Semester 6 (5) SERVICE ORIENTED ARCHITECTURE (1) Skill Test (1) software (1) Software Engineering (4) SOFTWARE TESTING (1) Structural Analysis (1) syllabus (34) SYSTEM SOFTWARE (1) system software lab (2) SYSTEMS MODELING AND SIMULATION (1) Tansat (2) Tansat 2011 (1) Tansat 2013 (1) TCP/IP DESIGN AND IMPLEMENTATION (1) TECHNICAL ENGLISH (7) Technology and National Security (1) Theory of Computation (3) Thought for the Day (1) Timetable (4) tips (4) Topic Notes (7) tot (1) TOTAL QUALITY MANAGEMENT (4) tutorial (8) Ubuntu LTS 12.04 (1) Unit Wise Notes (1) University Question Paper (1) UNIX INTERNALS (1) UNIX Lab (21) USER INTERFACE DESIGN (3) VIDEO TUTORIALS (1) Virtual Instrumentation Lab (1) Visual Programming (2) Web Technology (11) WIRELESS NETWORKS (1)

LinkWithin