回 帖 发 新 帖 刷新版面

主题:[原创]OpenGL入门学习——写给想用计算机画图的朋友

说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧?
但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。

[color=0000FF]本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。[/color]

OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。
[color=FF0000]1、与C语言紧密结合[/color]。
OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,[color=0000FF]使用OpenGL作图甚至比TC更加简单[/color]。
[color=FF0000]2、强大的可移植性[/color]。
微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL的基本命令都做到了硬件无关,甚至是平台无关。
[color=FF0000]3、高性能的图形渲染[/color]。
OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。
总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。
OpenGL官方网站(英文)
[color=0000FF]http://www.opengl.org[/color]

下面我将对Windows下的OpenGL编程进行简单介绍。

=====================未完,请勿跟帖=====================

回复列表 (共70个回复)

21 楼

真是对不起,原来Dev-C++的GLUT不是这样用的。具体的用法我也不清楚,不过我花了一点时间,写了一个GLUT的简化版,足够应付我现在举的各个例子。但以后的课程就很难说。
可惜的是,如果要写一个完全版,就不是几个钟头可以搞定的了。以我目前的水平,无法在有效时间内写出。
学到后面如果实在不行,还是装一个VS2005吧。

下面介绍Dev-C++下运行第一个OpenGL程序的方法。
[color=FF0000]1、新建工程[/color],选择Win32 GUI,不选Win32 Console

[color=FF0000]2、选项[/color],在Project -> Project Options中,选择Parameters标签,在最右边linker框中加入: -lopengl32 -lglu32

[color=FF0000]3、建一个文件OpenGL.c[/color],把上面的程序复制下来,但将第一行改为:
#include "glut.h"

[color=FF0000]4、建一个文件glut.h[/color],内容如下:
#ifndef _glut_h_
#define _glut_h_

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>

#define GLUT_INDEX  0x00000000
#define GLUT_RGB    0x80000000
#define GLUT_SINGLE 0x00000000
#define GLUT_DOUBLE PFD_DOUBLEBUFFER

void glutInit(int* argcp, char *argv[]);
void glutInitDisplayMode(unsigned int mode);
void glutInitWindowPosition(int x, int y);
void glutInitWindowSize(int width, int height);
void glutMainLoop(void);
int  glutCreateWindow(const char *title);
void glutDisplayFunc(void (*func)(void));
void glutSwapBuffers(void);

#endif

[color=FF0000]5、建一个文件glut.c[/color],内容如下:
#include "glut.h"

#include <stdio.h>
#include <stdlib.h>

static unsigned int DisplayMode = GLUT_RGB | GLUT_DOUBLE;
static int WindowX = CW_USEDEFAULT;
static int WindowY = CW_USEDEFAULT;
static int WindowWidth = CW_USEDEFAULT;
static int WindowHeight = CW_USEDEFAULT;

static HWND  hWnd = NULL;
static HDC   hDC  = NULL;
static HGLRC hRC  = NULL;

static void (*DisplayFunc)(void) = NULL;

static void Error(const char *msg)
{
       printf("错误,%s。\n");
       exit(1);
}

static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
       switch( msg )
       {
       case WM_PAINT:
            ValidateRect(hWnd, NULL);
            if( !DisplayFunc )
                Error("没有设置显示函数");
            DisplayFunc();
            return 0;
       case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
       }
       return DefWindowProc(hWnd, msg, wParam, lParam);
}

void glutInit(int* argcp, char *argv[])
{
}

void glutInitDisplayMode(unsigned int mode)
{
     if( mode & GLUT_RGB == 0 )
         Error("当前版本只支持RGB模式,不支持索引模式");
     DisplayMode = (mode&GLUT_DOUBLE)?(GLUT_DOUBLE):(0);
}

void glutInitWindowPosition(int x, int y)
{
     WindowX = x;
     WindowY = y;
}

void glutInitWindowSize(int width, int height)
{
     WindowWidth = width;
     WindowHeight = height;
}

void glutMainLoop(void)
{
     if( !hWnd )
     {
         printf("错误,没有创建窗口。\n");
         exit(1); 
     }
     for(;;)
     {
         MSG msg;
         int tmp = GetMessage(&msg, NULL, 0, 0);
         if( tmp <= 0 )
             break;
         TranslateMessage(&msg);
         DispatchMessage(&msg);
     }
}

int  glutCreateWindow(const char *title)
{
    WNDCLASSA wc;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = GetModuleHandle(NULL);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = title;
    if( !RegisterClass(&wc) )
        return 0;
    hWnd = CreateWindow(
        title,
        title,
        WS_OVERLAPPEDWINDOW,
        WindowX, WindowY, WindowWidth, WindowHeight,
        NULL, NULL, GetModuleHandle(NULL), NULL
        );

    PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR),1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | DisplayMode,
        PFD_TYPE_RGBA, 16,
        0,0,0,0,0,0,0,0,0,0,0,0,0,
        16,0,0,PFD_MAIN_PLANE,0,0,0,0
    };
    unsigned int pixelformat;
    if( !(hDC=GetDC(hWnd)) )
        return 0;
    if( !(pixelformat=ChoosePixelFormat(hDC, &pfd)) )
        return 0;
    if( !SetPixelFormat(hDC, pixelformat, &pfd))
        return 0;
    if( !(hRC=wglCreateContext(hDC)) )
        return 0;
    if( !wglMakeCurrent(hDC, hRC) )
        return 0;
    ShowWindow(hWnd, SW_SHOW);
    SetForegroundWindow(hWnd);
    SetFocus(hWnd);
    return 1;
}

void glutDisplayFunc(void (*func)(void))
{
     DisplayFunc = func;
}

void glutSwapBuffers(void)
{
     SwapBuffers(hDC);
}

[color=FF0000]6、保存,并编译之,然后运行[/color]

其中:glut.h和glut.c都是我临时写的,可能有一些问题。写这点东西主要还是说Dev-C++可以支持OpenGL编程,但由于我本人不知道Dev-C++如何使用GLUT,而我们现在的学习又用到GLUT,所以造成了一些不便。这也只好请各位克服以下了,当然也可以使用VS2005来避免这个问题。

22 楼

好东西!感谢楼主了!
慢慢学习!

23 楼

谢谢!我先顶一下

24 楼

给我上去![em11]

25 楼

楼主辛苦了

26 楼

我按照楼住说的,怎么不可以的 我用的是dev-c++ 

出现
1 C:\exam\opengl.c In file included from opengl.c 
43 C:\Dev-Cpp\include\gl\glut.h redeclaration of C++ built-in type `short' 
错误

是什么原因

27 楼

建议带上SDL,加上gcc编译(用win的使用dev-cpp)
这样就做到了openGL的平台无关性了,加上SDL的声音功能(SDL本身夸的平台不比openGL少)
作起游戏来就不比directX差了。
而游戏却不再是windows-only的了。

28 楼

顶啊
   顶啊
       顶啊

29 楼

顶啊 顶啊 顶啊

30 楼


谢谢啊

我来回复

您尚未登录,请登录后再回复。点此登录或注册