首先参考这篇文章绘制一个球体:OpenGL 用参数方程绘制球

我们知道球体的参数方程是这样的:

x=r·sin(α)·cos(β)
y=r·sin(α)·sin(β)
z=r·cos(α)

椭圆的参数方程是:

x=rx·sin(α)·cos(β)
y=ry·sin(α)·sin(β)
z=rz·cos(α)

在这个基础上进行一些修改就可以实现椭圆的绘制了!

代码实现如下:

/***************************************************************************** Copyright: 2012, ustc All rights reserved. contact:k283228391@126.com File name: main.c Description:using opengl in SDL. Author:Silang Quan Version: 1.0 Date: 2012.12.01 *****************************************************************************/ #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #define pi 3.1415926 SDL_Surface *screen; typedef struct Point3f {  GLfloat x;  GLfloat y;  GLfloat z; }point;   int getPoint2(GLfloat rx,GLfloat ry,GLfloat rz,GLfloat a,GLfloat b,point &p) {     p.x=rx*sin(a*pi/180.0)*cos(b*pi/180.0);     p.y=ry*sin(a*pi/180.0)*sin(b*pi/180.0);     p.z=rz*cos(a*pi/180.0);     return 1; } point* getPointMatrix2(GLfloat rx,GLfloat ry,GLfloat rz,GLint slices) {  int i,j,w=2*slices,h=slices;  float a=0.0,b=0.0;  float hStep=180.0/(h-1);  float wStep=360.0/w;  int length=w*h;  point *matrix;  matrix=(point *)malloc(length*sizeof(point));  if(!matrix)return NULL;  for(a=0.0,i=0;i<h;i++,a+=hStep)   for(b=0.0,j=0;j<w;j++,b+=wStep)    getPoint2(rx,ry,rz,a,b,matrix[i*w+j]);  return matrix; }   void drawSlice(point &p1,point &p2,point &p3,point &p4) {  glBegin(GL_LINE_LOOP);  glColor3f(0,1,0);  glVertex3f(p1.x,p1.y,p1.z);  glVertex3f(p2.x,p2.y,p2.z);  glVertex3f(p3.x,p3.y,p3.z);  glVertex3f(p4.x,p4.y,p4.z);  glEnd(); }  int drawOval(GLfloat rx,GLfloat ry,GLfloat rz,GLint slices) {     int i=0,j=0,w=2*slices,h=slices;     point *mx;     mx=getPointMatrix2(rx,ry,rz,slices);     if(!mx)return 0;     for(;i<h-1;i++)  {     for(j=0;j<w-1;j++)     {         drawSlice(mx[i*w+j],mx[i*w+j+1],mx[(i+1)*w+j+1],mx[(i+1)*w+j]);     }     drawSlice(mx[i*w+j],mx[i*w],mx[(i+1)*w],mx[(i+1)*w+j]);  }  free(mx);  return 1; } void quit( int code ) {     SDL_Quit( );     /* Exit program. */     exit( code ); } void handleKeyEvent( SDL_keysym* keysym ) {     switch( keysym->sym ) 	{     case SDLK_ESCAPE:         quit( 0 );         break;     case SDLK_SPACE:         break;     default:         break;     } } void resizeGL(int width,int height) {     if ( height == 0 )     {         height = 1;     }     //Reset View     glViewport( 0, 0, (GLint)width, (GLint)height );     //Choose the Matrix mode     glMatrixMode( GL_PROJECTION );     //reset projection     glLoadIdentity();     //set perspection     gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );     //choose Matrix mode     glMatrixMode( GL_MODELVIEW );     glLoadIdentity(); } void handleEvents() {     // Our SDL event placeholder.     SDL_Event event;     //Grab all the events off the queue.     while( SDL_PollEvent( &event ) ) {         switch( event.type ) {         case SDL_KEYDOWN:             // Handle key Event             handleKeyEvent( &event.key.keysym );             break;         case SDL_QUIT:             // Handle quit requests (like Ctrl-c).             quit( 0 );             break;         case SDL_VIDEORESIZE: 			//Handle resize event             screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16,                                       SDL_OPENGL|SDL_RESIZABLE);             if ( screen )             {                 resizeGL(screen->w, screen->h);             }             break;         }     } }  void initSDL(int width,int height,int bpp,int flags) {     // First, initialize SDL's video subsystem.     if( SDL_Init( SDL_INIT_VIDEO ) < 0 )     {         fprintf( stderr, "Video initialization failed: %s\n",                  SDL_GetError( ) );         quit( 1 );     }     atexit(SDL_Quit); 	//Set some Attribute of OpenGL in SDL     SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );     SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );     SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );     SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );      //Set the video mode     screen= SDL_SetVideoMode( width, height, bpp,flags);     if(!screen )     {         fprintf( stderr, "Video mode set failed: %s\n",SDL_GetError( ) );         quit( 1 );     }     resizeGL(screen->w, screen->h);     //Set caption     SDL_WM_SetCaption( "OpenGL Test", NULL ); }  void renderGL() {     // Clear the color and depth buffers.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );     // We don't want to modify the projection matrix. */     glMatrixMode( GL_MODELVIEW );     glLoadIdentity( );     // Move down the z-axis.     glTranslatef( 0.0, 0.0, -25.0 );     glRotatef(50.0f,0,1,1); 	//Draw a square     drawSphere(10,20);     //drawOval(5,8,15,20);     SDL_GL_SwapBuffers( ); } void initGL( int width, int height ) {     float ratio = (float) width / (float) height;     // Our shading model--Gouraud (smooth).     glShadeModel( GL_SMOOTH );     // Set the clear color.     glClearColor( 0, 0, 0, 0 );     // Setup our viewport.     glViewport( 0, 0, width, height );     //Change to the projection matrix and set our viewing volume.     glMatrixMode( GL_PROJECTION );     glLoadIdentity();     gluPerspective( 60.0, ratio, 1.0, 100.0 ); } int main( int argc, char* argv[] ) {      // Dimensions of our window.     int width = 640;     int height = 480;     // Color depth in bits of our window.     int bpp = 32;     int flags= SDL_OPENGL|SDL_RESIZABLE;     //Set the SDL     initSDL(width, height, bpp,flags);     //Set the OpenGL     initGL( width, height );      //main loop     while(true) 	{         /* Process incoming events. */         handleEvents( );         /* Draw the screen. */         renderGL( );     }     return 0; }