原创 OpenGL 学习2

2009-10-6 18:04 2675 8 8 分类: 软件与OS
学习OpenGL过程中所编写的学习程序,从网上搜集整理改写而成,如果你第一次接触OpenGL,希望这个例子对你有所帮助,欢迎同行共同探讨
在Dialog中的用户区域上画一个简单的四棱锥,如下图所示,
0c7db35b-f6a0-49a2-a1e4-dd14391b8d72.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"

#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:
    GLfloat    fRotate;                                    // rotation
    HDC        hDC;
    HGLRC    hRC;

    BOOL SetWindowPixelFormat(HDC hDC);
    void RenderScene();

    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);
};
///////////////////////////////////////////////////////////////////////////////
// 用于运行对话框的应用程序命令
void CFirstOpenGlApp::OnAppAbout()
{    CAboutDlg aboutDlg;
    aboutDlg.DoModal();
}
///////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    ON_WM_CLOSE()
    ON_WM_DESTROY()
    ON_WM_PAINT()
    ON_WM_TIMER()
    ON_WM_ERASEBKGND()
   
    ON_BN_CLICKED(IDOK, &CAboutDlg::OnBnClickedOk)
END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////////
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{    fRotate    = 10.0f;                                // rotation
    hDC        = NULL;
    hRC    = NULL;
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{    CDialog::DoDataExchange(pDX);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CAboutDlg::OnInitDialog()
{    CDialog::OnInitDialog();

    //TODO:  在此添加额外的初始化
    hDC    =::GetDC(m_hWnd);

    // OpenGL Initialization
    glShadeModel(GL_SMOOTH);                            // Enable Smooth Shading
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                // Black Background
    glClearDepth(1.0f);                                    // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);                                // The Type Of Depth Testing To Do
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculations

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

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

    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);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnPaint()
{    CPaintDC dc(this); // device context for painting
   
    // TODO: 在此处添加消息处理程序代码
    RenderScene();
    SwapBuffers(hDC);

    // 不为绘图消息调用 CDialog::OnPaint()
}
///////////////////////////////////////////////////////////////////////////////
BOOL CAboutDlg::OnEraseBkgnd(CDC* pDC)
{    // TODO: 在此添加消息处理程序代码和/或调用默认值
    return FALSE;

    //return CDialog::OnEraseBkgnd(pDC);
}
///////////////////////////////////////////////////////////////////////////////
void CAboutDlg::OnTimer(UINT_PTR nIDEvent)
{    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if(nIDEvent==1)
    {    Invalidate(TRUE);
        //RenderScene();
        //SwapBuffers(hDC1);
    }

    CDialog::OnTimer(nIDEvent);
}
///////////////////////////////////////////////////////////////////////////////
//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();
    glRotatef(fRotate, 0.0f, 1.0f, 0.0f);

    glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 0.0f, 0.0f);        // Red
        glVertex3f(0.0f, 0.5f, 0.0f);        // top
        glColor3f(0.0f, 1.0f, 0.0f);        // Green       
        glVertex3f(-0.5f, -0.5f, 0.5f);        // left
        glColor3f(0.0f, 0.0f, 1.0f);        // Blue       
        glVertex3f(0.5f, -0.5f, 0.5f);        // right

        glColor3f(1.0f, 0.0f, 0.0f);        // Red
        glVertex3f(0.0f, 0.5f, 0.0f);        // Top Of Triangle (Right)
        glColor3f(0.0f, 0.0f, 1.0f);        // Blue
        glVertex3f(0.5f, -0.5f, 0.5f);        // Left Of Triangle (Right)
        glColor3f(0.0f, 0.5f, 0.0f);        // Green
        glVertex3f(0.5f, -0.5f, -0.5f);        // Right Of Triangle (Right)

        glColor3f(1.0f, 0.0f, 0.0f);        // Red
        glVertex3f(0.0f, 0.5f, 0.0f);        // Top Of Triangle (Back)
        glColor3f(0.0f, 1.0f, 0.0f);        // Green
        glVertex3f(0.5f, -0.5f, -0.5f);        // Left Of Triangle (Back)
        glColor3f(0.0f, 0.0f, 1.0f);        // Blue
        glVertex3f(-0.5f, -0.5f, -0.5f);    // Right Of Triangle (Back)

        glColor3f(1.0f, 0.0f, 0.0f);        // Red
        glVertex3f(0.0f, 0.5f, 0.0f);        // Top Of Triangle (Left)
        glColor3f(0.0f, 0.0f, 1.0f);        // Blue
        glVertex3f(-0.5f, -0.5f, -0.5f);    // Left Of Triangle (Left)
        glColor3f(0.0f, 1.0f, 0.0f);        // Green
        glVertex3f(-0.5f, -0.5f, 0.5f);        // Right Of Triangle (Left)
    glEnd();

    //glFlush();
    fRotate+=1.0f;
}
///////////////////////////////////////////////////////////////////////////////
可执行文件如下,
rar


PARTNER CONTENT

文章评论0条评论)

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