• 入门系列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给我也行。先下线睡觉,晚安!


  • 相关阅读:
    静态代码块执行时机
    java中的命令
    JDBC
    final, finally, finalize
    面向对象
    线程中常用的一些方法
    线程中的yield()
    线程中的join()
    Thread对象 既传入了Runnable对象又重写了run()方法
    Python 绘制词云
  • 原文地址:https://www.cnblogs.com/oop/p/151758.html
Copyright © 2020-2023  润新知