我與OpenGL的故事之三:簡單的三角形旋轉動畫

1、OpenGL 移動和旋轉的代碼:

移動代碼:glTranslatef(float a,float,b,float c);

如glTranslatef(1.5,1.5, 0);//移動旋轉中心的長度

旋轉代碼:glRotatef(float angle,float x,float y,float z);

如glRotatef(CurrentAngle, 0.0, 0.0, 1.0);

2、代碼演示

  • 2.1 插入.cpp文件、.h頭文件
我與OpenGL的故事之三:簡單的三角形旋轉動畫

源文件和頭文件

  • 2.2 在源文件中寫入代碼

#include <math.h>// For math routines (such as sqrt & trig)./<math.h>

#include <stdio.h>

#include <stdlib.h>// For the "exit" function/<stdlib.h>

#include // OpenGL Graphics Utility Library

#include "SimpleAnim.h"

int RunMode = 1;// Used as a boolean (1 or 0) for "on" and "off"

// The next global variable controls the animation's state and speed.

float CurrentAngle = 0.0f;// Angle in degrees

float AnimateStep = 3.0f;// Rotation step per update

// 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" key presses.

void myKeyboardFunc( unsigned char key, int x, int y )

{

switch ( key ) {

case 'r':

RunMode = 1-RunMode;// Toggle to opposite value

if ( RunMode==1 ) {

glutPostRedisplay();

}

break;

case 's':

RunMode = 1;

drawScene();

RunMode = 0;

break;

case 27:// Escape key

exit(1);

}

}

// glutSpecialFunc is called below to set this function to handle

//all "special" key presses. See glut.h for the names of

//special keys.

void mySpecialKeyFunc( int key, int x, int y )

{

switch ( key ) {

case GLUT_KEY_UP:

if ( AnimateStep < 1.0e3) {// Avoid overflow problems

AnimateStep *= sqrt(2.0);// Increase the angle increment

}

break;

case GLUT_KEY_DOWN:

if (AnimateStep>1.0e-6) {// Avoid underflow problems.

AnimateStep /= sqrt(2.0);// Decrease the angle increment

}

break;

}

}

/*

* drawScene() handles the animation and the redrawing of the

*graphics window contents.

*/

void drawScene(void)

{

// Clear the rendering window

glClearColor(0.0,0.0,0.0,0.0); //除顏色設為黑色

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //表示要清除顏色緩衝以及深度緩衝,實際完成了把整個窗口清除為黑色的任務

if (RunMode==1) {

// Calculate animation parameters

CurrentAngle += AnimateStep;

if ( CurrentAngle > 360.0 ) {

CurrentAngle -= 360.0*floor(CurrentAngle/360.0);// Don't allow overflow

}

}

// Rotate the image

glMatrixMode( GL_MODELVIEW );// Current matrix affects objects positions

glLoadIdentity();// Initialize to the identity

glTranslatef( 1.5, 1.5, 0.0 );// Translate rotation center from origin

glRotatef( CurrentAngle, 0.0, 0.0, 1.0 );// Rotate through animation angle

glTranslatef( -1.5, -1.5, 0.0 );// Translate rotation center to origin

// Draw three overlapping triangles of different colors

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

glVertex3f(0.337, 0.786, 0.0);

glVertex3f(0.597, 0.636, 0.0);

glEnd();

// Flush the pipeline, swap the buffers

glFlush();

glutSwapBuffers();

if ( RunMode==1 )

{

glutPostRedisplay();// Trigger an automatic redraw for animation

}

}

// Initialize OpenGL's rendering modes

void initRendering()

{

glShadeModel( GL_FLAT );// The default value of GL_SMOOTH is usually better

glEnable( GL_DEPTH_TEST );// Depth testing must be turned on

}

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

// We're going to animate it, so double buffer

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );

// Window position (from top corner), and size (width% and hieght)

glutInitWindowPosition( 10, 60 );

glutInitWindowSize( 360, 360 );

glutCreateWindow( "SimpleAnim" );

// 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, "Arrow keys control speed. Press \"r\" to run, \"s\" to single step.\\n");

// Start the main loop. glutMainLoop never returns.

glutMainLoop( );

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

}

  • 2.3 在頭文件中寫入代碼

// .cpp用到的函數

void myKeyboardFunc(unsigned char key, int x, int y);

void mySpecialKeyFunc(int key, int x, int y);

void drawScene(void);

void initRendering();

void resizeWindow(int w, int h);

3、運行代碼

我與OpenGL的故事之三:簡單的三角形旋轉動畫

4、代碼功能

(1)按下鍵盤上的"r"可停止或者恢復三角形旋轉

(2)按下鍵盤上的"s"單步運行旋轉。

通過這個案例學習了C++的基本編程方法、學習Opengl的移動、旋轉命令。


分享到:


相關文章: