ضمیمه A: برنامه‌های نمونه 1 تا 7 و شیدرها | گرافیک تعاملی با OpenGL

ضمیمه A: برنامه‌های نمونه 1 تا 7 و شیدرها

ضمیمه A: برنامه‌های نمونه 1 تا 7 و شیدرها

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

ضمیمه A: برنامه‌های نمونهٔ ۱ تا ۷ و Shaderها

ضمیمه A — برنامه‌های نمونه

این ضمیمه کد منبع بسیاری از برنامه‌های نمونه‌ای را دربر دارد که در متن توسعه داده شدند. نسخه‌های همراه کتاب همچنین فایل‌های include مانند Angel.h، matrix.h و vector.h و یک Makefile برای مدیریت تفاوت معماری‌ها را شامل می‌شوند. نمونه‌های افزوده و یادداشت‌های پیاده‌سازی نیز همراه مجموعه ارائه شده‌اند.

driverهای کارت گرافیک، OpenGL را با ترکیبی از سخت‌افزار و نرم‌افزار پیاده‌سازی می‌کنند. بنابراین اگر driverها درست نصب شده باشند، استفاده از OpenGL در سامانه‌های مختلف از دید برنامه یکسان است؛ تفاوت کارت‌ها عمدتاً در کارایی، extensionهای پشتیبانی‌شده و نسخهٔ OpenGL است.

OpenGL روی بیشتر workstationها استاندارد است. در Windows کتابخانهٔ پویا و فایل‌های .lib/include همراه محیط‌های توسعه فراهم می‌شوند و فایل‌های GLUT یا freeglut نیز قابل استفاده‌اند. freeglut امکان بررسی سازگاری کد با نسخهٔ مشخصی از OpenGL را نیز می‌دهد. بیشتر کاربران می‌توانند از GLEW برای مدیریت version و extension استفاده کنند؛ در Mac معمولاً نیازی به GLEW نیست. در Linux نیز Mesa و driverهای سازندگان کارت‌ها گزینه‌های متداول‌اند.

برنامه‌های بعدی برای ارتباط با window system از GLUT استفاده می‌کنند و نام‌گذاری تابع‌ها مطابق OpenGL Programming Guide و GLUT Users Guide است. بخش بزرگی از کد میان نمونه‌ها مشترک است؛ بنابراین تابع‌هایی مانند reshape callback، تابع initialization و main بسیار شبیه‌اند و توضیح‌های مفصل فقط در اولین نمونه‌ها آمده‌اند.

هدف اصلی این نمونه‌ها نمایش اصول گرافیکی است، نه بهینه‌سازی. در بسیاری از موارد می‌توان برنامه‌ها را توسعه داد، کاراتر کرد یا همان نتیجهٔ بصری را با قابلیت دیگری از OpenGL ساخت.

برنامه‌های این ضمیمه عبارت‌اند از:

  1. تابع InitShader؛
  2. برنامهٔ تولید ۵۰۰۰ نقطه روی Sierpinski gasket؛
  3. نسخهٔ بازگشتی gasket؛
  4. مکعب چرخان با ارسال زاویه‌های rotation به GPU؛
  5. مشاهدهٔ مکعب با perspective؛
  6. مکعب چرخانِ shaded؛
  7. کرهٔ بازگشتی shaded با per-fragment lighting؛
  8. مکعب چرخان با texture؛
  9. برنامهٔ شکل مبتنی بر tree؛
  10. renderer قوری.

A.1 تابع مقداردهی اولیهٔ Shader

A.1.1 کد برنامه

کد زیر عیناً حفظ شده است:

#include "Angel.h" // Book header file

                       namespace Angel {

                       // Create a NULL-terminated string by reading the provided file
                       static char*
                       readShaderSource(const char* shaderFile)
                       {
                           FILE* fp = fopen(shaderFile, "r");

                             if ( fp == NULL ) { return NULL; }

                             fseek(fp, 0L, SEEK_END);
                             long size = ftell(fp);
                                                          A.1 Shader Initialization Function   609


    fseek(fp, 0L, SEEK_SET);
    char* buf = new char[size + 1];
    fread(buf, 1, size, fp);

    buf[size] = ’ ’;
    fclose(fp);

    return buf;
}


// Create a GLSL program object from vertex and fragment shader files

GLuint
InitShader(const char* vShaderFile, const char* fShaderFile)
{
    struct Shader {
        const char* filename;
        GLenum       type;
        GLchar*      source;
    } shaders[2] = {
        { vShaderFile, GL_VERTEX_SHADER, NULL },
        { fShaderFile, GL_FRAGMENT_SHADER, NULL }
    };

    GLuint program = glCreateProgram( void );

    for ( int i = 0; i < 2; ++i ) {
        Shader& s = shaders[i];
        s.source = readShaderSource( s.filename );
        if ( shaders[i].source == NULL ) {
            std::cerr << "Failed to read " << s.filename << std::endl;
            exit( EXIT_FAILURE );
        }

        GLuint shader = glCreateShader( s.type );
        glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
        glCompileShader( shader );

        GLint compiled;
        glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
        if ( !compiled ) {
            std::cerr << s.filename << " failed to compile:" << std::endl;
            GLint logSize;
            glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
            char* logMsg = new char[logSize];
            glGetShaderInfoLog( shader, logSize, NULL, logMsg );
            std::cerr << logMsg << std::endl;
            delete [] logMsg;

A.2 برنامهٔ Sierpinski Gasket

A.2.1 کد برنامه

610   Appendix A   Sample Programs



                                      exit( EXIT_FAILURE );
                                  }

                                  delete [] s.source;

                                  glAttachShader( program, shader );
                             }

                             // link and error check
                             glLinkProgram(program);

                             GLint linked;
                             glGetProgramiv( program, GL_LINK_STATUS, &linked );
                             if ( !linked ) {
                                 std::cerr << "Shader program failed to link" << std::endl;
                                 GLint logSize;
                                 glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
                                 char* logMsg = new char[logSize];
                                 glGetProgramInfoLog( program, logSize, NULL, logMsg );
                                 std::cerr << logMsg << std::endl;
                                 delete [] logMsg;

                                  exit( EXIT_FAILURE );
                             }

                             // use program object
                             glUseProgram(program);

                             return program;
                       }

                       }   // Close namespace Angel block




                       A.2       SIERPINSKI GASKET PROGRAM
                       A.2.1 Application Code
                       // Two-Dimensional Sierpinski Gasket
                       // Generated using randomly selected vertices and bisection

                       #include "Angel.h"
                       const int NumPoints = 5000;

                       void
                       init( void )
                       {
                            vec2 points[NumPoints];
                                                              A.2 Sierpinski Gasket Program   611


    // Specify the vertices for a triangle
    vec2 vertices[3] = {
        vec2( -1.0, -1.0 ), vec2( 0.0, 1.0 ), vec2( 1.0, -1.0 )
    };

    // Select an arbitrary initial point inside of the triangle
    points[0] = vec2( 0.25, 0.50 );

    // compute and store N-1 new points
    for ( int i = 1; i < NumPoints; ++i ) {
        int j = rand( void ) % 3;   // pick a vertex at random

        // Compute the point halfway between the selected vertex
        //   and the previous point
        points[i] = ( points[i - 1] + vertices[j] ) / 2.0;
    }

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

    // 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 );

    // Initialize the vertex position attribute from the vertex shader
    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0,
                           BUFFER_OFFSET(0) );

    glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}


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

void
display( void )
{
     glClear( GL_COLOR_BUFFER_BIT );     // clear the window
     glDrawArrays( GL_POINTS, 0, NumPoints );    // draw the points

A.2.2 Vertex Shader و A.2.3 Fragment Shader

612   Appendix A   Sample Programs



                           glFlush( void );
                       }

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

                       int
                       main( int argc, char **argv )
                       {
                           glutInit( &argc, argv );
                           glutInitDisplayMode( GLUT_RGBA );
                           glutInitWindowSize( 512, 512 );

                           // If you are using freeglut, the next two lines will check if
                           // the code is truly 3.2. Otherwise, comment them out

                           glutInitContextVersion( 3, 2 );
                           glutInitContextProfile( GLUT_CORE_PROFILE );

                           glutCreateWindow( "Sierpinski Gasket" );

                           glewInit( void );
                           init( void );
                           glutDisplayFunc( display );

                           glutMainLoop( void );
                           return 0;
                       }


                       A.2.2 Vertex Shader
                       #version 150   //GLSL Version 1.5

                       in vec4 vPosition;

                       void main()
                       {
                           gl_Position = vPosition;
                       }


                       A.2.3 Fragment Shader
                       #version 150

                       out vec4   fColor;

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

A.3 تولید بازگشتی Sierpinski Gasket

A.3.1 کد برنامه

                                             A.3 Recursive Generation of Sierpinski Gasket   613



A.3   RECURSIVE GENERATION OF SIERPINSKI GASKET
A.3.1 Application Code
// Recursive subdivision of triangle to form Sierpinski gasket
//   Number of recursive steps given on command line

#include "Angel.h"

using namespace Angel;

const int NumTimesToSubdivide = 5;
const int NumTriangles = 729; // 3^5 triangles generated
const int NumVertices = 3 * NumTriangles;

vec2 points[NumVertices];
int Index = 0;

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

void
triangle( const vec2& a, const vec2& b, const vec2& c )
{
     points[Index++] = a;
     points[Index++] = b;
     points[Index++] = c;
}

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

void
divide_triangle( const vec2& a, const vec2& b, const vec2& c, int count )
{
     if ( count > 0 ) {
     //compute midpoints of sides
         vec2 v0 = ( a + b ) / 2.0;
         vec2 v1 = ( a + c ) / 2.0;
         vec2 v2 = ( b + c ) / 2.0;
     //subdivide all but middle triangle
         divide_triangle( a, v0, v1, count - 1 );
         divide_triangle( c, v1, v2, count - 1 );
         divide_triangle( b, v2, v0, count - 1 );
     }
     else {
         triangle( a, b, c );     // draw triangle at end of recursion
     }
}
614   Appendix A   Sample Programs



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

                       void
                       init( void )
                       {
                            vec2 vertices[3] = {
                                vec2( -1.0, -1.0 ), vec2( 0.0, 1.0 ), vec2( 1.0, -1.0 )
                            };

                           // Subdivide the original triangle
                           divide_triangle( vertices[0], vertices[1], vertices[2],
                                            NumTimesToSubdivide );

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

                           // 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 );

                           // Initialize the vertex position attribute from the vertex shader
                           GLuint loc = glGetAttribLocation( program, "vPosition" );
                           glEnableVertexAttribArray( loc );
                           glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0,
                                                  BUFFER_OFFSET(0) );

                           glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
                       }

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

                       void
                       display( void )
                       {
                            glClear( GL_COLOR_BUFFER_BIT );
                            glDrawArrays( GL_TRIANGLES, 0, NumTriangles );
                            glFlush( void );
                       }

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

A.3.2 Vertex Shader، A.3.3 Fragment Shader و آغاز A.4 مکعب چرخان با rotation در shader

                                                   A.4 Rotating Cube with Rotation in Shader   615


int
main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA );
    glutInitWindowSize( 512, 512 );
    glutInitContextVersion( 3, 2 );
    glutInitContextProfile( GLUT_CORE_PROFILE );
    glutCreateWindow( "Sierpinski Gasket" );

      glewInit( void );

      init( void );

      glutDisplayFunc( display );

      glutMainLoop( void );
      return 0;
}


A.3.2 Vertex Shader
#version 150

in vec4 vPosition;

void main()
{
    gl_Position = vPosition;
}


A.3.3 Fragment Shader
#version 150

out vec4 fColor;

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



A.4     ROTATING CUBE WITH ROTATION IN SHADER
A.4.1 Application Code
//
// Display a rotating color cube
616   Appendix A   Sample Programs



                       // In this version, idle function increments angles
                       // which are sent to vertex shader where rotation takes place

                       #include "Angel.h"

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

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

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

                       // Vertices of a unit cube centered at origin, sides aligned with axes
                       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
                       };

                       // 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;   // The location of the "theta" shader uniform variable

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

                       // quad generates two triangles for each face and assigns colors
                       //    to the vertices
                                                 A.4 Rotating Cube with Rotation in Shader   617


int Index = 0;
void
quad( int a, int b, int c, int d )
{
     colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
     colors[Index] = vertex_colors[b]; points[Index] = vertices[b]; Index++;
     colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
     colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
     colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
     colors[Index] = vertex_colors[d]; points[Index] = vertices[d]; Index++;
}

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

// generate 12 triangles: 36 vertices and 36 colors
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 );
}

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

// OpenGL initialization
void
init( void )
{
     colorcube( void );

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

    // 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_STATIC_DRAW );
618   Appendix A   Sample Programs



                           glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
                           glBufferSubData( GL_ARRAY_BUFFER, sizeof(points),
                                            sizeof(colors), colors );

                           // set up vertex arrays
                           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(sizeof(points)) );

                           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
                       keyboard( unsigned char key, int x, int y )
                       {
                            switch( key ) {
                                case 033: // Escape Key
                                case ’q’: case ’Q’:
                                    exit( EXIT_SUCCESS );
                                    break;
                            }
                       }

                       //----------------------------------------------------------------------
                                                 A.4 Rotating Cube with Rotation in Shader   619


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 );
}

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

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

    glewInit( void );

    init( void );

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

    glutMainLoop( void );
    return 0;
}

A.4.2 Vertex Shader و A.4.3 Fragment Shader

620   Appendix A   Sample Programs



                       A.4.2 Vertex Shader
                       #version 150

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

                       uniform vec3 theta;

                       void main()
                       {
                           // Compute the sines and cosines of theta for each of
                           //   the three axes in one computation.
                           vec3 angles = radians( theta );
                           vec3 c = cos( angles );
                           vec3 s = sin( angles );

                           // Remember: these matrices are column-major
                           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;
                           gl_Position = rx * ry * rz * vPosition;
                       }



                       A.4.3 Fragment Shader
                       #version 150

                       in vec4 color;
                       out vec4 fColor;

                       void main()
                       {
                           fColor = color;
                       }

A.5 Perspective Projection

A.5.1 کد برنامه

                                                                   A.5 Perspective Projection   621



A.5      PERSPECTIVE PROJECTION
A.5.1 Application Code
// Perspective view of a color cube using LookAt( void ) and Frustum( void )

#include "Angel.h"

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

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

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

// Vertices of a unit cube centered at origin, sides aligned with axes
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
};

// Viewing transformation parameters

GLfloat radius = 1.0;
GLfloat theta = 0.0;
GLfloat phi = 0.0;

const GLfloat   dr = 5.0 * DegreesToRadians;

GLuint    model_view;   // model-view matrix uniform shader variable location
622   Appendix A   Sample Programs



                       // Projection transformation parameters

                       GLfloat    left = -1.0, right = 1.0;
                       GLfloat    bottom = -1.0, top = 1.0;
                       GLfloat    zNear = 0.5, zFar = 3.0;

                       GLuint    projection; // projection matrix uniform shader variable location

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

                       // quad generates two triangles for each face and assigns colors
                       //    to the vertices

                       int Index = 0;

                       void
                       quad( int a, int b, int c, int d )
                       {
                            colors[Index] = vertex_colors[a]; points[Index] = vertices[a];
                                            Index++;
                            colors[Index] = vertex_colors[b]; points[Index] = vertices[b];
                                            Index++;
                            colors[Index] = vertex_colors[c]; points[Index] = vertices[c];
                                            Index++;
                            colors[Index] = vertex_colors[a]; points[Index] = vertices[a];
                                            Index++;
                            colors[Index] = vertex_colors[c]; points[Index] = vertices[c];
                                            Index++;
                            colors[Index] = vertex_colors[d]; points[Index] = vertices[d];
                                            Index++;
                       }

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

                       // generate 12 triangles: 36 vertices and 36 colors
                       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.5 Perspective Projection   623


// OpenGL initialization
void
init( void )
{
     colorcube( void );

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

    // 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_STATIC_DRAW );
    glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
    glBufferSubData( GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors );

    // set up vertex arrays
    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(sizeof(points)) );

    model_view = glGetUniformLocation( program, "model_view" );
    projection = glGetUniformLocation( program, "projection" );

    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 );
624   Appendix A   Sample Programs



                           point4 eye( radius*sin(theta)*cos(phi),
                              radius*sin(theta)*sin(phi),
                              radius*cos(theta),
                              1.0 );
                           point4 at( 0.0, 0.0, 0.0, 1.0 );
                           vec4    up( 0.0, 1.0, 0.0, 0.0 );

                           mat4 mv = LookAt( eye, at, up );
                           glUniformMatrix4fv( model_view, 1, GL_TRUE, mv );

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

                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );

                           glutSwapBuffers( void );
                       }

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

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

                               case ’x’: left *= 1.1; right *= 1.1; break;
                               case ’X’: left *= 0.9; right *= 0.9; break;
                               case ’y’: bottom *= 1.1; top *= 1.1; break;
                               case ’Y’: bottom *= 0.9; top *= 0.9; break;
                               case ’z’: zNear *= 1.1; zFar *= 1.1; break;
                               case ’Z’: zNear *= 0.9; zFar *= 0.9; break;
                               case ’r’: radius *= 2.0; break;
                               case ’R’: radius *= 0.5; break;
                               case ’o’: theta += dr; break;
                               case ’O’: theta -= dr; break;
                               case ’p’: phi += dr; break;
                               case ’P’: phi -= dr; break;

                               case ’ ’: // reset values to their defaults
                                   left = -1.0;
                                   right = 1.0;
                                   bottom = -1.0;
                                   top = 1.0;
                                   zNear = 0.5;
                                   zFar = 3.0;

A.5.2 Vertex Shader

                                                                   A.5 Perspective Projection   625


            radius = 1.0;
            theta = 0.0;
            phi    = 0.0;
            break;
    }

    glutPostRedisplay( void );
}

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

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

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

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

    glewInit( void );

    init( void );

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

    glutMainLoop( void );
    return 0;
}




A.5.2 Vertex Shader
in vec4 vPosition;
in vec4 vColor;
out vec4 color;

uniform mat4 model_view;
uniform mat4 projection;

A.5.3 Fragment Shader

A.6 مکعب چرخانِ Shaded

A.6.1 کد برنامه

626   Appendix A   Sample Programs



                       void main()
                       {
                           gl_Position = projection*model_view*vPosition/vPosition.w;
                           color = vColor;
                       }


                       A.5.3 Fragment Shader
                       #version 150

                       in vec4 color;
                       out vec4 fColor;

                       void main()
                       {
                           fColor = color;
                       }



                       A.6     ROTATING SHADED CUBE
                       A.6.1 Application Code
                       //    Display a rotating cube with lighting
                       //
                       //    Light and material properties are sent to the shader as uniform
                       //      variables. Vertex positions and normals are sent after each
                       //      rotation.

                       #include "Angel.h"

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

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

                       point4 points[NumVertices];
                       vec3   normals[NumVertices];

                       // Vertices of a unit cube centered at origin, sides aligned with axes
                       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 )
                       };
                                                                A.6 Rotating Shaded Cube   627


// 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 };

// Model-view and projection matrices uniform location
GLuint ModelView, Projection;

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

// quad generates two triangles for each face and assigns colors
//    to the vertices

int Index = 0;

void
quad( int a, int b, int c, int d )
{
     // Initialize temporary vectors along the quad’s edge to
     //   compute its face normal
     vec4 u = vertices[b] - vertices[a];
     vec4 v = vertices[c] - vertices[b];

    vec3 normal = normalize( cross(u, v) );

    normals[Index] = normal; points[Index] = vertices[a]; Index++;
    normals[Index] = normal; points[Index] = vertices[b]; Index++;
    normals[Index] = normal; points[Index] = vertices[c]; Index++;
    normals[Index] = normal; points[Index] = vertices[a]; Index++;
    normals[Index] = normal; points[Index] = vertices[c]; Index++;
    normals[Index] = normal; points[Index] = vertices[d]; Index++;
}

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

// generate 12 triangles: 36 vertices and 36 colors
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 );
}

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

// OpenGL initialization
628   Appendix A   Sample Programs



                       void
                       init( void )
                       {
                            colorcube( 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(normals),
                               NULL, GL_STATIC_DRAW );
                           glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
                           glBufferSubData( GL_ARRAY_BUFFER, sizeof(points),
                                  sizeof(normals), normals );

                           // Load shaders and use the resulting shader program
                           GLuint program = InitShader( "vshader53.glsl", "fshader53.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) );

                           GLuint vNormal = glGetAttribLocation( program, "vNormal" );
                           glEnableVertexAttribArray( vNormal );
                           glVertexAttribPointer( vNormal, 3, GL_FLOAT, GL_FALSE, 0,
                                   BUFFER_OFFSET(sizeof(points)) );

                           // Initialize shader lighting parameters
                           point4 light_position( 0.0, 0.0, -1.0, 0.0 );
                           color4 light_ambient( 0.2, 0.2, 0.2, 1.0 );
                           color4 light_diffuse( 1.0, 1.0, 1.0, 1.0 );
                           color4 light_specular( 1.0, 1.0, 1.0, 1.0 );

                           color4 material_ambient( 1.0, 0.0, 1.0, 1.0 );
                           color4 material_diffuse( 1.0, 0.8, 0.0, 1.0 );
                           color4 material_specular( 1.0, 0.8, 0.0, 1.0 );
                           float material_shininess = 100.0;

                           color4 ambient_product = light_ambient * material_ambient;
                           color4 diffuse_product = light_diffuse * material_diffuse;
                           color4 specular_product = light_specular * material_specular;
                                                                  A.6 Rotating Shaded Cube   629


    glUniform4fv( glGetUniformLocation(program, "AmbientProduct"),
        1, ambient_product );
    glUniform4fv( glGetUniformLocation(program, "DiffuseProduct"),
        1, diffuse_product );
    glUniform4fv( glGetUniformLocation(program, "SpecularProduct"),
        1, specular_product );

    glUniform4fv( glGetUniformLocation(program, "LightPosition"),
        1, light_position );

    glUniform1f( glGetUniformLocation(program, "Shininess"),
       material_shininess );

    // Retrieve transformation uniform variable locations
    ModelView = glGetUniformLocation( program, "ModelView" );
    Projection = glGetUniformLocation( program, "Projection" );

    glEnable( GL_DEPTH_TEST );

    glShadeModel(GL_FLAT);

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

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

void
display( void )
{
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //   Generate the model-view matrix

    const vec3 viewer_pos( 0.0, 0.0, 2.0 );
    mat4 model_view = ( Translate( -viewer_pos ) *
          RotateX( Theta[Xaxis] ) *
          RotateY( Theta[Yaxis] ) *
          RotateZ( Theta[Zaxis] ) );

    glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view );

    glDrawArrays( GL_TRIANGLES, 0, NumVertices );
    glutSwapBuffers( void );
}

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

void
mouse( int button, int state, int x, int y )
630   Appendix A   Sample Programs



                       {
                           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 x, int y )
                       {
                            switch( key ) {
                                case 033: // Escape Key
                                case ’q’: case ’Q’:
                                    exit( EXIT_SUCCESS );
                                    break;
                            }
                       }

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

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

                           GLfloat aspect = GLfloat(width)/height;
                           mat4 projection = Perspective( 45.0, aspect, 0.5, 3.0 );

                           glUniformMatrix4fv( Projection, 1, GL_TRUE, projection );
                       }

A.6.2 Vertex Shader

                                                                A.6 Rotating Shaded Cube   631


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

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

    glewInit( void );

    init( void );

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

    glutMainLoop( void );
    return 0;
}



A.6.2 Vertex Shader
#version 150

in vec4 vPosition;
in vec3 vNormal;
out vec4 color;

uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform mat4 ModelView;
uniform mat4 Projection;
uniform vec4 LightPosition;
uniform float Shininess;
void main()
{
    // Transform vertex position into eye coordinates
    vec3 pos = (ModelView * vPosition).xyz;

    vec3 L = normalize( LightPosition.xyz - pos );
    vec3 E = normalize( -pos );
    vec3 H = normalize( L + E );

    // Transform vertex normal into eye coordinates
    vec3 N = normalize( ModelView*vec4(vNormal, 0.0) ).xyz;

A.6.3 Fragment Shader

A.7 نورپردازی Per-Fragment مدل کره

A.7.1 کد برنامه

632   Appendix A   Sample Programs



                             // Compute terms in the illumination equation
                             vec4 ambient = AmbientProduct;

                             float Kd = max( dot(L, N), 0.0 );
                             vec4 diffuse = Kd*DiffuseProduct;

                             float Ks = pow( max(dot(N, H), 0.0), Shininess );
                             vec4 specular = Ks * SpecularProduct;

                             if( dot(L, N) < 0.0 ) specular = vec4(0.0, 0.0, 0.0, 1.0);

                             gl_Position = Projection * ModelView * vPosition;

                             color = ambient + diffuse + specular;
                             color.a = 1.0;
                       }


                       A.6.3 Fragment Shader
                       #version 150

                       in vec4 color;
                       out vec4 fColor;

                       void main()
                       {
                           fColor = color;
                       }



                       A.7     PER-FRAGMENT LIGHTING OF SPHERE MODEL
                       A.7.1 Application Code
                       // fragment shading of sphere model

                       #include "Angel.h"

                       const int NumTimesToSubdivide = 5;
                       const int NumTriangles        = 4096;
                       // (4 faces)^(NumTimesToSubdivide + 1)
                       const int NumVertices         = 3 * NumTriangles;

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

                       point4 points[NumVertices];
                       vec3   normals[NumVertices];

                       // Model-view and projection matrices uniform location
                                                   A.7 Per-Fragment Lighting of Sphere Model   633


GLuint   ModelView, Projection;

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

int Index = 0;

void
triangle( const point4& a, const point4& b, const point4& c )
{
     vec3 normal = normalize( cross(b - a, c - b) );

    normals[Index] = normal;      points[Index] = a;   Index++;
    normals[Index] = normal;      points[Index] = b;   Index++;
    normals[Index] = normal;      points[Index] = c;   Index++;
}

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

point4
unit( const point4& p )
{
    float len = p.x*p.x + p.y*p.y + p.z*p.z;

    point4 t;
    if ( len > DivideByZeroTolerance ) {
        t = p / sqrt(len);
        t.w = 1.0;
    }

    return t;
}

void
divide_triangle( const point4& a, const point4& b,
        const point4& c, int count )
{
     if ( count > 0 ) {
         point4 v1 = unit( a + b );
         point4 v2 = unit( a + c );
         point4 v3 = unit( b + c );
         divide_triangle( a, v1, v2, count - 1 );
         divide_triangle( c, v2, v3, count - 1 );
         divide_triangle( b, v3, v1, count - 1 );
         divide_triangle( v1, v3, v2, count - 1 );
     }
     else {
         triangle( a, b, c );
     }
}
634   Appendix A   Sample Programs



                       void
                       tetrahedron( int count )
                       {
                            point4 v[4] = {
                                vec4( 0.0, 0.0, 1.0, 1.0 ),
                                vec4( 0.0, 0.942809, -0.333333, 1.0 ),
                                vec4( -0.816497, -0.471405, -0.333333, 1.0 ),
                                vec4( 0.816497, -0.471405, -0.333333, 1.0 )
                            };

                           divide_triangle( v[0], v[1], v[2], count );
                           divide_triangle( v[3], v[2], v[1], count );
                           divide_triangle( v[0], v[3], v[1], count );
                           divide_triangle( v[0], v[2], v[3], count );
                       }

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

                       // OpenGL initialization
                       void
                       init( void )
                       {
                            // Subdivide a tetrahedron into a sphere
                            tetrahedron( 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) + sizeof(normals),
                               NULL, GL_STATIC_DRAW );
                           glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
                           glBufferSubData( GL_ARRAY_BUFFER, sizeof(points),
                                  sizeof(normals), normals );

                           // Load shaders and use the resulting shader program
                           GLuint program = InitShader( "vshader56.glsl", "fshader56.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) );
                                                A.7 Per-Fragment Lighting of Sphere Model   635


    GLuint vNormal = glGetAttribLocation( program, "vNormal" );
    glEnableVertexAttribArray( vNormal );
    glVertexAttribPointer( vNormal, 3, GL_FLOAT, GL_FALSE, 0,
            BUFFER_OFFSET(sizeof(points)) );

    // Initialize shader lighting parameters
    point4 light_position( 0.0, 0.0, 2.0, 0.0 );
    color4 light_ambient( 0.2, 0.2, 0.2, 1.0 );
    color4 light_diffuse( 1.0, 1.0, 1.0, 1.0 );
    color4 light_specular( 1.0, 1.0, 1.0, 1.0 );

    color4 material_ambient( 1.0, 0.0, 1.0, 1.0 );
    color4 material_diffuse( 1.0, 0.8, 0.0, 1.0 );
    color4 material_specular( 1.0, 0.0, 1.0, 1.0 );
    float material_shininess = 5.0;

    color4 ambient_product = light_ambient * material_ambient;
    color4 diffuse_product = light_diffuse * material_diffuse;
    color4 specular_product = light_specular * material_specular;

    glUniform4fv( glGetUniformLocation(program, "AmbientProduct"),
        1, ambient_product );
    glUniform4fv( glGetUniformLocation(program, "DiffuseProduct"),
        1, diffuse_product );
    glUniform4fv( glGetUniformLocation(program, "SpecularProduct"),
        1, specular_product );

    glUniform4fv( glGetUniformLocation(program, "LightPosition"),
        1, light_position );

    glUniform1f( glGetUniformLocation(program, "Shininess"),
       material_shininess );

    // Retrieve transformation uniform variable locations
    ModelView = glGetUniformLocation( program, "ModelView" );
    Projection = glGetUniformLocation( program, "Projection" );

    glEnable( GL_DEPTH_TEST );

    glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}

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

void
display( void )
{
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    point4 at( 0.0, 0.0, 0.0, 1.0 );
636   Appendix A   Sample Programs



                           point4 eye( 0.0, 0.0, 2.0, 1.0 );
                           vec4   up( 0.0, 1.0, 0.0, 0.0 );

                           mat4 model_view = LookAt( eye, at, up );
                           glUniformMatrix4fv( ModelView, 16, GL_TRUE, model_view );

                           glDrawArrays( GL_TRIANGLES, 0, NumVertices );
                           glutSwapBuffers( void );
                       }

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

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

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

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

                           GLfloat left = -2.0, right = 2.0;
                           GLfloat top = 2.0, bottom = -2.0;
                           GLfloat zNear = -20.0, zFar = 20.0;

                           GLfloat aspect = GLfloat(width)/height;

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

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

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

A.7.2 Vertex Shader

                                                   A.7 Per-Fragment Lighting of Sphere Model   637


int
main( int argc, char **argv )
{

     glutInit( &argc, argv );
     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH );
     glutInitWindowSize( 512, 512 );
     glutCreateWindow( "Sphere" );

     glewInit( void );

     init( void );

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

     glutMainLoop( void );
     return 0;
}



A.7.2 Vertex Shader
#version 150

in   vec4 vPosition;
in   vec3 vNormal;

// output values that will be interpolated per-fragment
out vec3 fN;
out vec3 fE;
out vec3 fL;

uniform mat4 ModelView;
uniform vec4 LightPosition;
uniform mat4 Projection;

void main()
{
    fN = vNormal;
    fE = vPosition.xyz;
    fL = LightPosition.xyz;

     if( LightPosition.w != 0.0 ) {
         fL = LightPosition.xyz - vPosition.xyz;
     }

     gl_Position = Projection*ModelView*vPosition;
}

A.7.3 Fragment Shader

A.8 مکعب چرخان با Texture

A.8.1 کد برنامه (آغاز)

638   Appendix A   Sample Programs



                       A.7.3 Fragment Shader
                       #version 150

                       // per-fragment interpolated values from the vertex shader
                       in vec3 fN;
                       in vec3 fL;
                       in vec3 fE;

                       out vec4 fColor;

                       uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
                       uniform mat4 ModelView;
                       uniform vec4 LightPosition;
                       uniform float Shininess;

                       void main()
                       {
                           // Normalize the input lighting vectors
                           vec3 N = normalize(fN);
                           vec3 E = normalize(fE);
                           vec3 L = normalize(fL);

                             vec3 H = normalize( L + E );

                             vec4 ambient = AmbientProduct;

                             float Kd = max(dot(L, N), 0.0);
                             vec4 diffuse = Kd*DiffuseProduct;

                             float Ks = pow(max(dot(N, H), 0.0), Shininess);
                             vec4 specular = Ks*SpecularProduct;

                             // discard the specular highlight if the light’s behind the vertex
                             if( dot(L, N) < 0.0 ) {
                                 specular = vec4(0.0, 0.0, 0.0, 1.0);
                             }

                             fColor = ambient + diffuse + specular;
                             fColor.a = 1.0;
                       }




                       A.8     ROTATING CUBE WITH TEXTURE
                       A.8.1 Application Code
                       // rotating cube with two texture objects
                       // change textures with 1 and 2 keys

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

☆☆☆☆☆

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

 

0 نظر

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

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

0 / 500

اطلاعات تماس

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