入门系列--OpenGL最简单的入门

入门系列--OpenGL最简单的入门




     现在是1:00了,在睡觉之前先写一点东西...想了一下,就简单的OpenGL入门介绍吧。在Windows下的用户都知道Direct X系列驱动吧,OpenGL也是与这种东西Direct3D作用很一样的。关于DirectX与OpenGL的详细介绍,文章太多了,国内有一篇文章介绍得很详细,而且历史脉络也说得很清楚,推荐看一下:http://www.zkxt.com/D3D_OPENGL_1.htm。作为一个程序员,单是了解这些还是不够的,不过,不看这篇文章的话更是不行,先看以上这篇文章再说吧。

    OpenGL全称"开放式图形库",是由SGI公司开发的低层三维图形API,目前在图形开发领域已经成为工业标准。作为一个标准,在其官方网站可以查看其标准:http://www.opengl.org/,主要是由非赢利组织ARB来维护,主要是C/C++库的实现,其他的实现现在已经有Java的支持http://www.opengl.org/resources/java/ (如:GL4Java)。不过,目前主要还是用于C/C++。在一些游戏产商的强烈要求下,微软公司也在Windows95以上的平台都实现了自己的操作系统的OpenGL库支持,SGI公司也有自己的一套实现,不过是作为软件来实现的,不支持硬件加速。

    以下就简单的介绍一下入门知识:

1、环境的选择:

     由于是国内很多用户都是Windows操作系统,现在我简单的介绍在Dev-C++中怎样编译自己的第一个OpenGL程序。Dev-C++是基于MinGW来开发的,关于这些信息请到网上查找吧。下载信息请看我的其他Blog( ftp://ftp.jaist.ac.jp )里为你提供的一个高速开源下载地址,登陆服务器后,在sourceforge系列里查找Dev-cpp文件夹,然后再下载就OK了。

     好了,打开Dev-C++,选择菜单:文件/新建/工程/MultiMedia,选择OpenGL,c++工程,然后确定就okay了。默认会替你创建一个样例的文件。你现在也可以编译运行它,F9快捷键(或者使用菜单:运行/编译运行也行)。好了,等待,一个不停选择的三角形在动了吧。

    等等,就这么简单的话,我肯定要被人骂死的,尤其是那些不熟悉Win32API函数的读者,根本就看不懂代码是在做什么。现在我来把这些简单化。

2、简单化的学习:

    找到代码:

    else
        {
            /* OpenGL animation code goes here */

            glClearColor (0.0f, 0.0f, 0.0f, 0.0f);  //这一行开始

            ....

            SwapBuffers (hDC);

            theta += 1.0f; //到这一行
            Sleep (1);

        }

        好的,主要的内容就在这里了,现在我们把这部分OpenGL绘图的内容提到一个函数drawGrapchics中,并放到其他文件中(这样的话,我们在学习中就可以简单的不管这个main.cpp文件了)。

       好了,现在我们创建一个新的文件simple.hpp吧,在左边的工程管理里,右击,然后新建单元,把这个文件保存为simple.hpp,把上面的相关代码剪切下来:

  float theta=1.0f;  //注意在原来的main.cpp的相关的这行东西,也剪切出来(这个主要是旋转控制角度的)
  void drawGraphics(HDC& hDC){
    glClearColor (0.0f, 0.0f, 0.0f, 0.0f);

    ......

    SwapBuffers (hDC);  //调用交换缓冲数据,无论哪中实现,这个最后都是要调用的。

    theta -= 1.0; //控制角度,旋转角度的大小
}   

main.cpp就变为:

...

#include "simple.hpp"     //添加头文件

....

else
        {
            /* OpenGL animation code goes here */
            drawGraphics(hDC); //简化为函数操作
            Sleep (1);

        }     

...

以后当你要练习其他的话,呵呵,就添加其他的,然后把#include "simple.hpp"改为自己测试的文件就行了,其他的都不用改。

3、大量的练习与学习:

      对于程序员来说,没有API函数查找是最为痛苦的事情了,在这方面Java做的最好。Dev-C++提供了Win32API和OpenGL API文档的参考手册下载,请到我上面提到的那个下载Dev-C++里面下载。

      最好的入门教材莫过于OpenGL的RedBook了http://www.opengl.org/documentation/red_book_1.0/ 官方网站提供了这个版本的1.1的免费下载,其他版本的话自己出钱好了....~~。注意,学习过程中,不要看其他的框架实现,你主要是看OpenGL的主要主要函数实现,由于RedBook使用的是aux的创建窗口的方法,所以这部分东西我们可以省略,主要就学习其中的gl的实现就OK了。

      其次,再一步就是看NeHe的教程,现在国内有中文版下载,上Google搜索下载就行了。

      其他的就等着学习,自己写代码,经验学习了....

4、核对一下,完整的代码(以免误解了我的说解~~~):

首先是main.cpp:

/**************************
 * Includes
 *
 **************************/

#include <windows.h>
#include <gl/gl.h>
#include "simple.hpp"
//::void drawGraphics(HDC&);使用opengl

/**************************
 * Function Declarations
 *
 **************************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);
/**************************
 * WinMain
 *
 **************************/

int WINAPI WinMain (HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,
                    int iCmdShow)
{
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;       
    MSG msg;
    BOOL bQuit = FALSE;

    /* register window class */
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "GLSample";
    RegisterClass (&wc);

    /* create main window */
    hWnd = CreateWindow (
      "GLSample", "OpenGL Sample",
      WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
      0, 0, 256, 256,
      NULL, NULL, hInstance, NULL);

    /* enable OpenGL for the window */
    EnableOpenGL (hWnd, &hDC, &hRC);

    /* program main loop */
    while (!bQuit)
    {
        /* check for messages */
        if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }
        }
        else
        {
            /* OpenGL animation code goes here */
   drawGraphics(hDC);
            Sleep (2);

        }
    }

    /* shutdown OpenGL */
    DisableOpenGL (hWnd, hDC, hRC);

    /* destroy the window explicitly */
    DestroyWindow (hWnd);

    return msg.wParam;
}


/********************
 * Window Procedure
 *
 ********************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
                          WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage (0);
        return 0;

    case WM_DESTROY:
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;
        }
        return 0;

    default:
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
}


/*******************
 * Enable OpenGL
 *
 *******************/

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    /* get the device context (DC) */
    *hDC = GetDC (hWnd);

    /* set the pixel format for the DC */
    ZeroMemory (&pfd, sizeof (pfd));
    pfd.nSize = sizeof (pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW |
      PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat (*hDC, &pfd);
    SetPixelFormat (*hDC, iFormat, &pfd);

    /* create and enable the render context (RC) */
    *hRC = wglCreateContext( *hDC );
    wglMakeCurrent( *hDC, *hRC );

}


/******************
 * Disable OpenGL
 *
 ******************/

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent (NULL, NULL);
    wglDeleteContext (hRC);
    ReleaseDC (hWnd, hDC);
}

其次是simple.hpp:

//simple.hpp
float theta=1.0f;
void drawGraphics(HDC& hDC){
    glClear (GL_COLOR_BUFFER_BIT);

    glPushMatrix ();
    glRotatef (theta, 0.0f, 0.0f, 1.0f);
    glBegin (GL_TRIANGLES);
     glColor3f (1.0f, 0.0f, 0.0f);   glVertex2f (0.0f, 1.0f);
     glColor3f (0.0f, 1.0f, 0.0f);   glVertex2f (0.87f, -0.5f);
        glColor3f (0.0f, 0.0f, 1.0f);   glVertex2f (-0.87f, -0.5f);
    glEnd ();
    glPopMatrix ();

    SwapBuffers (hDC);

    theta -= 1.0;
}

5、好了,简单的怎样介绍入门的就到这里了,想学习OpenGL的哥们,还有MM,剩下的功夫到你自己了,努力去看,努力去写吧...不要相信自己的眼力,不要相信自己理解了,实践才是真理:-)

Note:oh,写了40多分钟....郁闷!要睡觉了~~~各位朋友,有问题的话留言给我;或者看我的联系方法,发E-mail给我也行。先下线睡觉,晚安!


posted @ 2005-05-09 15:30  OOP  阅读(641)  评论(0编辑  收藏  举报