标题:这个OpenGL旋转动画真的很爽
只看楼主
qq1023569223
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:湖南科技大学
等 级:贵宾
威 望:26
帖 子:2753
专家分:13404
注 册:2010-12-22
结帖率:100%
 问题点数:0 回复次数:4 
这个OpenGL旋转动画真的很爽
程序代码:
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

HGLRC hRC=NULL;            //窗口着色描述表句柄
HDC   hDC=NULL;            //OpenGL渲染描述表句柄
HWND  hWnd=NULL;           //保存窗口句柄
HINSTANCE hInstance;       //保存程序实例

bool keys[256];            //保存键盘按键的数组
bool active=true;          //窗口的活动状态,默认为true
bool fullscreen=true;      //全屏状态,默认为true

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);   //定义WndProc


GLvoid ReSizeGLScene(GLsizei width,GLsizei height)   //重置OpenGL窗口大小
{
    if(height==0)
    {
        height=1;
    }

    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

int InitGL(GLvoid)  //对OpenGL进行所有的设置
{
    glShadeModel(GL_SMOOTH);

    glClearColor(0.0f,0.0f,0.0f,0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    return 1;
}


    GLfloat rtri=0.5f;
    GLfloat rquad=1.0f;

int DrawGLScene(GLvoid)  //从这里开始所有的绘制
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(-1.5f,0.0f,-6.0f);

    glRotatef(rtri,0.0f,1.0f,0.0f);

    glBegin(GL_TRIANGLES);                          // 绘制三角形
        glColor3f(1.0f,0.0f,0.0f);
        glVertex3f( 0.0f, 1.0f, 0.0f);                // 上顶点
        glColor3f(0.0f,1.0f,0.0f);
        glVertex3f(-1.0f,-1.0f, 0.0f);                // 左下
        glColor3f(0.0f,0.0f,1.0f);
        glVertex3f( 1.0f,-1.0f, 0.0f);                // 右下
    glEnd();
   
    glTranslatef(3.0f,0.0f,0.0f);

    glRotatef(rquad,1.0f,0.0f,0.0f);

    glBegin(GL_QUADS);                                 //  绘制正方形
        glColor3f(0.5f,0.5f,1.0f);
        glVertex3f(-1.0f, 1.0f, 0.0f);                    // 左上
        glVertex3f( 1.0f, 1.0f, 0.0f);                 // 右上
        glVertex3f( 1.0f,-1.0f, 0.0f);                 // 左下
        glVertex3f(-1.0f,-1.0f, 0.0f);                 // 右下
    glEnd();

    rtri+=0.5f;
    rquad+=0.5f;

    return 1;
}

GLvoid KillGLWindow(GLvoid)  //正常销毁窗口
{
    if(fullscreen)
    {
        ChangeDisplaySettings(NULL,0);
        ShowCursor(true);
    }

    if(hRC)
    {
        if(!wglMakeCurrent(NULL,NULL))
        {
            MessageBox(NULL,"释放DC或者RC失败","关闭错误",MB_OK|MB_ICONINFORMATION);
        }

        if(!wglDeleteContext(hRC))
        {
            MessageBox(NULL,"释放RC失败","关闭错误",MB_OK|MB_ICONINFORMATION);
        }

        hRC=NULL;
    }

    if(hDC&&!DestroyWindow(hWnd))
    {
        MessageBox(NULL,"释放DC","关闭错误",MB_OK|MB_ICONINFORMATION);

        hDC=NULL;
    }

    if(hWnd&&!DestroyWindow(hWnd))
    {
        MessageBox(NULL,"释放窗口句柄失败","关闭错误",MB_OK|MB_ICONINFORMATION);

        hWnd=NULL;
    }

    if(!UnregisterClass("OpenGL",hInstance))
    {
        MessageBox(NULL,"不能注消窗口类","关闭错误",MB_OK|MB_ICONINFORMATION);

        hInstance=NULL;
    }
}

bool CreateGLWindow(char* title,int width,int height,int bits,bool fullscreenflag)
{
    GLuint PixelFormat;
    WNDCLASS wc;
    DWORD dwExStyle;
    DWORD dwStyle;

    RECT WindowRect;
    WindowRect.left=(long)0;
    WindowRect.right=(long)width;
    WindowRect.top=(long)0;
    WindowRect.bottom=(long)height;

    fullscreen= fullscreenflag;

    hInstance= GetModuleHandle(NULL);

    wc.style= CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
    wc.lpfnWndProc= (WNDPROC) WndProc;           
    wc.cbClsExtra= 0;                   
    wc.cbWndExtra= 0;                       
    wc.hInstance= hInstance;                   
    wc.hIcon= LoadIcon(NULL, IDI_WINLOGO);           
    wc.hCursor= LoadCursor(NULL, IDC_ARROW);           
    wc.hbrBackground= NULL;                   
    wc.lpszMenuName= NULL;                       
    wc.lpszClassName= "OpenGL";    

    if (!RegisterClass(&wc))                   
    {
        MessageBox(NULL,"注册窗口失败","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;                           
    }

    if(fullscreen)
    {
        DEVMODE dmScreenSettings;                   
        memset(&dmScreenSettings,0,sizeof(dmScreenSettings));       
        dmScreenSettings.dmSize= sizeof(dmScreenSettings);           
        dmScreenSettings.dmPelsWidth= width;               
        dmScreenSettings.dmPelsHeight= height;               
        dmScreenSettings.dmBitsPerPel= bits;                   
        dmScreenSettings.dmFields= DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

        if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
        {
            if (MessageBox(NULL,"全屏模式在当前显卡上设置失败!\n使用窗口模式?","OpenGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
            {
                fullscreen=false;
            }
            else
            {
                MessageBox(NULL,"程序将被关闭","错误",MB_OK|MB_ICONSTOP);
                return false;
            }
        }
    }

    if(fullscreen)
    {
        dwExStyle=WS_EX_APPWINDOW;                   
        dwStyle=WS_POPUP;                       
        ShowCursor(false);   
    }
    else
    {
        dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;       
        dwStyle=WS_OVERLAPPEDWINDOW;                   
    }

    AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle);

    if(!(hWnd=CreateWindowEx(dwExStyle,"OpenGL",title,WS_CLIPSIBLINGS|WS_CLIPCHILDREN|dwStyle,0, 0,WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top,NULL,NULL,hInstance,NULL)))
    {
        KillGLWindow();                       
        MessageBox(NULL,"不能创建一个窗口设备描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;
    }

    static PIXELFORMATDESCRIPTOR pfd=    //pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
    {
        sizeof(PIXELFORMATDESCRIPTOR),    //上述格式描述符的大小
        1,                                // 版本号
        PFD_DRAW_TO_WINDOW |            // 格式支持窗口
        PFD_SUPPORT_OPENGL |            // 格式必须支持OpenGL
        PFD_DOUBLEBUFFER,                // 必须支持双缓冲
        PFD_TYPE_RGBA,                    // 申请 RGBA 格式
        bits,                            // 选定色彩深度
        0, 0, 0, 0, 0, 0,                // 忽略的色彩位
        0,                                // 无Alpha缓存
        0,                                // 忽略Shift Bit
        0,                                // 无累加缓存
        0, 0, 0, 0,                        // 忽略聚集位
        16,                                // 16位 Z-缓存 (深度缓存)
        0,                                // 无蒙板缓存
        0,                                // 无辅助缓存
        PFD_MAIN_PLANE,                    // 主绘图层
        0,                                // Reserved
        0, 0, 0                            // 忽略层遮罩
    };

    if (!(hDC=GetDC(hWnd)))                       
    {
        KillGLWindow();                           
        MessageBox(NULL,"不能创建一种相匹配的像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;                           
    }

    if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))           
    {
        KillGLWindow();                           
        MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;                       
    }

    if(!SetPixelFormat(hDC,PixelFormat,&pfd))               
    {
        KillGLWindow();                       
        MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;                           
    }

    if (!(hRC=wglCreateContext(hDC)))                   
    {
        KillGLWindow();                           
        MessageBox(NULL,"不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;                       
    }

    if(!wglMakeCurrent(hDC,hRC))                       
    {
        KillGLWindow();                           
        MessageBox(NULL,"不能激活当前的OpenGL渲然描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;                           
    }

    ShowWindow(hWnd,SW_SHOW);                    // 显示窗口
    SetForegroundWindow(hWnd);                    // 略略提高优先级
    SetFocus(hWnd);                                // 设置键盘的焦点至此窗口
    ReSizeGLScene(width, height);                // 设置透视 GL 屏幕

    if (!InitGL())                           
    {
        KillGLWindow();                           
        MessageBox(NULL,"初始化失败","错误",MB_OK|MB_ICONEXCLAMATION);
        return false;                       
    }

    return true;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT    uMsg,WPARAM    wParam,LPARAM lParam)                   
{
    switch (uMsg)                               
    {
        case WM_ACTIVATE:                        // 监视窗口激活消息
        {
            if (!HIWORD(wParam))                // 检查最小化状态
            {
                active=true;                    // 程序处于激活状态
            }
            else
            {
                active=false;                    // 程序不再激活
            }

            return 0;                            // 返回消息循环
        }

        case WM_SYSCOMMAND:                        // 系统中断命令
        {
            switch (wParam)                        // 检查系统调用
            {
                case SC_SCREENSAVE:                // 屏保要运行
                case SC_MONITORPOWER:  return 0;                       
            }

            break;                                // 退出
        }

        case WM_CLOSE:                            // 收到Close消息
        {
            PostQuitMessage(0);                    // 发出退出消息
            return 0;                            // 返回
        }

        case WM_KEYDOWN:                        // 有键按下么?
        {
            keys[wParam] = true;                // 如果是,设为TRUE
            return 0;                            // 返回
        }

        case WM_KEYUP:                            // 有键放开么?
        {
            keys[wParam] = false;                // 如果是,设为FALSE
            return 0;                            // 返回
        }

        case WM_SIZE:                            // 调整OpenGL窗口大小
        {
            ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));        // LoWord=Width,HiWord=Height
            return 0;                                            // 返回
        }
    }

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

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,    int    nCmdShow)           
{
    MSG    msg;                           
    bool done=false;

    if (MessageBox(NULL,"你想在全屏模式下运行么?", "设置全屏模式",MB_YESNO|MB_ICONQUESTION)==IDNO)
    {
        fullscreen=false;                   
    }

    if (!CreateGLWindow("0810050225",640,480,16,fullscreen))
    {
        return 0;                           
    }

    while(!done)                           
    {
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))            // 有消息在等待吗?
        {
            if (msg.message==WM_QUIT)                        // 收到退出消息?
            {
                done=true;                                    // 是,则done=TRUE
            }
            else                                            // 不是,处理窗口消息
            {
                TranslateMessage(&msg);                        // 翻译消息
                DispatchMessage(&msg);                        // 发送消息
            }
        }
        else                                                // 如果没有消息
        {
            if (active)                        // 程序激活的么?
            {
                if (keys[VK_ESCAPE])        // ESC 按下了么?
                {
                    done=true;                // ESC 发出退出信号
                }
                else                        // 不是退出的时候,刷新屏幕
                {
                    DrawGLScene();            // 绘制场景
                    SwapBuffers(hDC);        // 交换缓存 (双缓存)
                }
            }

            if (keys[VK_F1])                    // F1键按下了么?
            {
                keys[VK_F1]=false;                // 若是,使对应的Key数组中的值为 FALSE
                KillGLWindow();                    // 销毁当前的窗口
                fullscreen=!fullscreen;            // 切换 全屏 / 窗口 模式
                if (!CreateGLWindow("0810050225",640,480,16,fullscreen))
                {
                    return 0;                    // 如果窗口未能创建,程序退出
                }
            }
        }
    }

    KillGLWindow();                                // 销毁窗口
    return (msg.wParam);                        // 退出程序
}
搜索更多相关主题的帖子: 动画 旋转 color 
2011-06-30 11:17
Utopie
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2011-8-15
得分:0 
没啥意思
2011-08-15 21:28
qq1023569223
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:湖南科技大学
等 级:贵宾
威 望:26
帖 子:2753
专家分:13404
注 册:2010-12-22
得分:0 
当初看的时候有点意思!

   唯实惟新 至诚致志
2011-08-18 09:43
fschang
Rank: 1
等 级:新手上路
帖 子:4
专家分:1
注 册:2009-7-6
得分:0 
运行不了
2011-09-21 08:36
BlueGuy
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
得分:0 
还是不建议用win32写opengl程序,一堆没用的垃圾代码,glut挺好的

我就是真命天子,顺我者生,逆我者死!
2018-06-02 10:30



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-344377-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.080517 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved