下面是一个基于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.0, 1.0, 1.0 );
switch (CurrentMode)
{
case 0:
// Draw three points
//画三个点
glBegin(GL_POINTS);
glVertex2f( 1.0, 1.0 );
glVertex2f( 2.0, 1.0 );
glVertex2f( 2.0, 2.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.5, 1.0 );
glVertex2f( 2.0, 2.0 );
glVertex2f( 1.8, 2.6 );
glVertex2f( 0.7, 2.2 );
glVertex2f( 1.6, 1.2 );
glVertex2f( 1.0, 0.5 );
glEnd();
break;
case 4: // Overlapping triangles
glBegin( GL_TRIANGLES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.3, 1.0, 0.5 );
glVertex3f( 2.7, 0.85, 0.0 );
glVertex3f( 2.7, 1.15, 0.0 );
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f(2.53, 0.71, 0.5 );
glVertex3f(1.46, 2.86, 0.0 );
glVertex3f(1.2, 2.71, 0.0 );
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f(1.667, 2.79, 0.5);
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f(0.337, 0.786, 0.0);
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f(0.597, 0.636, 0.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( 0, 0, 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)/w < (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, -1, 1 );
}
// 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( 20, 60 );
glutInitWindowSize( 360, 360 );
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.
}
#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.0, 1.0, 1.0 );
switch (CurrentMode)
{
case 0:
// Draw three points
//画三个点
glBegin(GL_POINTS);
glVertex2f( 1.0, 1.0 );
glVertex2f( 2.0, 1.0 );
glVertex2f( 2.0, 2.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.5, 1.0 );
glVertex2f( 2.0, 2.0 );
glVertex2f( 1.8, 2.6 );
glVertex2f( 0.7, 2.2 );
glVertex2f( 1.6, 1.2 );
glVertex2f( 1.0, 0.5 );
glEnd();
break;
case 4: // Overlapping triangles
glBegin( GL_TRIANGLES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.3, 1.0, 0.5 );
glVertex3f( 2.7, 0.85, 0.0 );
glVertex3f( 2.7, 1.15, 0.0 );
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f(2.53, 0.71, 0.5 );
glVertex3f(1.46, 2.86, 0.0 );
glVertex3f(1.2, 2.71, 0.0 );
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f(1.667, 2.79, 0.5);
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f(0.337, 0.786, 0.0);
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f(0.597, 0.636, 0.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( 0, 0, 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)/w < (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, -1, 1 );
}
// 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( 20, 60 );
glutInitWindowSize( 360, 360 );
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.
}