原创 OpenGL 学习3

2009-10-6 18:25 3139 6 6 分类: 软件与OS
学习OpenGL过程中所编写的学习程序,从网上搜集整理改写而成,如果你第一次接触OpenGL,希望这个例子对你有所帮助,欢迎同行共同探讨
在Dialog中的用户区域上画三个齿轮,如下图所示,
a470f331-fb7e-4f84-bcd4-a7c322c0c288.gif
首先,在stdafx.h文件中包含相关头文件gl.h和glu.h,
然后,在项目属性页中添加opengl32.lib和glu32.lib,
所需的动态连接库opengl32.dll和glu32.dll位于目录c:\windows\system32下,
相关代码如下,
// FirstOpenGl.cpp : 定义应用程序的类行为。
#include "stdafx.h"
#include "FirstOpenGl.h"
#include "MainFrm.h"
#include "FirstOpenGlDoc.h"
#include "FirstOpenGlView.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define M_PI 3.14159265
static GLfloat viewDist = 1;            //40.0
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
static GLint gear1, gear2, gear3;
static GLfloat angle = 10.0;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
///////////////////////////////////////////////////////////////////////////////
// CFirstOpenGlApp
BEGIN_MESSAGE_MAP(CFirstOpenGlApp, CWinApp)
    ON_COMMAND(ID_APP_ABOUT, &CFirstOpenGlApp::OnAppAbout)
   
    // 基于文件的标准文档命令
    ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
    ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////////
// CFirstOpenGlApp 构造
CFirstOpenGlApp::CFirstOpenGlApp()
{    // TODO: 在此处添加构造代码,
    // 将所有重要的初始化放置在 InitInstance 中
}
///////////////////////////////////////////////////////////////////////////////
// 唯一的一个 CFirstOpenGlApp 对象
CFirstOpenGlApp theApp;
///////////////////////////////////////////////////////////////////////////////
// CFirstOpenGlApp 初始化
BOOL CFirstOpenGlApp::InitInstance()
{    // 如果一个运行在 Windows XP 上的应用程序清单指定要
    // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
    //则需要 InitCommonControlsEx()。否则,将无法创建窗口。
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // 将它设置为包括所有要在应用程序中使用的
    // 公共控件类。
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);

    CWinApp::InitInstance();

    // 初始化 OLE 库
    if (!AfxOleInit())
    {    AfxMessageBox(IDP_OLE_INIT_FAILED);
        return FALSE;
    }
    AfxEnableControlContainer();
    // 标准初始化
    // 如果未使用这些功能并希望减小
    // 最终可执行文件的大小,则应移除下列
    // 不需要的特定初始化例程
    // 更改用于存储设置的注册表项
    // TODO: 应适当修改该字符串,
    // 例如修改为公司或组织名
    SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
    LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)
    // 注册应用程序的文档模板。文档模板
    // 将用作文档、框架窗口和视图之间的连接
    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CFirstOpenGlDoc),
        RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
        RUNTIME_CLASS(CFirstOpenGlView));
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);

    // 分析标准外壳命令、DDE、打开文件操作的命令行
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    // 调度在命令行中指定的命令。如果
    // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;

    // 唯一的一个窗口已初始化,因此显示它并对其进行更新
    m_pMainWnd->ShowWindow(SW_SHOW);
    m_pMainWnd->UpdateWindow();
    // 仅当具有后缀时才调用 DragAcceptFiles
    //  在 SDI 应用程序中,这应在 ProcessShellCommand 之后发生
    return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// 对话框数据
    enum { IDD = IDD_ABOUTBOX };

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    virtual BOOL OnInitDialog();

// 实现
protected:
    DECLARE_MESSAGE_MAP()

public:
    HDC      hDC;
    HGLRC    hRC;
    BOOL    SetWindowPixelFormat(HDC hDC);
    void    RenderScene();
    void    gear(GLfloat inner_radius, GLfloat outer_radius,
                GLfloat width, GLint teeth, GLfloat tooth_depth);

    afx_msg void OnBnClickedOk();
    afx_msg void OnClose();
    afx_msg void OnDestroy();
    afx_msg void OnPaint();
    afx_msg void OnTimer(UINT_PTR nIDEvent);
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg void OnSize(UINT nType, int cx, int cy);

    afx_msg void OnBnClickedViewDistPlus();
    afx_msg void OnBnClickedViewDistSub();
    afx_msg void OnBnClickedRotateXPlus();
    afx_msg void OnBnClickedRotateXSub();
    afx_msg void OnBnClickedRotateYPlus();
    afx_msg void OnBnClickedRotateYSub();
    afx_msg void OnBnClickedOpenglInfo();
};
///////////////////////////////////////////////////////////////////////////////
// 用于运行对话框的应用程序命令
void CFirstOpenGlApp::OnAppAbout()
{    CAboutDlg aboutDlg;
    aboutDlg.DoModal();
}
///////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    ON_WM_CLOSE()
    ON_WM_DESTROY()
    ON_WM_PAINT()
    ON_WM_SIZE()
    ON_WM_TIMER()
    ON_WM_KEYDOWN()
    ON_WM_ERASEBKGND()
   
    ON_BN_CLICKED(IDOK, &CAboutDlg::OnBnClickedOk)
    ON_BN_CLICKED(IDC_VIEW_DIST_PLUS, &CAboutDlg::OnBnClickedViewDistPlus)
    ON_BN_CLICKED(IDC_VIEW_DIST_SUB, &CAboutDlg::OnBnClickedViewDistSub)
    ON_BN_CLICKED(IDC_ROTATE_X_PLUS, &CAboutDlg::OnBnClickedRotateXPlus)
    ON_BN_CLICKED(IDC_ROTATE_X_SUB, &CAboutDlg::OnBnClickedRotateXSub)
    ON_BN_CLICKED(IDC_ROTATE_Y_PLUS, &CAboutDlg::OnBnClickedRotateYPlus)
    ON_BN_CLICKED(IDC_ROTATE_Y_SUB, &CAboutDlg::OnBnClickedRotateYSub)
    ON_BN_CLICKED(IDC_OPENGL_INFO, &CAboutDlg::OnBnClickedOpenglInfo)
END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////////
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{    hDC        = NULL;
     hRC        = NULL;
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{    CDialog::DoDataExchange(pDX);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CAboutDlg::OnInitDialog()
{    CDialog::OnInitDialog();

    //TODO:  在此添加额外的初始化
    // For every window, we get the HDC
    hDC    =::GetDC(m_hWnd);

    SetWindowPixelFormat(hDC);
    hRC = wglCreateContext(hDC);
    wglMakeCurrent(hDC, hRC);

    glDrawBuffer(GL_BACK);
    SetTimer(1, 30, NULL);

    static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0};
    static GLfloat red[4] = {0.8, 0.2, 0.2, 1.0};
    static GLfloat green[4] = {0.2, 0.8, 0.2, 1.0};
    static GLfloat blue[4] = {0.2, 0.2, 0.8, 1.0};

    glLightfv(GL_LIGHT0, GL_POSITION, pos);
    glEnable(GL_CULL_FACE);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);

     /* make the gears */
    gear1 = glGenLists(1);
    glNewList(gear1, GL_COMPILE);
        glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
        gear(1.0, 4.0, 1.0, 20, 0.7);
    glEndList();

    gear2 = glGenLists(1);
    glNewList(gear2, GL_COMPILE);
        glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
        gear(0.5, 2.0, 2.0, 10, 0.7);
    glEndList();

    gear3 = glGenLists(1);
    glNewList(gear3, GL_COMPILE);
        glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
        gear(1.3, 2.0, 0.5, 10, 0.7);
    glEndList();

    glEnable(GL_NORMALIZE);

    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
}
///////////////////////////////////////////////////////////////////////////////
// CFirstOpenGlApp 消息处理程序
void CAboutDlg::OnBnClickedOk()
{    // TODO: 在此添加控件通知处理程序代码

    OnOK();
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnClose()
{    // TODO: 在此添加消息处理程序代码和/或调用默认值

    CDialog::OnClose();
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnDestroy()
{    CDialog::OnDestroy();

    // TODO: 在此处添加消息处理程序代码
    if(wglGetCurrentContext()!=NULL)
        wglMakeCurrent(NULL, NULL);            // make the rendering context not current

    if(hRC!=NULL)
    {    wglDeleteContext(hRC);
        hRC = NULL;
    }

    if(m_hWnd!=NULL)
        ::ReleaseDC(m_hWnd, hDC);

    glDeleteLists(gear1, 1);
    glDeleteLists(gear2, 1);
    glDeleteLists(gear3, 1);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnPaint()
{    CPaintDC dc(this); // device context for painting
   
    // TODO: 在此处添加消息处理程序代码
    RenderScene();
    SwapBuffers(hDC);

    // 不为绘图消息调用 CDialog::OnPaint()
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnSize(UINT nType, int cx, int cy)
{    CDialog::OnSize(nType, cx, cy);

    // TODO: 在此处添加消息处理程序代码
    GLfloat h = 0.0f;
    if(cx==0)
        h = (GLfloat)cy;
    else
        h = (GLfloat)cy / (GLfloat)cx;

    glViewport(0, 0, (GLint)cx, (GLint)cy);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -h, h, 5.0, 200.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();   
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnBnClickedViewDistPlus()
{    // TODO: 在此添加控件通知处理程序代码
    //viewDist -= 0.1;
    //InvalidateRect(NULL, FALSE);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnBnClickedViewDistSub()
{    // TODO: 在此添加控件通知处理程序代码
    //viewDist += 0.1;
    //InvalidateRect(NULL, FALSE);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnBnClickedRotateXPlus()
{    // TODO: 在此添加控件通知处理程序代码
    view_roty += 5.0;
    InvalidateRect(NULL, FALSE);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnBnClickedRotateXSub()
{    // TODO: 在此添加控件通知处理程序代码
    view_roty -= 5.0;
    InvalidateRect(NULL, FALSE);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnBnClickedRotateYPlus()
{    // TODO: 在此添加控件通知处理程序代码
    view_rotx += 5.0;
    InvalidateRect(NULL, FALSE);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnBnClickedRotateYSub()
{    // TODO: 在此添加控件通知处理程序代码
    view_rotx -= 5.0;
    InvalidateRect(NULL, FALSE);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CAboutDlg::OnEraseBkgnd(CDC* pDC)
{    // TODO: 在此添加消息处理程序代码和/或调用默认值
    return FALSE;

    //return CDialog::OnEraseBkgnd(pDC);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnTimer(UINT_PTR nIDEvent)
{    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if(nIDEvent==1)
    {    angle += 70.0;                    // 70 degrees per second
        angle = fmod(angle, 360.0f);    // prevents eventual overflow
        //view_rotz += 5.0;
        //RenderScene();
        //SwapBuffers(hDC);

        InvalidateRect(NULL, FALSE);
    }

    CDialog::OnTimer(nIDEvent);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnBnClickedOpenglInfo()
{    // TODO: 在此添加控件通知处理程序代码
    CString strTemp0("");
    CString strTemp("");

    strTemp0.Format("GL_RENDERER   = %s\n", (char *)glGetString(GL_RENDERER));
    strTemp += strTemp0;

    strTemp0.Format("GL_VERSION    = %s\n", (char *)glGetString(GL_VERSION));
    strTemp += strTemp0;

    strTemp0.Format("GL_VENDOR     = %s\n", (char *)glGetString(GL_VENDOR));
    strTemp += strTemp0;

    strTemp0.Format("GL_EXTENSIONS = %s", (char *)glGetString(GL_EXTENSIONS));
    strTemp += strTemp0;

    AfxMessageBox(strTemp);
}
///////////////////////////////////////////////////////////////////////////////
//BOOL CAboutDlg::SetWindowPixelFormat(HDC hDC)
//{    PIXELFORMATDESCRIPTOR pixelDesc;
//    pixelDesc.nSize        = sizeof(PIXELFORMATDESCRIPTOR);
//    pixelDesc.nVersion    = 1;
//
//    //pixelDesc.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP |
//    //    PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI | PFD_STEREO_DONTCARE;
//    pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
//                        PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE;
//    pixelDesc.iPixelType        = PFD_TYPE_RGBA;
//    pixelDesc.cColorBits        = 32;
//    pixelDesc.cRedBits            = 8;
//    pixelDesc.cRedShift            = 16;
//    pixelDesc.cGreenBits        = 8;
//    pixelDesc.cGreenShift        = 8;
//    pixelDesc.cBlueBits            = 8;
//    pixelDesc.cBlueShift        = 0;
//    pixelDesc.cAlphaBits        = 0;
//    pixelDesc.cAlphaShift        = 0;
//    pixelDesc.cAccumBits        = 64;
//    pixelDesc.cAccumRedBits        = 16;
//    pixelDesc.cAccumGreenBits    = 16;
//    pixelDesc.cAccumBlueBits    = 16;
//    pixelDesc.cAccumAlphaBits    = 0;
//    pixelDesc.cDepthBits        = 32;
//    pixelDesc.cStencilBits        = 8;
//    pixelDesc.cAuxBuffers        = 0;
//    pixelDesc.iLayerType        = PFD_MAIN_PLANE;
//    pixelDesc.bReserved            = 0;
//    pixelDesc.dwLayerMask        = 0;
//    pixelDesc.dwVisibleMask        = 0;
//    pixelDesc.dwDamageMask        = 0;
//
//    int m_GLPixelIndex = ChoosePixelFormat(hDC, &pixelDesc);
//    if(m_GLPixelIndex==0)                        // Let's choose a default index.
//    {    m_GLPixelIndex = 1;
//        if(DescribePixelFormat(hDC, m_GLPixelIndex,    sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc)==0)
//            return FALSE;
//    }
//   
//    if(SetPixelFormat(hDC, m_GLPixelIndex, &pixelDesc)==FALSE)
//        return FALSE;
//
//    return TRUE;
//}
BOOL CAboutDlg::SetWindowPixelFormat(HDC hDC)
{    PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),    // size of this pfd
        1,                                // version number
        PFD_DRAW_TO_WINDOW |              // support window
        PFD_SUPPORT_OPENGL |              // support OpenGL
        PFD_DOUBLEBUFFER,                 // double buffered
        PFD_TYPE_RGBA,                    // RGBA type
        24,                               // 24-bit color depth
        0, 0, 0, 0, 0, 0,                 // color bits ignored
        0,                                // no alpha buffer
        0,                                // shift bit ignored
        0,                                // no accumulation buffer
        0, 0, 0, 0,                       // accum bits ignored
        32,                               // 32-bit z-buffer    
        0,                                // no stencil buffer
        0,                                // no auxiliary buffer
        PFD_MAIN_PLANE,                   // main layer
        0,                                // reserved
        0, 0, 0                           // layer masks ignored
    };
   
    int    iPixelFormat = 0;
 
    // get the device context's best, available pixel format match
    if((iPixelFormat = ChoosePixelFormat(hDC, &pfd))==0)
        return FALSE;
     
    // make that match the device context's current pixel format
    if(SetPixelFormat(hDC, iPixelFormat, &pfd) == FALSE)
        return FALSE;

    return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// we will draw a simple 3D-Triangle
void CAboutDlg::RenderScene()
{    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glPushMatrix();
    //glTranslatef(0, 0, -viewDist);
    glScalef(0.1f, 0.1f, 0.1f);
   
    glRotatef(view_rotx, 1.0, 0.0, 0.0);
    glRotatef(view_roty, 0.0, 1.0, 0.0);
    glRotatef(view_rotz, 0.0, 0.0, 1.0);

    glPushMatrix();
        glTranslatef(-3.0, -2.0, 0.0);
        glRotatef(angle, 0.0, 0.0, 1.0);
        glCallList(gear1);
    glPopMatrix();

    glPushMatrix();
        glTranslatef(3.1, -2.0, 0.0);
        glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
        glCallList(gear2);
    glPopMatrix();

    glPushMatrix();
        glTranslatef(-3.1, 4.2, 0.0);
        glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
        glCallList(gear3);
    glPopMatrix();

    glPopMatrix();
}
///////////////////////////////////////////////////////////////////////////////
// 来自Mesa 的范例
void CAboutDlg::gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
                    GLint teeth, GLfloat tooth_depth)
{    GLint i;
    GLfloat r0, r1, r2;
    GLfloat angle, da;
    GLfloat u, v, len;

    r0 = inner_radius;
    r1 = outer_radius - tooth_depth / 2.0;
    r2 = outer_radius + tooth_depth / 2.0;

    da = 2.0 * M_PI / teeth / 4.0;

    glShadeModel(GL_FLAT);
    glNormal3f(0.0, 0.0, 1.0);

    /* draw front face */
    glBegin(GL_QUAD_STRIP);
        for(i = 0; i <= teeth; i++)
        {    angle = i * 2.0 * M_PI / teeth;
            glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
            glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
            if(i < teeth)
            {    glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
                glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
            }
        }
    glEnd();

    /* draw front sides of teeth */
    glBegin(GL_QUADS);
        da = 2.0 * M_PI / teeth / 4.0;
        for(i = 0; i < teeth; i++)
        {    angle = i * 2.0 * M_PI / teeth;

            glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
            glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
            glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
            glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
        }
    glEnd();

    glNormal3f(0.0, 0.0, -1.0);

    /* draw back face */
    glBegin(GL_QUAD_STRIP);
        for(i = 0; i <= teeth; i++)
        {    angle = i * 2.0 * M_PI / teeth;
            glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
            glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
            if(i < teeth)
            {    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
                glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
            }
        }
    glEnd();

    /* draw back sides of teeth */
    glBegin(GL_QUADS);
        da = 2.0 * M_PI / teeth / 4.0;
        for(i = 0; i < teeth; i++)
        {    angle = i * 2.0 * M_PI / teeth;

            glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
            glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
            glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
            glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
        }
    glEnd();

    /* draw outward faces of teeth */
    glBegin(GL_QUAD_STRIP);
        for(i = 0; i < teeth; i++)
        {    angle = i * 2.0 * M_PI / teeth;

            glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
            glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
            u = r2 * cos(angle + da) - r1 * cos(angle);
            v = r2 * sin(angle + da) - r1 * sin(angle);
            len = sqrt(u * u + v * v);
            u /= len;
            v /= len;
            glNormal3f(v, -u, 0.0);
            glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
            glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
            glNormal3f(cos(angle), sin(angle), 0.0);
            glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
            glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
            u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
            v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
            glNormal3f(v, -u, 0.0);
            glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
            glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
            glNormal3f(cos(angle), sin(angle), 0.0);
        }
        glVertex3f(r1 * cos(0.0f), r1 * sin(0.0f), width * 0.5);
        glVertex3f(r1 * cos(0.0f), r1 * sin(0.0f), -width * 0.5);
    glEnd();

    glShadeModel(GL_SMOOTH);

    /* draw inside radius cylinder */
    glBegin(GL_QUAD_STRIP);
        for(i = 0; i <= teeth; i++)
        {    angle = i * 2.0 * M_PI / teeth;
            glNormal3f(-cos(angle), -sin(angle), 0.0);
            glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
            glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
        }
    glEnd();
}
///////////////////////////////////////////////////////////////////////////////

可执行文件如下,
rar
该范例是本人在Mesa3d范例基础上改写的,原范例运行界面如下,
cf3c4b57-fa38-43f4-b592-9160502e6567.gif
源代码如下,
rar
存在问题:改写后齿轮的咬合没原来的好,三个齿轮分布在三个不同层面而不是在一个层面上,原因不明。



PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条