游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3303|回复: 7

OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

[复制链接]

96

主题

529

帖子

539

积分

高级会员

Rank: 4

积分
539
发表于 2004-11-15 12:28:00 | 显示全部楼层 |阅读模式
小弟刚开始学习OpenGL,准备用OpenGL开发一个程序,同时需要在屏幕上画上一些2D的自定义控件。小弟查看了下载的NEHE OpenGL教程,发现OpenGL里面没有提供真正的2D函数库,而是用3D库去摸拟2D,这明显是一种资源和时间上的浪费,就像打苍蝇硬要用大炮轰一样。OpenGL难道就真的没有真正的2D函数库吗?

小弟十分的困惑,不知道怎样才能在使用OpenGL的同时进行真正的2D绘制操作,节省更多的效率和资源。
不知道是否有这方面的教程。

还希望高手不吝赐教!小弟先谢了!!!

1

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2004-11-15 12:41:00 | 显示全部楼层

Re:OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

把3D的东西在屏幕上做正投影不就成了2D么。你只要保持这种固定的坐标就行了,速度比用GDI要快得多。另外,DirectX8.0以后也是用Direct3D来取代DirectDraw而且这样更简便且具通用性.如果你用过就不会对此感到奇怪了。

28

主题

685

帖子

703

积分

高级会员

Rank: 4

积分
703
发表于 2004-11-15 12:43:00 | 显示全部楼层

Re:OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

这种苍蝇拍一般都有几万行代码呢。
DX的苍蝇拍也有1万行左右了。

1

主题

60

帖子

60

积分

注册会员

Rank: 2

积分
60
发表于 2004-11-15 14:18:00 | 显示全部楼层

Re:OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

写一个纯2D实现的苍蝇拍才需要几万行代码吧?

96

主题

529

帖子

539

积分

高级会员

Rank: 4

积分
539
 楼主| 发表于 2004-11-16 19:59:00 | 显示全部楼层

Re:OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

谢谢大家的指点

63

主题

871

帖子

891

积分

高级会员

Rank: 4

积分
891
QQ
发表于 2004-11-17 16:03:00 | 显示全部楼层

Re:OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

俺的苍蝇拍也差不多1w而已(没数过)

14

主题

245

帖子

256

积分

中级会员

Rank: 3Rank: 3

积分
256
QQ
发表于 2004-11-20 23:01:00 | 显示全部楼层

Re: OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

以下是一个2D示例,OpenGL下的2D功能一点不比3D的差.只是人们用2D用得少.以下是 一个示例.
#include <math.h>

HGLRC hRC;
HDC   hDC;

//回调函数
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM ,LPARAM);

//设置视见区大小
void SceneResizeViewport(GLsizei w,GLsizei h)
{
        if(h==0)
                h=1;
        //设置视见区
        glViewport(0,0,w,h);

        //重置投影矩阵
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        //设置修剪范围
        glOrtho(0,w,h,0,0,1);
        //重置模形矩阵
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
}

//把绘制信息全放到一个函数里进行
//#define GL_PI 3.1415f
void Draw()
{
  glPushMatrix();

  glBegin(GL_TRIANGLES);
    glVertex2f(25.0f,0.0f);
    glVertex2f(0.0f ,25.0f);
    glVertex2f(50.0f,25.0f);
  glEnd();

  glPopMatrix();
}

//在这里进行渲染
void SceneShow()
{
        //清除缓冲区及深度缓冲区
        glClear(GL_COLOR_BUFFER_BIT );
        //重置所有的矩阵
        glLoadIdentity();
        //以下绘制开始
        Draw();

        //交换缓冲区,显示
        SwapBuffers(hDC);
}

//初始化OpenGL
void InitOpenGL(HWND hWnd)
{
        PIXELFORMATDESCRIPTOR pfd;
        int iFormat;

        //从窗口句柄取得设备句柄
        hDC=GetDC(hWnd);

        //以下设置像素格式
        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        = 16;
        pfd.cDepthBits        = 16;
        pfd.iLayerType        = PFD_MAIN_PLANE;

        //设置像素格式
        iFormat=ChoosePixelFormat(hDC,&pfd);
        SetPixelFormat(hDC,iFormat,&pfd);
        //创建渲染场景
        hRC=wglCreateContext(hDC);
        //设置为当前渲染场景
        wglMakeCurrent(hDC,hRC);

        glShadeModel(GL_SMOOTH);                                //允许平滑着色
        glClearColor(0.0f,0.0f,0.0f,1.0f);                //设置清屏颜色

        //下面的代码没有确切的意思.是为了程序在运行初始能够显示而设立的
        RECT rect;
        int sw,sh;

        GetClientRect(hWnd,&rect);
        sw=rect.right-rect.left;
        sh=rect.bottom-rect.top;

        if(sw > 0 && sh >0 )
        {
                SceneResizeViewport(sw,sh);
        }

}

//释放OpenGL和窗体对象
void ReleaseOpenGL(HWND hWnd)
{
        wglMakeCurrent(NULL,NULL);
        wglDeleteContext(hRC);
        ReleaseDC(hWnd,hDC);
}

//更改分辩率
bool ChangeResolution(int w,int h,int bitdepth,int fre)
{
        DEVMODE devMode;
        int modeSwitch;
        int closeMode=0;

        //枚举
        EnumDisplaySettings(NULL,closeMode,&devMode);

        //设置为当前所请求的
        devMode.dmBitsPerPel=bitdepth;
        devMode.dmPelsHeight=h;
        devMode.dmPelsWidth        =w;
        devMode.dmDisplayFrequency=fre;

        devMode.dmFields=DM_BITSPERPEL | DM_PELSWIDTH |DM_PELSHEIGHT|DM_DISPLAYFREQUENCY;

        //更改
        modeSwitch=ChangeDisplaySettings(&devMode,CDS_FULLSCREEN);

        if(modeSwitch==DISP_CHANGE_SUCCESSFUL)
        {
                return true;
        }
        else
        {
                return false;
        }
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
        RECT rect;
        int sw,sh;

        switch(message)
        {
        case WM_SIZE:
                GetClientRect(hWnd,&rect);
                sw=rect.right-rect.left;
                sh=rect.bottom-rect.top;

                if(sw > 0 && sh >0 )
                {
                        SceneResizeViewport(sw,sh);
                }
                return 0;

        case WM_CLOSE:
                PostQuitMessage(0);
                return 0;
        case WM_KEYDOWN:
                switch(wParam)
                {
                case VK_ESCAPE:
                        PostMessage(hWnd,WM_CLOSE,0,0);
                        break;
                }
                return 0;
        }

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

//创建一个窗口供OpenGL使用.
//窗口标题,程序实例句柄,窗口宽,高,颜色位,是否全屏
HWND CreateOpenGL(char*title,HINSTANCE hInst,int sw,int sh,int bit,bool fullscreen)
{
        HWND hWnd;
        WNDCLASS wc;

        wc.style         = CS_OWNDC;
        wc.lpfnWndProc         = WndProc;
        wc.cbClsExtra         = 0;
        wc.cbWndExtra         = 0;
        wc.hInstance         = hInst;
        wc.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
        wc.hCursor         = LoadCursor(NULL,IDC_ARROW);
        wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        wc.lpszMenuName         = NULL;
        wc.lpszClassName = "OpenGL框架程序";

        //注册窗口类
        RegisterClass(&wc);

        //全屏模式开
        if(fullscreen)
        {
                //创建窗口
                hWnd=CreateWindow("OpenGL框架程序",title,WS_POPUP | WS_CLIPSIBLINGS | WS_VISIBLE,
                        0,0,sw,sh,NULL,NULL,hInst,NULL);
        }
        else
        {
                //让窗口保持在屏幕的正中间,计算左起,和上起 坐标
                int t,l;
                l=(GetSystemMetrics(SM_CXSCREEN)-sw)/2;
                t=(GetSystemMetrics(SM_CYSCREEN)-sh)/2;

                hWnd=CreateWindow("OpenGL框架程序",title,WS_VISIBLE|WS_THICKFRAME|WS_SYSMENU|WS_MINIMIZEBOX,
                        l,t,sw,sh,NULL,NULL,hInst,NULL);
        }

        //显示窗口
        ShowWindow(hWnd,SW_SHOW);
        //更新
        UpdateWindow(hWnd);

        if(fullscreen)
        {
                //更改分辩率
                ChangeResolution(sw,sh,bit,75);
                //隐藏鼠标
                ShowCursor(false);
        }

        //返回窗口句柄
        return hWnd;
}

//入口函数
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int)
{
        MSG msg;
        HWND hWnd;
        bool fullscreen=false;

        //创建窗口
        hWnd=CreateOpenGL("OpenGL 2D",hInst,800,600,16,fullscreen);

        //初始化OpenGL设置
        InitOpenGL(hWnd);

        //进入循环
        while(1)
        {
                if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
                {
                        if(msg.message==WM_QUIT)
                        {
                                break;
                        }
                        else
                        {
                                TranslateMessage(&msg);
                                DispatchMessage(&msg);
                        }
                }
                else
                {
                                SceneShow();
                }
        }

        ReleaseOpenGL(hWnd);
        DestroyWindow(hWnd);

        return 0;
}

14

主题

245

帖子

256

积分

中级会员

Rank: 3Rank: 3

积分
256
QQ
发表于 2004-11-20 23:04:00 | 显示全部楼层

Re:OpenGL只给我们提供了大炮而没有给我们提供苍蝇拍?

看<<OpenGL超级宝典>>有对2D函数详细的介绍.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-23 09:01

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表