Lesson 8 Nehe

来源:互联网 发布:恐怖黎明官方数据库 编辑:程序博客网 时间:2024/05/21 07:47
#include <gl/opengl.h>#include <stdio.h>HGLRC hRC = NULL;HDC   hDC = NULL;HWND  hWnd = NULL;HINSTANCE hInstance = NULL;BOOL keys[256];BOOL active = TRUE;BOOL fullscreen = FALSE;BOOL light = TRUE;              // 光源开关BOOL lp = TRUE;                 // L键按下了吗?BOOL fp;                        // F键按下了吗?GLfloat xRote;GLfloat yRote;GLfloat xStep = 0.1f;           // X旋转速度GLfloat yStep = 0.1f;           // Y 旋转速度GLfloat z = -5.0f;              // 深入屏幕的距离BOOL blend;                     // 是否混合BOOL bp;                        // B键是否按下GLfloat LightAmbient[]  = {0.5f, 0.5f, 0.5f, 1.0f};  //环境光参数GLfloat LightDiffuse[]  = {1.0f, 1.0f, 1.0f, 1.0f};  //漫射光参数数GLfloat LightPosition[] = {0.0f, 0.0f, 2.0f, 1.0f};  //光源位置GLuint  filter = 0;                                      // 跟踪采用何种纹理GLuint texture[3];                                   // 存三个纹理LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);AUX_RGBImageRec* LoadBMP(char* FileName){    FILE *File = NULL;    if (!FileName){        MessageBox(NULL, "文件未存在", "错误", MB_OK|MB_ICONEXCLAMATION);        return NULL;    }    File = fopen(FileName, "r");    if (!File){        MessageBox(NULL, "文件未能正常打开", "错误", MB_OK|MB_ICONEXCLAMATION);        return  NULL;    }    fclose(File);    return auxDIBImageLoad(FileName);}BOOL LoadGLTexture(char* Filename, GLuint* texture){    BOOL Status  =  FALSE;    AUX_RGBImageRec *TextureImage[1];    memset(TextureImage, 0, sizeof(void*)*1);    if (TextureImage[0] = LoadBMP(Filename)){        Status = TRUE;        // 创建三个纹理        glGenTextures(3, texture);        ///////////////////////////////////////////////////        glBindTexture(GL_TEXTURE_2D, texture[0]);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        glTexImage2D(GL_TEXTURE_2D,  0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);        ////////////////////////////////////////////////////////        glBindTexture(GL_TEXTURE_2D, texture[1]);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);        glTexImage2D(GL_TEXTURE_2D,  0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);        ////////////////////////////////////////////////////////        glBindTexture(GL_TEXTURE_2D, texture[2]);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);    }    if (TextureImage[0]){        if (TextureImage[0]->data)            free(TextureImage[0]->data);        free(TextureImage[0]);    }    return Status;}GLvoid ReSizeGLScene(GLsizei width, GLsizei height){    // 如果高为0 , 则设置其为1    if (height == 0) height = 1;    // 设置可以看到的视角    glViewport(0,0,width, height);    // 设置投影矩阵    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    // 设置平截头体    gluPerspective(45.0f, (GLdouble)width/(GLdouble)height, 0.1f, 100.0f);    // 设置模型矩阵    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();}GLvoid InitGL(){    if (!LoadGLTexture("Data/Glass.bmp", &texture[0])){        MessageBox(NULL, "载入纹理失败", "错误", MB_OK|MB_ICONEXCLAMATION);        exit(1);    }    // 混合初始化    glColor4f(1.0f, 1.0f, 1.0f, 0.5f);    glBlendFunc(GL_SRC_ALPHA, GL_ONE);    // 开启光照    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫射光    glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); // 光源位置    glEnable(GL_LIGHT1);    //glEnable(GL_LIGHTING);    glEnable(GL_TEXTURE_2D);    glShadeModel(GL_SMOOTH);    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    // 1.0f 为最大深度    glClearDepth(1.0f);    glEnable(GL_DEPTH_TEST);    glDepthFunc(GL_LEQUAL);    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);}GLvoid DrawGLScene(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();                   // 重置坐标系    glTranslatef(0.0f, 0.0f, z);    glRotatef(xRote, 1.0f, 0.0f, 0.0f);    glRotatef(yRote, 0.0f, 1.0f, 0.0f);    glBindTexture(GL_TEXTURE_2D, texture[filter]);    // 画正方体    glBegin(GL_QUADS);    // 前面    glNormal3f(0.0f, 0.0f, 1.0f);    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // A    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // B    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // C    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // D    // 右面    glNormal3f(1.0f, 0.0f, 0.0f);    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // D    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // C    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // E    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // F    //后面    glNormal3f(0.0f, 0.0f,-1.0f);    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // F    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // E    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // G    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // H    //左面    glNormal3f(-1.0f, 0.0f, 0.0f);    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // H    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // G    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // B    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // A    //上面    glNormal3f(0.0f, 1.0f, 0.0f);    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // B    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // G    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // E    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // C     //下面    glNormal3f(0.0f,-1.0f, 0.0f);    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // H    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // A    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // D    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // F    glEnd();    if (xRote>= 360.0f) xRote = 0.0f;    if (yRote>= 360.0f) yRote = 0.0f;    xRote += xStep;    yRote += yStep;}GLvoid KillGLWindow(){    if (fullscreen){        ChangeDisplaySettings(NULL, 0);        ShowCursor(FALSE);    }    if (hRC){        if (!wglMakeCurrent(NULL, NULL))            MessageBox(NULL, "释放DC 或 RC 失败", "错误", MB_OK);        if (!wglDeleteContext(hRC))            MessageBox(NULL, "释放RC失败", "错误", MB_OK);        hRC = NULL;    }    // ReleaseDC 失败返回0, 成功返回非0    if (hDC && !ReleaseDC(hWnd, hDC)){        MessageBox(NULL, "释放DC失败", "错误", MB_OK);        hDC = NULL;    }    if (hWnd && !DestroyWindow(hWnd)){        MessageBox(NULL, "销毁窗口失败", "错误", MB_OK);        hWnd = NULL;    }    if (!UnregisterClass("opengl", hInstance)){        MessageBox(NULL, "反注册失败", "错误", MB_OK);        hInstance = NULL;    }}bool CreateGLWindow(char* title, int width, int height, int bits, HINSTANCE hInstance, bool fullscreenflag){    GLuint PixelFormat;    WNDCLASS wc;    DWORD dwStyle;    DWORD dwExStyle;    RECT WindowRect;    WindowRect.left = (long)0;    WindowRect.right= (long)width;    WindowRect.top  =  (long)0;    WindowRect.bottom = (long)height;    fullscreen = fullscreenflag;    wc.hInstance = hInstance;    wc.cbClsExtra  = 0;    wc.cbWndExtra  = 0;    wc.style       = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;    wc.lpfnWndProc = WindowProc;    wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);    wc.hCursor = LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground = NULL;    wc.lpszClassName = "opengl";    wc.lpszMenuName = NULL;    // 注册窗口类    if (!RegisterClass(&wc)){        MessageBox(NULL, "窗口注册失败", "错误", MB_OK);        return FALSE;    }    if (fullscreen){        DEVMODE dmScreenSetting;        memset(&dmScreenSetting, 0, sizeof(dmScreenSetting));        dmScreenSetting.dmSize = sizeof(dmScreenSetting);        dmScreenSetting.dmBitsPerPel = bits;        dmScreenSetting.dmPelsHeight = height;        dmScreenSetting.dmPelsWidth = width;        dmScreenSetting.dmFields = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH;        // 设置显示模式        if  (ChangeDisplaySettings(&dmScreenSetting, CDS_FULLSCREEN)!= DISP_CHANGE_SUCCESSFUL){            if (MessageBox(NULL, "当前显卡不支持全屏操做\n使用窗口模式?", "错误", MB_YESNO|MB_ICONEXCLAMATION) == IDYES){                fullscreen = FALSE;            }            else{                MessageBox(NULL, "程序将会被关闭", "错误", MB_OK|MB_ICONEXCLAMATION);                return false;            }        }    }    if (fullscreen){        dwExStyle = WS_EX_APPWINDOW;        dwStyle = WS_POPUP;        ShowCursor(FALSE);    }    else{        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;        dwStyle = WS_OVERLAPPEDWINDOW;        //ShowCursor(TRUE);    }    dwStyle = dwStyle | WS_CLIPCHILDREN|WS_CLIPSIBLINGS;    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);    if (!(hWnd = CreateWindowEx(dwExStyle, "opengl", title, dwStyle, 0,0, WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect.top, NULL, NULL, hInstance, NULL))){        KillGLWindow();        MessageBox(NULL, "不能创建一个窗口设备描述表", "错误", MB_OK);        return false;    }    static PIXELFORMATDESCRIPTOR pfd = {        sizeof(PIXELFORMATDESCRIPTOR),        1,        PFD_DRAW_TO_WINDOW|        PFD_SUPPORT_OPENGL|        PFD_DOUBLEBUFFER,        PFD_TYPE_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);        return false;    }    ShowWindow(hWnd, SW_SHOW);    // 激活窗口    SetForegroundWindow(hWnd);    // 接收键盘信息    SetFocus(hWnd);    ReSizeGLScene(width, height);    InitGL();    return true;}LRESULT CALLBACK WindowProc( 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_CLOSE:        {            PostQuitMessage(0);            return 0;        }    case WM_KEYUP:        {            keys[wParam] = FALSE;            return 0;        }    case WM_KEYDOWN:        {            keys[wParam] = TRUE;            return 0;        }    case WM_SIZE:        {            ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));            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_ICONEXCLAMATION) == IDYES)        fullscreen = TRUE;    if (!CreateGLWindow("Lesson 7", 640, 480, 16, hInstance, fullscreen))        return 0;    while (!done){        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){            if (msg.message == WM_QUIT)                done = TRUE;            else{                TranslateMessage(&msg);                DispatchMessage(&msg);            }        }        else        {            if (active)            {                if (keys[VK_ESCAPE])                    done = TRUE;                else{                    DrawGLScene();                    SwapBuffers(hDC);                }                // 判断L 键按下, 并进行功能                if (keys['L'] && !lp){                    lp = TRUE;                    if (light)                        glEnable(GL_LIGHTING);                    else                        glDisable(GL_LIGHTING);                    light = !light;                }                if (!keys['L']){                    lp = FALSE;                }                // 判断F键,并进行功能                 if (keys['F'] && fp){                    fp = TRUE;                    filter++;                    if (filter >2) filter = 0;                }                if (keys['F']){                    fp = FALSE;                }                // PageUp                if (keys[VK_PRIOR]){                    z -= 0.05f;                }                // Page Down                if (keys[VK_NEXT]){                    z += 0.05F;                }                // 上 下 左 右 四个键                if (keys[VK_UP]){                    xStep += 0.01f;                }                if (keys[VK_DOWN])                    xStep -= 0.01f;                if (keys[VK_LEFT])                    yStep += 0.01f;                if (keys[VK_RIGHT])                    yStep -= 0.01f;                // 判断B键是否被搂下                if (keys['B'] && !bp){                    bp = TRUE;                    if (blend){                        glEnable(GL_BLEND);                        glDisable(GL_DEPTH_TEST);                    }                    else{                        glEnable(GL_DEPTH_TEST);                        glDisable(GL_BLEND);                    }                    blend = !blend;                }                if (!keys['B']){                    bp = FALSE;                }                // 判断F1                if (keys[VK_F1]){                    keys[VK_F1] = FALSE;                    KillGLWindow();                    fullscreen = !fullscreen;                    if (!CreateGLWindow("Lesson 7", 640, 480, 16, hInstance, fullscreen))                        return 0;                }            }        }    }    KillGLWindow();    return (msg.wParam);}

这里写图片描述
这里写图片描述

0 0
原创粉丝点击