迈克老狼

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

         下面是一个基于glut的OpenGL程序框架,用的是正投影,可以方便的通过参数设置Frustum的大小。

         通常可以用来做二维的demo,比如二维填充算法演示等等。

 

代码
//迈克老狼整理,参考3D Graphics书

#include 
<stdlib.h>
#include 
<stdio.h>
#include 
<GL/glew.h>    // muse be placed before glut. gkd
#include <GL/glut.h>    // OpenGL Graphics Utility Library

// These variables control the current mode
//一共有5种模式, CurrentMode表示当前显示模式
int CurrentMode = 0;
const int NumModes = 5;

// These variables set the dimensions of the rectanglar region we wish to view.
// 设置视口的大小,后面我们设置点的坐标在这个范围内,可以显示,否则被裁减。
const double Xmin = 0.0, Xmax = 3.0;
const double Ymin = 0.0, Ymax = 3.0;

// glutKeyboardFunc is called below to set this function to handle
//        all "normal" ascii key presses.
// Only space bar and escape key have an effect.
//处理普通按键的回调函数
void myKeyboardFunc( unsigned char key, int x, int y )
{
    
switch ( key ) 
    {

    
case ' ':                                    // Space bar
        
// Increment the current mode, and tell operating system screen needs redrawing
        CurrentMode = (CurrentMode+1)%NumModes;
        glutPostRedisplay();
        
break;

    
case 27:                                    // "27" is the Escape key
        exit(1);

    }
}


/*
 * drawScene() handles the animation and the redrawing of the
 *        graphics window contents.
 * 在窗口中画要显示的物体
 
*/
void drawScene(void)
{
    
// Clear the rendering window
    
//清楚颜色缓冲区和深度缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    
// Set drawing color to white
    
//设置画笔颜色为白色
    glColor3f( 1.01.01.0 );        

    
switch (CurrentMode)
    {

    
case 0:
        
// Draw three points
        
//画三个点
        glBegin(GL_POINTS);
        glVertex2f( 
1.01.0 );
        glVertex2f( 
2.01.0 );
        glVertex2f( 
2.02.0 );
        glEnd();
        
break;

    
case 1:
    
case 2:
    
case 3:
        
if ( CurrentMode==1 )
        {
            
// Draw lines in GL_LINES mode
            glBegin( GL_LINES );
        }
        
else if ( CurrentMode==2 )
        {
            
// Draw lines in GL_LINE_STRIP mode
            glBegin( GL_LINE_STRIP );
        }
        
else 
        {
            
// Draw lines in GL_LINE_LOOP mode
            glBegin( GL_LINE_LOOP );
        }
        glVertex2f( 
0.51.0 );
        glVertex2f( 
2.02.0 );
        glVertex2f( 
1.82.6 );
        glVertex2f( 
0.72.2 );
        glVertex2f( 
1.61.2 );
        glVertex2f( 
1.00.5 );
        glEnd();
        
break;

    
case 4:            // Overlapping triangles
        glBegin( GL_TRIANGLES );
        glColor3f( 
1.00.00.0 );
        glVertex3f( 
0.31.00.5 );
        glVertex3f( 
2.70.850.0 );
        glVertex3f( 
2.71.150.0 );

        glColor3f( 
0.01.00.0 );
        glVertex3f(
2.530.710.5 );
        glVertex3f(
1.462.860.0 );
        glVertex3f(
1.22.710.0 );

        glColor3f( 
0.00.01.0 );
        glVertex3f(
1.6672.790.5);
        glColor3f( 
1.00.00.0 );
        glVertex3f(
0.3370.7860.0);
        glColor3f( 
0.01.00.0 );
        glVertex3f(
0.5970.6360.0);
        glEnd();
    }

    
// Flush the pipeline.  (Not usually necessary.)
    glFlush();

}

// Initialize OpenGL's rendering modes
void initRendering()
{

    glEnable ( GL_DEPTH_TEST );

    
// Uncomment out the first block of code below, and then the second block,
    
//        to see how they affect line and point drawing.

    
// The following commands should cause points and line to be drawn larger
    
//    than a single pixel width.
    
//  设置点的大小和线的宽度
    glPointSize(8);
    glLineWidth(
5);

    
// The following commands should induce OpenGL to create round points and 
    
//    antialias points and lines.  (This is implementation dependent unfortunately).
    
//RGBA mode antialias need cooperate with blend function.
    
//点和线的反锯齿设置
    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);    
// Make round points, not square points
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);        // Antialias the lines
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


}

// Called when the window is resized
//        w, h - width and height of the window in pixels.
void resizeWindow(int w, int h)
{
    
double scale, center;
    
double windowXmin, windowXmax, windowYmin, windowYmax;

    
// Define the portion of the window used for OpenGL rendering.
    glViewport( 00, w, h );    // View port uses whole window

    
// Set up the projection view matrix: orthographic projection
    
// Determine the min and max values for x and y that should appear in the window.
    
// The complication is that the aspect ratio of the window may not match the
    
//        aspect ratio of the scene we want to view.
    
// 根据纵横比来改变视口的大小,保证物体不会变形。
    w = (w==0? 1 : w;
    h 
= (h==0? 1 : h;
    
if ( (Xmax-Xmin)/< (Ymax-Ymin)/h ) 
    {
        scale 
= ((Ymax-Ymin)/h)/((Xmax-Xmin)/w);
        center 
= (Xmax+Xmin)/2;
        windowXmin 
= center - (center-Xmin)*scale;
        windowXmax 
= center + (Xmax-center)*scale;
        windowYmin 
= Ymin;
        windowYmax 
= Ymax;
    }
    
else 
    {
        scale 
= ((Xmax-Xmin)/w)/((Ymax-Ymin)/h);
        center 
= (Ymax+Ymin)/2;
        windowYmin 
= center - (center-Ymin)*scale;
        windowYmax 
= center + (Ymax-center)*scale;
        windowXmin 
= Xmin;
        windowXmax 
= Xmax;
    }
    
    
// Now that we know the max & min values for x & y that should be visible in the window,
    
//        we set up the orthographic projection.
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( windowXmin, windowXmax, windowYmin, windowYmax, 
-11 );

}


// Main routine
// Set up OpenGL, define the callbacks and start the main loop
int main( int argc, char** argv )
{
    glutInit(
&argc,argv);

    
// The image is not animated so single buffering is OK. 
    
//单缓冲,RGB模式
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH );


    
// Window position (from top corner), and size (width and hieght)
    glutInitWindowPosition( 2060 );
    glutInitWindowSize( 
360360 );
    glutCreateWindow( 
"Simple OpenGL Demo - Press space bar to toggle images" );

    
//initialize glew
    
//初始化glew
    GLenum err = glewInit();
    
if (GLEW_OK != err)
    {
        
/* Problem: glewInit failed, something is seriously wrong. */
        fprintf(stderr, 
"Error: %s\n", glewGetErrorString(err));

    }
    fprintf(stdout, 
"Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));

    
//check opengl version and function extensions.
    if (GLEW_ARB_vertex_program)
    {
        
/* It is safe to use the ARB_vertex_program extension here. */
        fprintf(stdout, 
"glGenProgramsARB is suported\n");
    }
    
if (glewIsSupported("GL_VERSION_1_4  GL_ARB_point_sprite"))
    {
        
/* Great, we have OpenGL 1.4 + point sprites. */
        fprintf(stdout, 
"Great, we have OpenGL 1.4 + point sprites\n");
    }
    
if (glewGetExtension("GL_ARB_fragment_program"))
    {
        
/* Looks like ARB_fragment_program is supported. */
        fprintf(stdout, 
"Looks like ARB_fragment_program is supported\n");
    }

    
// Initialize OpenGL as we like it..
    initRendering();

    
// Set up callback functions for key presses
    glutKeyboardFunc( myKeyboardFunc );            // Handles "normal" ascii symbols
    
// glutSpecialFunc( mySpecialKeyFunc );        // Handles "special" keyboard keys

    
// Set up the callback function for resizing windows
    glutReshapeFunc( resizeWindow );

    
// Call this for background processing
    
// glutIdleFunc( myIdleFunction );

    
// call this whenever window needs redrawing
    glutDisplayFunc( drawScene );

    fprintf(stdout, 
"Press space bar to toggle images; escape button to quit.\n");
    
    
// Start the main loop.  glutMainLoop never returns.
    glutMainLoop(  );

    
return(0);    // This line is never reached.
}

 

 

posted on 2009-12-17 14:50  迈克老狼  阅读(663)  评论(0编辑  收藏  举报