ضمیمه A: برنامه‌های نمونه 8 تا 10، پیمایش درخت و قوری | گرافیک تعاملی با OpenGL

ضمیمه A: برنامه‌های نمونه 8 تا 10، پیمایش درخت و قوری

ضمیمه A: برنامه‌های نمونه 8 تا 10، پیمایش درخت و قوری

  • عنوان اصلی اثر: Interactive Computer Graphics: A Top-Down Approach with Shader-Based OpenGL, Sixth Edition
  • عنوان ترجمه‌شدهٔ این بخش: ضمیمه A: برنامه‌های نمونه 8 تا 10، پیمایش درخت و قوری
  • نویسندگان و سازمان: Edward Angel — University of New Mexico؛ Dave Shreiner — ARM, Inc.
  • زبان اصلی: انگلیسی
  • وضعیت مجوز: حق ترجمه و بازنشر توسط کاربر تأیید شده است.
  • تاریخ ترجمه: ۱۴۰۵/۰۵/۲۲
  • مترجم: ترجمه با کمک هوش مصنوعی

ضمیمه A: برنامه‌های نمونهٔ ۸ تا ۱۰، پیمایش Tree و قوری

این بخش ادامهٔ کدهای نمونهٔ ضمیمه A است. برای حفظ قابلیت اجرای نمونه‌ها، تمام شناسه‌ها، دستورها، literalها و commentهای داخل code blockها عیناً نگه داشته شده‌اند.

A.8 مکعب چرخان با Texture — ادامهٔ کد برنامه

                                                            A.8 Rotating Cube with Texture   639


#include "Angel.h"

const int   NumTriangles = 12; // (6 faces)(2 triangles/face)
const int   NumVertices = 3 * NumTriangles;
const int   TextureSize = 64;

typedef Angel::vec4 point4;
typedef Angel::vec4 color4;

// Texture objects and storage for texture image
GLuint textures[2];

GLubyte image[TextureSize][TextureSize][3];
GLubyte image2[TextureSize][TextureSize][3];

// Vertex data arrays
point4 points[NumVertices];
color4 quad_colors[NumVertices];
vec2    tex_coords[NumVertices];

// Array of rotation angles (in degrees) for each coordinate axis
enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
int      Axis = Xaxis;
GLfloat Theta[NumAxes] = { 0.0, 0.0, 0.0 };
GLuint   theta;

//----------------------------------------------------------------------

int Index = 0;

void
quad( int a, int b, int c, int d )
{
     point4 vertices[8] = {
         point4( -0.5, -0.5, 0.5, 1.0 ),
         point4( -0.5, 0.5, 0.5, 1.0 ),
         point4( 0.5, 0.5, 0.5, 1.0 ),
         point4( 0.5, -0.5, 0.5, 1.0 ),
         point4( -0.5, -0.5, -0.5, 1.0 ),
         point4( -0.5, 0.5, -0.5, 1.0 ),
         point4( 0.5, 0.5, -0.5, 1.0 ),
         point4( 0.5, -0.5, -0.5, 1.0 )
     };

    color4 colors[8] = {
        color4( 0.0, 0.0, 0.0, 1.0 ),   // black
        color4( 1.0, 0.0, 0.0, 1.0 ),   // red
        color4( 1.0, 1.0, 0.0, 1.0 ),   // yellow
        color4( 0.0, 1.0, 0.0, 1.0 ),   // green
640   Appendix A   Sample Programs



                                color4( 0.0, 0.0, 1.0, 1.0 ),   // blue
                                color4( 1.0, 0.0, 1.0, 1.0 ),   // magenta
                                color4( 0.0, 1.0, 1.0, 1.0 ),   // white
                                color4( 1.0, 1.0, 1.0, 1.0 )    // cyan
                           };

                           quad_colors[Index] = colors[a];
                           points[Index] = vertices[a];
                           tex_coords[Index] = vec2( 0.0, 0.0 );
                           Index++;

                           quad_colors[Index] = colors[a];
                           points[Index] = vertices[b];
                           tex_coords[Index] = vec2( 0.0, 1.0 );
                           Index++;

                           quad_colors[Index] = colors[a];
                           points[Index] = vertices[c];
                           tex_coords[Index] = vec2( 1.0, 1.0 );
                           Index++;

                           quad_colors[Index] = colors[a];
                           points[Index] = vertices[a];
                           tex_coords[Index] = vec2( 0.0, 0.0 );
                           Index++;

                           quad_colors[Index] = colors[a];
                           points[Index] = vertices[c];
                           tex_coords[Index] = vec2( 1.0, 1.0 );
                           Index++;

                           quad_colors[Index] = colors[a];
                           points[Index] = vertices[d];
                           tex_coords[Index] = vec2( 1.0, 0.0 );
                           Index++;
                       }

                       //----------------------------------------------------------------------

                       void
                       colorcube( void )
                       {
                            quad( 1, 0, 3, 2 );
                            quad( 2, 3, 7, 6 );
                            quad( 3, 0, 4, 7 );
                            quad( 6, 5, 1, 2 );
                            quad( 4, 5, 6, 7 );
                            quad( 5, 4, 0, 1 );
                       }
                                                            A.8 Rotating Cube with Texture   641


//----------------------------------------------------------------------

void
init( void )
{
     colorcube( void );

    // Create a checkerboard pattern
    for ( int i = 0; i < 64; i++ ) {
        for ( int j = 0; j < 64; j++ ) {
            GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8)   == 0)) * 255;
            image[i][j][0] = c;
            image[i][j][1] = c;
            image[i][j][2] = c;
            image2[i][j][0] = c;
            image2[i][j][1] = 0;
            image2[i][j][2] = c;
        }
    }

    // Initialize texture objects
    glGenTextures( 2, textures );

    glBindTexture( GL_TEXTURE_2D, textures[0] );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, TextureSize, TextureSize, 0,
                  GL_RGB, GL_UNSIGNED_BYTE, image );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

    glBindTexture( GL_TEXTURE_2D, textures[1] );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, TextureSize, TextureSize, 0,
                  GL_RGB, GL_UNSIGNED_BYTE, image2 );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, textures[0] );

    // Create a vertex array object
    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    // Create and initialize a buffer object
    GLuint buffer;
642   Appendix A   Sample Programs



                           glGenBuffers( 1, &buffer );
                           glBindBuffer( GL_ARRAY_BUFFER, buffer );
                           glBufferData( GL_ARRAY_BUFFER,
                                         sizeof(points) + sizeof(quad_colors) +
                                         sizeof(tex_coords), NULL, GL_STATIC_DRAW );

                           // Specify an offset to keep track of where we’re placing data in
                           //   our vertex array buffer. We’ll use the same technique when we
                           //   associate the offsets with vertex attribute pointers.
                           GLintptr offset = 0;
                           glBufferSubData( GL_ARRAY_BUFFER, offset, sizeof(points), points );
                           offset += sizeof(points);

                           glBufferSubData( GL_ARRAY_BUFFER, offset,
                                            sizeof(quad_colors), quad_colors );
                           offset += sizeof(quad_colors);

                           glBufferSubData( GL_ARRAY_BUFFER, offset, sizeof(tex_coords),
                                            tex_coords );

                           // Load shaders and use the resulting shader program
                           GLuint program = InitShader( "vshader71.glsl", "fshader71.glsl" );
                           glUseProgram( program );

                           // set up vertex arrays
                           offset = 0;
                           GLuint vPosition = glGetAttribLocation( program, "vPosition" );
                           glEnableVertexAttribArray( vPosition );
                           glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
                                                   BUFFER_OFFSET(offset) );
                           offset += sizeof(points);

                           GLuint vColor = glGetAttribLocation( program, "vColor" );
                           glEnableVertexAttribArray( vColor );
                           glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0,
                                                  BUFFER_OFFSET(offset) );
                           offset += sizeof(quad_colors);

                           GLuint vTexCoord = glGetAttribLocation( program, "vTexCoord" );
                           glEnableVertexAttribArray( vTexCoord );
                           glVertexAttribPointer( vTexCoord, 2, GL_FLOAT, GL_FALSE, 0,
                                                  BUFFER_OFFSET(offset) );

                           // Set the value of the fragment shader texture sampler variable
                           //   ("texture") to the appropriate texture unit. In this case,
                           //   zero, for GL_TEXTURE0 which was previously set by calling
                           //   glActiveTexture( void ).
                           glUniform1i( glGetUniformLocation(program, "texture"), 0 );
                                                                 A.8 Rotating Cube with Texture   643


    theta = glGetUniformLocation( program, "theta" );

    glEnable( GL_DEPTH_TEST );

    glClearColor( 1.0, 1.0, 1.0, 1.0 );
}

void
display( void )
{
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     glUniform3fv( theta, 1, Theta );
     glDrawArrays( GL_TRIANGLES, 0, NumVertices );
     glutSwapBuffers( void );
}

//----------------------------------------------------------------------

void
mouse( int button, int state, int x, int y )
{
     if ( state == GLUT_DOWN ) {
         switch( button ) {
             case GLUT_LEFT_BUTTON:   Axis = Xaxis;     break;
             case GLUT_MIDDLE_BUTTON: Axis = Yaxis;     break;
             case GLUT_RIGHT_BUTTON:  Axis = Zaxis;     break;
         }
     }
}

//----------------------------------------------------------------------

void
idle( void )
{
     Theta[Axis] += 0.01;

    if ( Theta[Axis] > 360.0 ) {
        Theta[Axis] -= 360.0;
    }

    glutPostRedisplay( void );
}

//----------------------------------------------------------------------

void
keyboard( unsigned char key, int mousex, int mousey )
{

A.8.2 Vertex Shader

644   Appendix A   Sample Programs



                            switch( key ) {
                                case 033: // Escape Key
                                case ’q’: case ’Q’:
                                    exit( EXIT_SUCCESS );
                                    break;
                                case ’1’:
                                    glBindTexture( GL_TEXTURE_2D, textures[0] );
                                          break;

                                case ’2’:
                                    glBindTexture( GL_TEXTURE_2D, textures[1] );
                                    break;
                            }

                            glutPostRedisplay( void );
                       }

                       //----------------------------------------------------------------------

                       int
                       main( int argc, char **argv )
                       {
                           glutInit( &argc, argv );
                           glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
                           glutInitWindowSize( 512, 512 );
                           glutInitContextVersion( 3, 2 );
                           glutInitContextProfile( GLUT_CORE_PROFILE );
                           glutCreateWindow( "Color Cube" );

                            glewInit( void );

                            init( void );

                            glutDisplayFunc( display );
                            glutKeyboardFunc( keyboard );
                            glutMouseFunc( mouse );
                            glutIdleFunc( idle );

                            glutMainLoop( void );
                            return 0;
                       }


                       A.8.2 Vertex Shader
                       #version 150

                       in   vec4 vPosition;
                       in   vec4 vColor;
                       in   vec2 vTexCoord;

A.8.3 Fragment Shader

                                                            A.8 Rotating Cube with Texture   645


out vec4 color;
out vec2 texCoord;

uniform vec3 theta;

void main()
{
    const float    DegreesToRadians = 3.14159265 / 180.0;

     vec3 c = cos( DegreesToRadians * theta );
     vec3 s = sin( DegreesToRadians * theta );

     mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
           0.0, c.x, -s.x, 0.0,
           0.0, s.x, c.x, 0.0,
           0.0, 0.0, 0.0, 1.0);

     mat4 ry = mat4(   c.y, 0.0, s.y, 0.0,
             0.0, 1.0, 0.0, 0.0,
            -s.y, 0.0, c.y, 0.0,
             0.0, 0.0, 0.0, 1.0 );

     mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
           s.z, c.z, 0.0, 0.0,
           0.0, 0.0, 1.0, 0.0,
           0.0, 0.0, 0.0, 1.0 );

     color       = vColor;
     texCoord    = vTexCoord;
     gl_Position = rz * ry * rx * vPosition;
}




A.8.3 Fragment Shader
#version 150

in   vec4 color;
in   vec2 texCoord;

out vec4 fColor;

uniform sampler2D texture;

void main()
{
    fColor = color * texture2D( texture, texCoord );
}

A.9 شکل با پیمایش Tree

A.9.1 کد برنامه

646   Appendix A   Sample Programs




                       A.9   FIGURE WITH TREE TRAVERSAL
                       A.9.1 Application Code
                       #include "Angel.h"
                       #include <assert.h>

                       typedef Angel::vec4 point4;
                       typedef Angel::vec4 color4;

                       const int NumVertices = 36; //(6 faces)(2 triangles/face)
                                                     (3 vertices/triangle)

                       point4 points[NumVertices];
                       color4 colors[NumVertices];

                       point4 vertices[8] = {
                           point4( -0.5, -0.5, 0.5, 1.0 ),
                           point4( -0.5, 0.5, 0.5, 1.0 ),
                           point4( 0.5, 0.5, 0.5, 1.0 ),
                           point4( 0.5, -0.5, 0.5, 1.0 ),
                           point4( -0.5, -0.5, -0.5, 1.0 ),
                           point4( -0.5, 0.5, -0.5, 1.0 ),
                           point4( 0.5, 0.5, -0.5, 1.0 ),
                           point4( 0.5, -0.5, -0.5, 1.0 )
                       };

                       // RGBA colors
                       color4 vertex_colors[8] = {
                           color4( 0.0, 0.0, 0.0, 1.0 ),   // black
                           color4( 1.0, 0.0, 0.0, 1.0 ),   // red
                           color4( 1.0, 1.0, 0.0, 1.0 ),   // yellow
                           color4( 0.0, 1.0, 0.0, 1.0 ),   // green
                           color4( 0.0, 0.0, 1.0, 1.0 ),   // blue
                           color4( 1.0, 0.0, 1.0, 1.0 ),   // magenta
                           color4( 1.0, 1.0, 1.0, 1.0 ),   // white
                           color4( 0.0, 1.0, 1.0, 1.0 )    // cyan
                       };

                       //----------------------------------------------------------------------

                       class MatrixStack {
                           int    _index;
                           int    _size;
                           mat4* _matrices;

                          public:
                           MatrixStack( int numMatrices = 32 ):_index(0), _size(numMatrices)
                                                             A.9 Figure with Tree Traversal   647


         { _matrices = new mat4[numMatrices]; }

     ~MatrixStack( void )
         { delete[]_matrices; }

     mat4& push( const mat4& m ) {
         assert( _index + 1 < _size );
         _matrices[_index++] = m;
     }

     mat4& pop( void ) {
         assert( _index - 1 >= 0 );
         _index--;
         return _matrices[_index + 1];
     }
};

MatrixStack   mvstack;
mat4          model_view;
GLuint        ModelView, Projection;

//----------------------------------------------------------------------

#define TORSO_HEIGHT 5.0
#define TORSO_WIDTH 1.0
#define UPPER_ARM_HEIGHT 3.0
#define LOWER_ARM_HEIGHT 2.0
#define UPPER_LEG_WIDTH 0.5
#define LOWER_LEG_WIDTH 0.5
#define LOWER_LEG_HEIGHT 2.0
#define UPPER_LEG_HEIGHT 3.0
#define UPPER_LEG_WIDTH 0.5
#define UPPER_ARM_WIDTH 0.5
#define LOWER_ARM_WIDTH 0.5
#define HEAD_HEIGHT 1.5
#define HEAD_WIDTH 1.0

// Set up menu item indices, which we can also use with the joint angles
enum {
    Torso = 0,
    Head = 1,
    Head1 = 1,
    Head2 = 2,
    LeftUpperArm = 3,
    LeftLowerArm = 4,
    RightUpperArm = 5,
    RightLowerArm = 6,
    LeftUpperLeg = 7,
648   Appendix A   Sample Programs



                              LeftLowerLeg = 8,
                              RightUpperLeg = 9,
                              RightLowerLeg = 10,
                              NumNodes,
                              Quit
                       };

                       // Joint angles with initial values
                       GLfloat
                       theta[NumNodes] = {
                           0.0,    // Torso
                           0.0,    // Head1
                           0.0,    // Head2
                           0.0,    // LeftUpperArm
                           0.0,    // LeftLowerArm
                           0.0,    // RightUpperArm
                           0.0,    // RightLowerArm
                           180.0, // LeftUpperLeg
                           0.0,     // LeftLowerLeg
                           180.0, // RightUpperLeg
                           0.0    // RightLowerLeg
                       };

                       GLint angle = Head2;

                       //----------------------------------------------------------------------

                       struct Node {
                           mat4 transform;
                           void (*render)( void );
                           Node* sibling;
                           Node* child;

                              Node( void ) :
                                  render(NULL), sibling(NULL), child(NULL) {}

                              Node( mat4& m, void (*render)( void ), Node* sibling, Node* child ) :
                                  transform(m), render(render), sibling(sibling), child(child) {}
                       };

                       Node    nodes[NumNodes];

                       //----------------------------------------------------------------------

                       int Index = 0;

                       void
                       quad( int a, int b, int c, int d )
                                                             A.9 Figure with Tree Traversal   649


{
    colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
    colors[Index] = vertex_colors[a]; points[Index] = vertices[b]; Index++;
    colors[Index] = vertex_colors[a]; points[Index] = vertices[c]; Index++;
    colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
    colors[Index] = vertex_colors[a]; points[Index] = vertices[c]; Index++;
    colors[Index] = vertex_colors[a]; points[Index] = vertices[d]; Index++;
}

void
colorcube( void )
{
     quad( 1, 0, 3, 2 );
     quad( 2, 3, 7, 6 );
     quad( 3, 0, 4, 7 );
     quad( 6, 5, 1, 2 );
     quad( 4, 5, 6, 7 );
     quad( 5, 4, 0, 1 );
}

//----------------------------------------------------------------------

void
traverse( Node* node )
{
     if ( node == NULL ) { return; }

    mvstack.push( model_view );

    model_view *= node->transform;
    node->render( void );

    if ( node->child ) { traverse( node->child ); }

    model_view = mvstack.pop( void );

    if ( node->sibling ) { traverse( node->sibling ); }
}

//----------------------------------------------------------------------

void
torso( void )
{
     mvstack.push( model_view );

    mat4 instance = ( Translate( 0.0, 0.5 * TORSO_HEIGHT, 0.0 ) *
                      Scale( TORSO_WIDTH, TORSO_HEIGHT, TORSO_WIDTH ) );
650   Appendix A   Sample Programs



                           glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );

                           model_view = mvstack.pop( void );
                       }

                       void
                       head( void )
                       {
                            mvstack.push( model_view );

                           mat4 instance = (Translate( 0.0, 0.5 * HEAD_HEIGHT, 0.0 ) *
                                            Scale( HEAD_WIDTH, HEAD_HEIGHT, HEAD_WIDTH ) );

                           glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );

                           model_view = mvstack.pop( void );
                       }

                       void
                       left_upper_arm( void )
                       {
                            mvstack.push( model_view );

                           mat4 instance = (Translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ) *
                                            Scale( UPPER_ARM_WIDTH,
                                                   UPPER_ARM_HEIGHT,
                                                   UPPER_ARM_WIDTH ) );

                           glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );

                           model_view = mvstack.pop( void );
                       }

                       void
                       left_lower_arm( void )
                       {
                            mvstack.push( model_view );

                           mat4 instance = ( Translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ) *
                                             Scale( LOWER_ARM_WIDTH,
                                                    LOWER_ARM_HEIGHT,
                                                    LOWER_ARM_WIDTH ) );

                           glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );
                                                             A.9 Figure with Tree Traversal   651


    model_view = mvstack.pop( void );
}

void
right_upper_arm( void )
{
     mvstack.push( model_view );

    mat4 instance = (Translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ) *
                     Scale( UPPER_ARM_WIDTH,
                            UPPER_ARM_HEIGHT,
                            UPPER_ARM_WIDTH ) );

    glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
    glDrawArrays( GL_TRIANGLES, 0, NumVertices );

    model_view = mvstack.pop( void );
}

void
right_lower_arm( void )
{
     mvstack.push( model_view );

    mat4 instance = (Translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ) *
                     Scale( LOWER_ARM_WIDTH,
                            LOWER_ARM_HEIGHT,
                            LOWER_ARM_WIDTH ) );

    glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
    glDrawArrays( GL_TRIANGLES, 0, NumVertices );

    model_view = mvstack.pop( void );
}

void
left_upper_leg( void )
{
     mvstack.push( model_view );

    mat4 instance = ( Translate( 0.0, 0.5 * UPPER_LEG_HEIGHT, 0.0 ) *
                      Scale( UPPER_LEG_WIDTH,
                             UPPER_LEG_HEIGHT,
                             UPPER_LEG_WIDTH ) );

    glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
    glDrawArrays( GL_TRIANGLES, 0, NumVertices );
652   Appendix A   Sample Programs



                           model_view = mvstack.pop( void );
                       }

                       void
                       left_lower_leg( void )
                       {
                            mvstack.push( model_view );

                           mat4 instance = (Translate( 0.0, 0.5 * LOWER_LEG_HEIGHT, 0.0 ) *
                                            Scale( LOWER_LEG_WIDTH,
                                                   LOWER_LEG_HEIGHT,
                                                   LOWER_LEG_WIDTH ) );

                           glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );

                           model_view = mvstack.pop( void );
                       }

                       void
                       right_upper_leg( void )
                       {
                            mvstack.push( model_view );

                           mat4 instance = (Translate( 0.0, 0.5 * UPPER_LEG_HEIGHT, 0.0 ) *
                                            Scale( UPPER_LEG_WIDTH,
                                                   UPPER_LEG_HEIGHT,
                                                   UPPER_LEG_WIDTH ) );

                           glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );

                           model_view = mvstack.pop( void );
                       }

                       void
                       right_lower_leg( void )
                       {
                            mvstack.push( model_view );

                           mat4 instance = ( Translate( 0.0, 0.5 * LOWER_LEG_HEIGHT, 0.0 ) *
                                             Scale( LOWER_LEG_WIDTH,
                                                    LOWER_LEG_HEIGHT,
                                                    LOWER_LEG_WIDTH ) );

                           glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );

                           model_view = mvstack.pop( void );
                       }
                                                              A.9 Figure with Tree Traversal   653


//----------------------------------------------------------------------

void
display( void )
{
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     traverse( &nodes[Torso] );
     glutSwapBuffers( void );
}

//----------------------------------------------------------------------

void
mouse( int button, int state, int x, int y )
{
     if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
         theta[angle] += 5.0;
         if ( theta[angle] > 360.0 ) { theta[angle] -= 360.0; }
     }

    if ( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN ) {
        theta[angle] -= 5.0;
        if ( theta[angle] < 0.0 ) { theta[angle] += 360.0; }
    }

    mvstack.push( model_view );

    switch( angle ) {
        case Torso:
            nodes[Torso].transform =
                RotateY( theta[Torso] );
            break;

        case Head1: case Head2:
            nodes[Head].transform =
                Translate(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0) *
                RotateX(theta[Head1]) *
                RotateY(theta[Head2]) *
                Translate(0.0, -0.5*HEAD_HEIGHT, 0.0);
            break;

        case LeftUpperArm:
            nodes[LeftUpperArm].transform =
                Translate(-(TORSO_WIDTH+UPPER_ARM_WIDTH),
                           0.9*TORSO_HEIGHT, 0.0) *
                RotateX(theta[LeftUpperArm]);
            break;

        case RightUpperArm:
            nodes[RightUpperArm].transform =
654   Appendix A   Sample Programs



                                         Translate(TORSO_WIDTH+UPPER_ARM_WIDTH,
                                                   0.9*TORSO_HEIGHT, 0.0) *
                                         RotateX(theta[RightUpperArm]);
                                     break;

                               case RightUpperLeg:
                                   nodes[RightUpperLeg].transform =
                                       Translate(TORSO_WIDTH+UPPER_LEG_WIDTH,
                                                 0.1*UPPER_LEG_HEIGHT, 0.0) *
                                       RotateX(theta[RightUpperLeg]);
                                   break;

                               case LeftUpperLeg:
                                   nodes[LeftUpperLeg].transform =
                                       Translate(-(TORSO_WIDTH+UPPER_LEG_WIDTH),
                                                 0.1*UPPER_LEG_HEIGHT, 0.0) *
                                       RotateX(theta[LeftUpperLeg]);
                                   break;

                               case LeftLowerArm:
                                   nodes[LeftLowerArm].transform =
                                       Translate(0.0, UPPER_ARM_HEIGHT, 0.0) *
                                       RotateX(theta[LeftLowerArm]);
                                   break;

                               case LeftLowerLeg:
                                   nodes[LeftLowerLeg].transform =
                                       Translate(0.0, UPPER_LEG_HEIGHT, 0.0) *
                                       RotateX(theta[LeftLowerLeg]);
                                   break;

                               case RightLowerLeg:
                                   nodes[RightLowerLeg].transform =
                                       Translate(0.0, UPPER_LEG_HEIGHT, 0.0) *
                                       RotateX(theta[RightLowerLeg]);
                                   break;

                               case RightLowerArm:
                                   nodes[RightLowerArm].transform =
                                       Translate(0.0, UPPER_ARM_HEIGHT, 0.0) *
                                       RotateX(theta[RightLowerArm]);
                                   break;
                           }

                           model_view = mvstack.pop( void );
                           glutPostRedisplay( void );
                       }

                       //----------------------------------------------------------------------
                                                              A.9 Figure with Tree Traversal   655


void
menu( int option )
{
     if ( option == Quit ) {
         exit( EXIT_SUCCESS );
     }

    angle = option;
}

//----------------------------------------------------------------------

void
reshape( int width, int height )
{
     glViewport( 0, 0, width, height );

    GLfloat left = -10.0, right = 10.0;
    GLfloat bottom = -10.0, top = 10.0;
    GLfloat zNear = -10.0, zFar = 10.0;

    GLfloat aspect = GLfloat( width ) / height;

    if ( aspect > 1.0 ) {
        left *= aspect;
        right *= aspect;
    }
    else {
        bottom /= aspect;
        top /= aspect;
    }

    mat4 projection = Ortho( left, right, bottom, top, zNear, zFar );
    glUniformMatrix4fv( Projection, 1, GL_TRUE, projection );

    model_view = mat4( 1.0 );    // An Identity matrix
}

//----------------------------------------------------------------------

void
initNodes( void )
{
     mat4 m;

    m = RotateY( theta[Torso] );
    nodes[Torso] = Node( m, torso, NULL, &nodes[Head1] );

    m = Translate(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0) *
656   Appendix A   Sample Programs



                               RotateX(theta[Head1]) *
                               RotateY(theta[Head2]);
                           nodes[Head1] = Node( m, head, &nodes[LeftUpperArm], NULL );

                           m = Translate(-(TORSO_WIDTH+UPPER_ARM_WIDTH), 0.9*TORSO_HEIGHT,
                               0.0) * RotateX(theta[LeftUpperArm]);
                           nodes[LeftUpperArm] =
                               Node( m, left_upper_arm, &nodes[RightUpperArm],
                                                        &nodes[LeftLowerArm] );

                           m = Translate(TORSO_WIDTH+UPPER_ARM_WIDTH, 0.9*TORSO_HEIGHT, 0.0) *
                               RotateX(theta[RightUpperArm]);
                           nodes[RightUpperArm] =
                               Node( m, right_upper_arm,
                                     &nodes[LeftUpperLeg], &nodes[RightLowerArm] );

                           m = Translate(-(TORSO_WIDTH+UPPER_LEG_WIDTH),
                               0.1*UPPER_LEG_HEIGHT, 0.0) *
                               RotateX(theta[LeftUpperLeg]);
                           nodes[LeftUpperLeg] =
                               Node( m, left_upper_leg, &nodes[RightUpperLeg],
                                                        &nodes[LeftLowerLeg] );

                           m = Translate(TORSO_WIDTH+UPPER_LEG_WIDTH,
                               0.1*UPPER_LEG_HEIGHT, 0.0) * RotateX(theta[RightUpperLeg]);
                           nodes[RightUpperLeg] =
                               Node( m, right_upper_leg, NULL, &nodes[RightLowerLeg] );

                           m = Translate(0.0, UPPER_ARM_HEIGHT, 0.0) *
                               RotateX(theta[LeftLowerArm]);
                           nodes[LeftLowerArm] = Node( m, left_lower_arm, NULL, NULL );

                           m = Translate(0.0, UPPER_ARM_HEIGHT, 0.0) *
                               RotateX(theta[RightLowerArm]);
                           nodes[RightLowerArm] = Node( m, right_lower_arm, NULL, NULL );

                           m = Translate(0.0, UPPER_LEG_HEIGHT, 0.0) *
                               RotateX(theta[LeftLowerLeg]);
                           nodes[LeftLowerLeg] = Node( m, left_lower_leg, NULL, NULL );

                           m = Translate(0.0, UPPER_LEG_HEIGHT, 0.0) *
                               RotateX(theta[RightLowerLeg]);
                           nodes[RightLowerLeg] = Node( m, right_lower_leg, NULL, NULL );
                       }

                       //----------------------------------------------------------------------

                       void
                       init( void )
                                                                A.9 Figure with Tree Traversal   657


{
    colorcube( void );

    // Initialize tree
    initNodes( void );

    // Create a vertex array object
    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    // Create and initialize a buffer object
    GLuint buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors),
                   NULL, GL_DYNAMIC_DRAW );
    glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
    glBufferSubData( GL_ARRAY_BUFFER, sizeof(points), sizeof(colors),
                      colors );

    // Load shaders and use the resulting shader program
    GLuint program = InitShader( "vshader83.glsl", "fshader83.glsl" );
    glUseProgram( program );

    GLuint vPosition = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( vPosition );
    glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
                           BUFFER_OFFSET(0) );

    GLuint vColor = glGetAttribLocation( program, "vColor" );
    glEnableVertexAttribArray( vColor );
    glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0,
                           BUFFER_OFFSET(points) );

    ModelView = glGetUniformLocation( program, "ModelView" );
    Projection = glGetUniformLocation( program, "Projection" );

    glEnable( GL_DEPTH_TEST );
    glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

    glClearColor( 1.0, 1.0, 1.0, 1.0 );

}

//----------------------------------------------------------------------

void
keyboard( unsigned char key, int x, int y )
658   Appendix A   Sample Programs



                       {
                           switch( key ) {
                               case 033: // Escape Key
                               case ’q’: case ’Q’:
                                   exit( EXIT_SUCCESS );
                                   break;
                           }
                       }

                       //----------------------------------------------------------------------

                       int
                       main( int argc, char **argv )
                       {
                           glutInit( &argc, argv );
                           glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
                           glutInitWindowSize( 512, 512 );
                           glutInitContextVersion( 3, 2 );
                           glutInitContextProfile( GLUT_CORE_PROFILE );
                           glutCreateWindow( "robot" );

                           glewInit( void );

                           init( void );

                           glutDisplayFunc( display );
                           glutReshapeFunc( reshape );
                           glutKeyboardFunc( keyboard );
                           glutMouseFunc( mouse );

                           glutCreateMenu( menu );
                           glutAddMenuEntry( "torso", Torso );
                           glutAddMenuEntry( "head1", Head1 );
                           glutAddMenuEntry( "head2", Head2 );
                           glutAddMenuEntry( "right_upper_arm", RightUpperArm );
                           glutAddMenuEntry( "right_lower_arm", RightLowerArm );
                           glutAddMenuEntry( "left_upper_arm", LeftUpperArm );
                           glutAddMenuEntry( "left_lower_arm", LeftLowerArm );
                           glutAddMenuEntry( "right_upper_leg", RightUpperLeg );
                           glutAddMenuEntry( "right_lower_leg", RightLowerLeg );
                           glutAddMenuEntry( "left_upper_leg", LeftUpperLeg );
                           glutAddMenuEntry( "left_lower_leg", LeftLowerLeg );
                           glutAddMenuEntry( "quit", Quit );
                           glutAttachMenu( GLUT_MIDDLE_BUTTON );

                           glutMainLoop( void );
                           return 0;
                       }

A.9.2 Vertex Shader و A.9.3 Fragment Shader

A.10 رندرکنندهٔ قوری

A.10.1 کد برنامه

                                                                    A.10 Teapot Renderer   659


A.9.2 Vertex Shader
#version 150

in vec4 vPosition;
in vec4 vColor;
out vec4 color;

uniform mat4 ModelView;
uniform mat4 Projection;

void main()
{
    color = vColor;
    gl_Position = Projection*ModelView*vPosition;
}



A.9.3 Fragment Shader
#version 150

in vec4 color;
out vec4 fColor;

void main()
{
    fColor = color;
}



A.10   TEAPOT RENDERER
A.10.1 Application Code
#include "Angel.h"

typedef Angel::vec4 point4;

// Define a convenient type for referencing patch control points, which
//   is used in the declaration of the vertices’ array (used in "vertices.h")
typedef GLfloat      point3[3];
#include "vertices.h"
#include "patches.h"

const int NumTimesToSubdivide = 3;
const int PatchesPerSubdivision = 4;
const int NumQuadsPerPatch =
    (int) pow( PatchesPerSubdivision, NumTimesToSubdivide );
const int NumTriangles =
660   Appendix A   Sample Programs



                           ( NumTeapotPatches * NumQuadsPerPatch * 2 // triangles / quad );
                       const int NumVertices =
                           ( NumTriangles * 3 // vertices / triangle );

                       int      Index = 0;
                       point4   points[NumVertices];

                       GLuint   Projection;

                       enum { X = 0, Y = 1, Z = 2 };

                       //----------------------------------------------------------------------

                       void
                       divide_curve( point4 c[4], point4 r[4], point4 l[4] )
                       {
                            // Subdivide a Bezier curve into two equivalent Bezier curves:
                            //   left (l) and right (r) sharing the midpoint of the middle
                            //   control point
                            point4 t, mid = ( c[1] + c[2] ) / 2;

                           l[0] = c[0];
                           l[1] = ( c[0] + c[1] ) / 2;
                           l[2] = ( l[1] + mid ) / 2;

                           r[3] = c[3];
                           r[2] = ( c[2] + c[3] ) / 2;
                           r[1] = ( mid + r[2] ) / 2;

                           l[3] = r[0] = ( l[2] + r[1] ) / 2;

                           for ( int i = 0; i < 4; ++i ) {
                           l[i].w = 1.0;
                           r[i].w = 1.0;
                           }
                       }

                       //----------------------------------------------------------------------

                       void
                       draw_patch( point4 p[4][4] )
                       {
                            // Draw the quad (as two triangles) bounded by the corners of the
                            //   Bezier patch.
                            points[Index++] = p[0][0];
                            points[Index++] = p[3][0];
                            points[Index++] = p[3][3];
                            points[Index++] = p[0][0];
                            points[Index++] = p[3][3];
                                                                    A.10 Teapot Renderer   661


    points[Index++] = p[0][3];
}

//----------------------------------------------------------------------

inline void
transpose( point4 a[4][4] )
{
    for ( int i = 0; i < 4; i++ ) {
        for ( int j = i; j < 4; j++ ) {
            point4 t = a[i][j];
            a[i][j] = a[j][i];
            a[j][i] = t;
        }
    }
}

void
divide_patch( point4 p[4][4], int count )
{
     if ( count > 0 ) {
     point4 q[4][4], r[4][4], s[4][4], t[4][4];
     point4 a[4][4], b[4][4];

    // subdivide curves in u direction, transpose results, divide
    // in u direction again (equivalent to subdivision in v)
        for ( int k = 0; k < 4; ++k ) {
            divide_curve( p[k], a[k], b[k] );
    }

        transpose( a );
        transpose( b );

        for ( int k = 0; k < 4; ++k ) {
            divide_curve( a[k], q[k], r[k] );
            divide_curve( b[k], s[k], t[k] );
        }

    // recursive division of 4 resulting patches
        divide_patch( q, count - 1 );
        divide_patch( r, count - 1 );
        divide_patch( s, count - 1 );
        divide_patch( t, count - 1 );
    }
    else {
        draw_patch( p );
    }
}
662   Appendix A   Sample Programs



                       //----------------------------------------------------------------------

                       void
                       init( void )
                       {
                            for ( int n = 0; n < NumTeapotPatches; n++ ) {
                            point4 patch[4][4];

                           // Initialize each patch’s control point data
                           for ( int i = 0; i < 4; ++i ) {
                               for ( int j = 0; j < 4; ++j ) {
                               point3& v = vertices[indices[n][i][j]];
                               patch[i][j] = point4( v[X], v[Y], v[Z], 1.0 );
                               }
                           }

                           // Subdivide the patch
                               divide_patch( patch, NumTimesToSubdivide );
                           }

                           // Create a vertex array object
                           GLuint vao;
                           glGenVertexArrays( 1, &vao );
                           glBindVertexArray( vao );

                           // Create and initialize a buffer object
                           GLuint buffer;
                           glGenBuffers( 1, &buffer );
                           glBindBuffer( GL_ARRAY_BUFFER, buffer );
                           glBufferData( GL_ARRAY_BUFFER, sizeof(points), points,
                                          GL_STATIC_DRAW );

                           // Load shaders and use the resulting shader program
                           GLuint program = InitShader( "vshader101.glsl", "fshader101.glsl" );
                           glUseProgram( program );

                           // set up vertex arrays
                           GLuint vPosition = glGetAttribLocation( program, "vPosition" );
                           glEnableVertexAttribArray( vPosition );
                           glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
                                      BUFFER_OFFSET(0) );

                           Projection = glGetUniformLocation( program, "Projection" );

                           glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

                           glClearColor( 1.0, 1.0, 1.0, 1.0 );
                       }
                                                                    A.10 Teapot Renderer   663


//----------------------------------------------------------------------

void
display( void )
{
     glClear( GL_COLOR_BUFFER_BIT );
     glDrawArrays( GL_TRIANGLES, 0, NumVertices );
     glutSwapBuffers( void );
}

//----------------------------------------------------------------------

void
reshape( int width, int height )
{
     glViewport( 0, 0, width, height );

    GLfloat   left = -4.0, right = 4.0;
    GLfloat   bottom = -3.0, top = 5.0;
    GLfloat   zNear = -10.0, zFar = 10.0;

    GLfloat   aspect = GLfloat(width)/height;

    if ( aspect > 0 ) {
        left *= aspect;
        right *= aspect;
    }
    else {
        bottom /= aspect;
        top /= aspect;
    }

    mat4 projection = Ortho( left, right, bottom, top, zNear, zFar );
    glUniformMatrix4fv( Projection, 1, GL_TRUE, projection );
}

//----------------------------------------------------------------------

void
keyboard( unsigned char key, int x, int y )
{
     switch ( key ) {
     case ’q’: case ’Q’: case 033 // Escape key:
         exit( EXIT_SUCCESS );
         break;
     }
}

//----------------------------------------------------------------------

A.10.2 Vertex Shader و A.10.3 Fragment Shader

664   Appendix A   Sample Programs



                       int
                       main( int argc, char *argv[] )
                       {
                           glutInit( &argc, argv );
                           glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
                           glutInitWindowSize( 512, 512 );
                           glutInitContextVersion( 3, 2 );
                           glutInitContextProfile( GLUT_CORE_PROFILE );
                           glutCreateWindow( "teapot" );

                            glewInit( void );

                            init( void );

                            glutDisplayFunc( display );
                            glutReshapeFunc( reshape );
                            glutKeyboardFunc( keyboard );

                            glutMainLoop( void );
                            return 0;
                       }


                       A.10.2 Vertex Shader
                       #version 150

                       in   vec4 vPosition;

                       uniform mat4 Projection;

                       void main()
                       {
                           gl_Position = Projection * vPosition;
                       }


                       A.10.3 Fragment Shader
                       #version 150

                       out vec4 fColor;

                       void main()
                       {
                           fColor = vec4( 0.0, 0.0, 0.0, 1.0 );
                       }

امتیاز کاربران به این مقاله

☆☆☆☆☆

0 نفر امتیاز داده اند. میانگین: 0.0 از 5

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

0 / 500

اطلاعات تماس

  • آدرس:اصفهان-خیابان ام کلثوم غربی - بعد خیابان تخم چی - بیست متر بعد از پیتزا ننه شب - کوچه تعمیر گاه سمار زغالی - پلاک 354 - درب مشکی - طبقه هفتم
  • آدرس ایمیل:najafzade@gmail.com
  • وب سایت:http://www.a00b.com/
  • تلفن ثابت:(+98)9131253620
  • تلفن همراه:09131253620