outdated: 42.Multiple Viewports

一个屏幕分为四个小窗口,如下图。

UpdateTex()为绘制函数,

void UpdateTex(int dmx, int dmy)            // Update pixel dmx, dmy on the texture
{
    tex_data[0 + ((dmx + (width * dmy)) * 3)] = 255;      // Set red pixel to full bright
    tex_data[1 + ((dmx + (width * dmy)) * 3)] = 255;      // Green
    tex_data[2 + ((dmx + (width * dmy)) * 3)] = 255;      // Blue
}

在绘制完所有迷宫时,会设置标题题目“SetWindowText()函数”且重置贴图数据“ZeroMemory()函数”,最后重新绘制。

在Initialize()函数中,对quadric贴图时,需要先对quadric贴图坐标设置。

gluQuadricTexture(quadric, GL_TRUE);

每次的Update都会检查迷宫是否绘制完成,

done = TRUE;
for
(int x = 0; x < width; x+=2) { for (int y = 0; y < height; y+=2) { if (tex_data[((x + (width * y)) * 3)] == 0) done = FALSE; // Check } }
if (done) {
  ...
}

在确定下一步绘制哪里时,先得判断是否是在边缘和现在位置的上下左右是否绘制过。如下,

if (((mx > (width - 4) || tex_data[(((mx + 2) + (width*my)) * 3)] == 255)) &&
    ((mx < 2 || tex_data[(((mx - 2) + (width*my)) * 3)] == 255)) &&
    ((my >(height - 4) || tex_data[((mx + (width*(my + 2))) * 3)] == 255)) &&
    ((my < 2 || tex_data[((mx + (width*(my - 2))) * 3)] == 255)))
{
    do {
        mx = int(rand() % (width / 2)) * 2;
        my = int(rand() % (width / 2)) * 2;
    } while (tex_data[((mx + (width*my)) * 3)] == 0);
}

接下来再随机选方向,来绘制,

dir = int(rand() % 4);           // Pick a random direction
if ((dir == 0) && (mx <= (width - 4))) {
    if (tex_data[(((mx + 2) + (width * my)) * 3)] == 0) {
        UpdateTex(mx + 1, my);  // Update the texture to show path cut out between rooms
        mx += 2;                // Move to the right
    }
}
if ((dir == 1) && (my <= (width - 4))) {
    if (tex_data[((mx + (width * (my + 2))) * 3)] == 0) {
        UpdateTex(mx, my + 1);
        my += 2;
    }
}
if ((dir == 2) && (mx >= 2)) {
    if (tex_data[(((mx - 2) + (width * my)) * 3)] == 0) {
        UpdateTex(mx - 1, my);
        mx -= 2;
    }
}
if ((dir == 3) && (my >= 2)) {
    if (tex_data[((mx + (width * (my - 2))) * 3)] == 0) {
        UpdateTex(mx, my - 1);
        my -= 2;
    }
}

UpdateTex(mx, my);

在Draw()函数中,GetClientRect()函数可以获取窗口的尺寸。glViewport()函数用来分割窗口。glTexSubImage2D()函数用来更新贴图。下面为代码,

#ifndef GL_FRAMEWORK_INCLUDED
#define GL_FRAMEWORK_INCLUDED

#include <windows.h>

typedef struct {                                   // Structure for keyboard stuff
    BOOL keyDown[256];
} Keys;

typedef struct {                                   // Contains information vital to applications 
    HMODULE hInstance;                             // Application Instance
    const char* className;
} Application;

typedef struct {                                   // Window creation info
    Application* application;
    char* title;
    int width;
    int height;
    int bitsPerPixel;
    BOOL isFullScreen;
} GL_WindowInit;

typedef struct {                                   // Contains information vital to a window
    Keys* keys;
    HWND hWnd;                                     // Windows handle
    HDC hDC;                                       // Device context
    HGLRC hRC;                                     // Rendering context
    GL_WindowInit init;
    BOOL isVisible;                                // Window visiable?
    DWORD lastTickCount;                           // Tick counter
} GL_Window;

void TerminateApplication(GL_Window* window);      // Terminate the application

void ToggleFullscreen(GL_Window* window);          // Toggle fullscreen / Windowed mode

BOOL Initialize(GL_Window* window, Keys* keys);

void Deinitialize(void);

void Update(DWORD milliseconds);

void Draw(void);

#endif
Previous.h
#include <Windows.h>
#include <GL\glew.h>
#include <GL\glut.h>
#include "Previous.h"

#define WM_TOGGLEFULLSCREEN (WM_USER+1)                   // Application define message for toggling 
// between fulscreen / windowed mode
static BOOL g_isProgramLooping;                           // Window creation loop, for fullscreen / windowed mode
static BOOL g_createFullScreen;                           // If true, then create window

void TerminateApplication(GL_Window* window)              // Terminate the application
{
    PostMessage(window->hWnd, WM_QUIT, 0, 0);             // Send a WM_QUIT message
    g_isProgramLooping = FALSE;                           // Stop looping of the program
}

void ToggleFullscreen(GL_Window* window)                  // Toggle fullscreen /windowed mode
{
    PostMessage(window->hWnd, WM_TOGGLEFULLSCREEN, 0, 0); // Send a WM_TOGGLEFULLSCREEN message
}
/******************************************************************************************************************************************/
/******************************************************************************************************************************************/
void ReshapeGL(int width, int height)                     // Reshape the window  when it's moved or resized
{
    glViewport(0, 0, (GLsizei)(width), (GLsizei)(height)); // Reset the current viewport
    //glMatrixMode(GL_PROJECTION);
    //glLoadIdentity();
    //// Calcutate the aspect ratio of the window
    //gluPerspective(45.0f, (GLfloat)(width) / (GLfloat)(height), 1.0, 100.0f);
    //glMatrixMode(GL_MODELVIEW);
    //glLoadIdentity();
}
/******************************************************************************************************************************************/
/******************************************************************************************************************************************/
BOOL ChangeScreenResolution(int width, int height, int bitsPerPixel)     // Change the screen resolution
{
    DEVMODE dmScreenSettings;                              // Device mode
    ZeroMemory(&dmScreenSettings, sizeof(DEVMODE));        // Make sure memory is cleared
    dmScreenSettings.dmSize = sizeof(DEVMODE);             // Size of the devmode structure
    dmScreenSettings.dmPelsWidth = width;
    dmScreenSettings.dmPelsHeight = height;
    dmScreenSettings.dmBitsPerPel = bitsPerPixel;
    dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
    if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
        return FALSE;                                      // Display change failed
    }
    return TRUE;
}

BOOL CreateWindowGL(GL_Window* window)
{
    DWORD windowStyle = WS_OVERLAPPEDWINDOW;                // Define window style
    DWORD windowExtendedStyle = WS_EX_APPWINDOW;            // Define the window's extended style

    PIXELFORMATDESCRIPTOR pdf = {
        sizeof(PIXELFORMATDESCRIPTOR),                      // Size of this pixel format descriptor
        1,                                                  // Version Number
        PFD_DRAW_TO_WINDOW |                                // Format must support window
        PFD_SUPPORT_OPENGL |                                // Format must support openGL
        PFD_DOUBLEBUFFER,                                   // Must support double buffering
        PFD_TYPE_RGBA,                                      // Request an RGBA format
        window->init.bitsPerPixel,                          // Select color depth
        0, 0, 0, 0, 0, 0,                                   // Color bits ignored
        0,                                                  // No alpha buffer
        0,                                                  // Shift bit ignored
        0,                                                  // No accumulation buffer
        0, 0, 0, 0,                                         // Accumulation bits ignored
        16,                                                 // 16bits Z-buffer (depth buffer)
        0,                                                  // No stencil buffer
        0,                                                  // No auxiliary buffer
        PFD_MAIN_PLANE,                                     // Main drawing layer
        0,                                                  // Reserved
        0, 0, 0                                             // Layer masks ignored
    };
    RECT windowRect = { 0, 0, window->init.width, window->init.height };   // Window coordiantes

    GLuint PixelFormat;

    if (window->init.isFullScreen == TRUE) {
        if (ChangeScreenResolution(window->init.width, window->init.height, window->init.bitsPerPixel) == FALSE)
        {
            // Fullscreen mode failed, run in windowed mode instead
            MessageBox(HWND_DESKTOP, "Mode Switch Failed.\nRuning In Windowed Mode.",
                "Error", MB_OK | MB_ICONEXCLAMATION);
            window->init.isFullScreen = FALSE;
        }
        else {
            ShowCursor(FALSE);
            windowStyle = WS_POPUP;                         // Popup window
            windowExtendedStyle |= WS_EX_TOPMOST;
        }
    }
    else {
        // Adjust window, account for window borders
        AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle);
    }
    // Create Opengl window
    window->hWnd = CreateWindowEx(windowExtendedStyle,      // Extended style
        window->init.application->className,                // Class name
        window->init.title,                                 // Window title
        windowStyle,                                        // Window style
        0, 0,                                               // Window X,Y position
        windowRect.right - windowRect.left,                 // Window width
        windowRect.bottom - windowRect.top,                 // Window height
        HWND_DESKTOP,                                       // Desktop is window's parent
        0,                                                  // No menu
        window->init.application->hInstance,                // Pass the window instance
        window);

    if (window->hWnd == 0) {                                // Was window creation a success?
        return FALSE;
    }
    window->hDC = GetDC(window->hWnd);
    if (window->hDC == 0) {
        DestroyWindow(window->hWnd);
        window->hWnd = 0;
        return FALSE;
    }
    PixelFormat = ChoosePixelFormat(window->hDC, &pdf);     // Find a compatible pixel format
    if (PixelFormat == 0) {
        ReleaseDC(window->hWnd, window->hDC);               // Release device context
        window->hDC = 0;
        DestroyWindow(window->hWnd);
        window->hWnd = 0;
        return FALSE;
    }
    if (SetPixelFormat(window->hDC, PixelFormat, &pdf) == FALSE) {   // Try to set the pixel format
        ReleaseDC(window->hWnd, window->hDC);
        window->hDC = 0;
        DestroyWindow(window->hWnd);
        window->hWnd = 0;
        return FALSE;
    }
    window->hRC = wglCreateContext(window->hDC);            // Try to get a rendering context
    if (window->hRC == 0) {
        ReleaseDC(window->hWnd, window->hDC);
        window->hDC = 0;
        DestroyWindow(window->hWnd);
        window->hWnd = 0;
        return FALSE;
    }
    // Make the rendering context our current rendering context
    if (wglMakeCurrent(window->hDC, window->hRC) == FALSE) {
        wglDeleteContext(window->hRC);                      //  Delete the rendering context
        window->hRC = 0;
        ReleaseDC(window->hWnd, window->hDC);
        window->hDC = 0;
        DestroyWindow(window->hWnd);
        window->hWnd = 0;
        return FALSE;
    }
    ShowWindow(window->hWnd, SW_NORMAL);                    // Make the window visiable
    window->isVisible = TRUE;
    ReshapeGL(window->init.width, window->init.height);     // Reshape our GL window
    ZeroMemory(window->keys, sizeof(Keys));                 // Clear all keys
    window->lastTickCount = GetTickCount();
    return TRUE;
}

BOOL DestroyWindowGL(GL_Window* window)
{
    if (window->hWnd != 0) {
        if (window->hDC != 0) {
            wglMakeCurrent(window->hDC, 0);                 // Setting current active rendering context to zero
            if (window->hRC != 0) {
                wglDeleteContext(window->hRC);
                window->hRC = 0;
            }
            ReleaseDC(window->hWnd, window->hDC);
            window->hDC = 0;
        }
        DestroyWindow(window->hWnd);
        window->hWnd = 0;
    }
    if (window->init.isFullScreen) {
        ChangeDisplaySettings(NULL, 0);                     // Switch back to desktop resolution
        ShowCursor(TRUE);
    }
    return TRUE;
}
/******************************************************************************************************************************************/
/******************************************************************************************************************************************/
// Process window message callback
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    DWORD tickCount;             // Holds current tick count
    __int64 timer;               // Used for the tick count
/******************************************************************************************************************************************/
/******************************************************************************************************************************************/
    // Get the window context
    GL_Window* window = (GL_Window*)(GetWindowLong(hWnd, GWL_USERDATA));
    switch (uMsg) {                                         // Evaluate window message
    case WM_PAINT:
    {
        tickCount = GetTickCount();
        Update(tickCount - window->lastTickCount);
        window->lastTickCount = tickCount;
        Draw();
        SwapBuffers(window->hDC);
    }
    return 0;

    case WM_SYSCOMMAND:                                     // Intercept system commands
    {
        switch (wParam) {                                   // Check system calls
        case SC_SCREENSAVE:                                 // Screensaver trying to start?
        case SC_MONITORPOWER:                               // Mointer trying to enter powersave?
            return 0;                                           // Prevent form happening
        }
        break;
    }
    return 0;
    case WM_CREATE:
    {
        CREATESTRUCT* creation = (CREATESTRUCT*)(lParam);   // Store window structure pointer
        window = (GL_Window*)(creation->lpCreateParams);
        SetWindowLong(hWnd, GWL_USERDATA, (LONG)(window));
    }
    return 0;

    case WM_CLOSE:
        TerminateApplication(window);
        return 0;

    case WM_SIZE:
        switch (wParam) {
        case SIZE_MINIMIZED:                                 // Was window minimized?
            window->isVisible = FALSE;
            return 0;
        case SIZE_MAXIMIZED:
            window->isVisible = TRUE;
            ReshapeGL(LOWORD(lParam), HIWORD(lParam));
            return 0;
        case SIZE_RESTORED:
            window->isVisible = TRUE;
            ReshapeGL(LOWORD(lParam), HIWORD(lParam));
            return 0;
        }
        break;

    case WM_KEYDOWN:
        if ((wParam >= 0) && (wParam <= 255)) {
            window->keys->keyDown[wParam] = TRUE;            // Set the selected key(wParam) to true
            return 0;
        }
        break;

    case WM_KEYUP:
        if ((wParam >= 0) && (wParam <= 255)) {
            window->keys->keyDown[wParam] = FALSE;
            return 0;
        }
        break;

    case WM_TOGGLEFULLSCREEN:
        g_createFullScreen = (g_createFullScreen == TRUE) ? FALSE : TRUE;
        PostMessage(hWnd, WM_QUIT, 0, 0);
        break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);        // Pass unhandle message to DefWindowProc
}

BOOL RegisterWindowClass(Application* application)
{
    WNDCLASSEX windowClass;
    ZeroMemory(&windowClass, sizeof(WNDCLASSEX));            // Make sure memory is cleared
    windowClass.cbSize = sizeof(WNDCLASSEX);                 // Size of the windowClass structure
    windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  // Redraws the window for any movement / resizing
    windowClass.lpfnWndProc = (WNDPROC)(WindowProc);         // WindowProc handles message
    windowClass.hInstance = application->hInstance;          // Set the instance
    windowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);// Class background brush color
    windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);       // Load the arrow pointer
    windowClass.lpszClassName = application->className;      // Sets the application className
    if (RegisterClassEx(&windowClass) == 0) {
        MessageBox(HWND_DESKTOP, "RegisterClassEx Failed!", "Error", MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
    }
    return TRUE;
}

int WINAPI WinMain(HINSTANCE hIstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    Application application;
    GL_Window window;
    Keys keys;
    BOOL isMessagePumpActive;
    MSG msg;
/******************************************************************************************************************************************/
/******************************************************************************************************************************************/
    application.className = "OpenGL";
    application.hInstance = hIstance;

    ZeroMemory(&window, sizeof(GL_Window));
    window.keys = &keys;                                     // Window key structure
    window.init.application = &application;                  // Window application
    window.init.title = "Multiple Viewports...Building Maze!";    // Window title
    window.init.width = 1024;                                // Window width
    window.init.height = 768;                                // Window height
    window.init.bitsPerPixel = 32;                           // Bits per pixel
    window.init.isFullScreen = TRUE;                         // Fullscreen? (set to TRUE)
/******************************************************************************************************************************************/
/******************************************************************************************************************************************/
    ZeroMemory(&keys, sizeof(Keys));
    if (MessageBox(HWND_DESKTOP, "Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",
        MB_YESNO | MB_ICONQUESTION) == IDNO)
    {
        window.init.isFullScreen = FALSE;
    }
    if (RegisterWindowClass(&application) == FALSE)
    {
        MessageBox(HWND_DESKTOP, "Error Registering Window Class!", "Error", MB_OK | MB_ICONEXCLAMATION);
        return -1;
    }
    g_isProgramLooping = TRUE;
    g_createFullScreen = window.init.isFullScreen;
    while (g_isProgramLooping) {                             // Loop until WM_QUIT is received
        window.init.isFullScreen = g_createFullScreen;       // Set init param of window creation to fullscreen?
        if (CreateWindowGL(&window) == TRUE) {               // Was window creation successful?
                                                             // At this point we should have a window that is setup to render OpenGL
            if (Initialize(&window, &keys) == FALSE) {
                TerminateApplication(&window);               // Close window, this will handle the shutdown
            }
            else {
                isMessagePumpActive = TRUE;
                while (isMessagePumpActive == TRUE) {
                    // Success creating window. Check for window messages
                    if (PeekMessage(&msg, window.hWnd, 0, 0, PM_REMOVE) != 0) {
                        if (msg.message != WM_QUIT) {
                            DispatchMessage(&msg);
                        }
                        else {
                            isMessagePumpActive = FALSE;     // Terminate the message pump
                        }
                    }
                    else {
                        if (window.isVisible == FALSE) {
                            WaitMessage();                   // Application is minimized wait for a message
                        }
                        //else {
                        //    // Process application loop
                        //    tickCount = GetTickCount();      // Get the tick count
                        //    Update(tickCount - window.lastTickCount); // Update the counter
                        //    window.lastTickCount = tickCount;// Set last count to current count
                        //    Draw();                          // Draw screen
                        //    SwapBuffers(window.hDC);
                        //}
                    }
                }
            }
            // Application is finished
            Deinitialize();
            DestroyWindowGL(&window);
        }
        else {
            MessageBox(HWND_DESKTOP, "Error Creating OpenGL Window", "Error", MB_OK | MB_ICONEXCLAMATION);
            g_isProgramLooping = FALSE;
        }
    }
    UnregisterClass(application.className, application.hInstance);    // UnRegister window class
    return 0;
}
Previous.cpp
#include <Windows.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/GLUAX.H>
#include <math.h>
#include <stdio.h>
#include "Previous.h"

#pragma comment(lib, "legacy_stdio_definitions.lib")

#ifndef CDS_FULLSCREEN
#define CDS_FULLSCREEN 4
#endif

GL_Window* g_window;
Keys* g_keys;

int mx, my;             // Used for loops
const int width = 128;       // Maze
const int height = 128;

BOOL done;              // Flag to let us know when it's done
BOOL sp;                // Spacebar pressed?

BYTE r[4], g[4], b[4];   // Random color
BYTE* tex_data;

GLfloat xrot, yrot, zrot;    // Rotation
GLUquadricObj* quadric;      // The quadric object

void UpdateTex(int dmx, int dmy)            // Update pixel dmx, dmy on the texture
{
    tex_data[0 + ((dmx + (width * dmy)) * 3)] = 255;      // Set red pixel to full bright
    tex_data[1 + ((dmx + (width * dmy)) * 3)] = 255;      // Green
    tex_data[2 + ((dmx + (width * dmy)) * 3)] = 255;      // Blue
}

void Reset(void)                        // Reset the maze,colors,start point,etc
{
    ZeroMemory(tex_data, width * height * 3);
    srand(GetTickCount());

    for (int loop = 0; loop < 4; ++loop) {         // Color
        r[loop] = rand() % 128 + 128;
        g[loop] = rand() % 128 + 128;
        b[loop] = rand() % 128 + 128;
    }

    mx = int(rand() % (width / 2)) * 2;                // Position
    my = int(rand() % (height / 2)) * 2;
}

BOOL Initialize(GL_Window* window, Keys* keys)
{
    tex_data = new BYTE[width * height * 3];
    g_window = window;
    g_keys = keys;

    Reset();
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_data);

    glEnable(GL_TEXTURE_2D);
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);                // Enable color material
    
    quadric = gluNewQuadric();                  // Create a pointer to the quadric bject
    gluQuadricNormals(quadric, GLU_SMOOTH);     // Create smooth normal
    gluQuadricTexture(quadric, GL_TRUE);        // Create texture coords
    glEnable(GL_LIGHT0);

    return TRUE;
}

void Deinitialize(void)
{
    delete[] tex_data;
}

void Update(DWORD milliseconds)
{
    if (g_keys->keyDown[VK_ESCAPE] == TRUE)
        TerminateApplication(g_window);
    if (g_keys->keyDown[VK_F1] == TRUE)
        ToggleFullscreen(g_window);
    if (g_keys->keyDown[' '] && sp) {
        sp = TRUE;
        Reset();
    }
    if (!g_keys->keyDown[' '])
        sp = FALSE;

    int dir;          // Direction

    xrot += (float)(milliseconds)* 0.02f;
    yrot += (float)(milliseconds)* 0.03f;
    zrot += (float)(milliseconds)* 0.015f;

    done = TRUE;
    for (int x = 0; x < width; x+=2) {
        for (int y = 0; y < height; y+=2) {
            if (tex_data[((x + (width * y)) * 3)] == 0)
                done = FALSE;                        // Check
        }
    }
    // Title
    if (done) {
        // Display a message at the top of the window, pause for a bit and then start building a new maze
        SetWindowText(g_window->hWnd, "Multiple Viewports...Maze Complete!");
        Sleep(5000);
        SetWindowText(g_window->hWnd, "Multiple Viewports...Building Maze!");
        Reset();
    }

    if (((mx > (width - 4) || tex_data[(((mx + 2) + (width*my)) * 3)] == 255)) &&
        ((mx < 2 || tex_data[(((mx - 2) + (width*my)) * 3)] == 255)) &&
        ((my >(height - 4) || tex_data[((mx + (width*(my + 2))) * 3)] == 255)) &&
        ((my < 2 || tex_data[((mx + (width*(my - 2))) * 3)] == 255)))
    {
        do {
            mx = int(rand() % (width / 2)) * 2;
            my = int(rand() % (width / 2)) * 2;
        } while (tex_data[((mx + (width*my)) * 3)] == 0);
    }

    dir = int(rand() % 4);           // Pick a random direction
    if ((dir == 0) && (mx <= (width - 4))) {
        if (tex_data[(((mx + 2) + (width * my)) * 3)] == 0) {
            UpdateTex(mx + 1, my);  // Update the texture to show path cut out between rooms
            mx += 2;                // Move to the right
        }
    }
    if ((dir == 1) && (my <= (width - 4))) {
        if (tex_data[((mx + (width * (my + 2))) * 3)] == 0) {
            UpdateTex(mx, my + 1);
            my += 2;
        }
    }
    if ((dir == 2) && (mx >= 2)) {
        if (tex_data[(((mx - 2) + (width * my)) * 3)] == 0) {
            UpdateTex(mx - 1, my);
            mx -= 2;
        }
    }
    if ((dir == 3) && (my >= 2)) {
        if (tex_data[((mx + (width * (my - 2))) * 3)] == 0) {
            UpdateTex(mx, my - 1);
            my -= 2;
        }
    }

    UpdateTex(mx, my);
}

void Draw(void)
{
    RECT rect;
    GetClientRect(g_window->hWnd, &rect);            // Get window dimensions
    int window_width = rect.right - rect.left;
    int window_height = rect.bottom - rect.top;

    // Update texture
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, tex_data);

    glClear(GL_COLOR_BUFFER_BIT);
    
    for (int loop = 0; loop < 4; ++loop) {
        glColor3ub(r[loop], g[loop], b[loop]);            // Assign color to current view

        if (loop == 0) {
            glViewport(0, window_height / 2, window_width / 2, window_height / 2);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluOrtho2D(0, window_width / 2, window_height / 2, 0);
        }
        if (loop == 1) {
            glViewport(window_width / 2, window_height / 2, window_width / 2, window_height / 2);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluPerspective(45.0f, (GLfloat)(width) / (GLfloat)(height), 0.1f, 500.0f);
        }
        if (loop == 2) {
            glViewport(window_width / 2, 0, window_width / 2, window_height / 2);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluPerspective(45.0f, (GLfloat)(width) / (GLfloat)(height), 0.1f, 500.0f);
        }
        if (loop == 3) {
            glViewport(0, 0, window_width / 2, window_height / 2);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluPerspective(45.0f, (GLfloat)(width) / (GLfloat)(height), 0.1f, 500.0f);
        }

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glClear(GL_DEPTH_BUFFER_BIT);

        if (loop == 0) {
            glBegin(GL_QUADS);
                glTexCoord2f(1.0f, 0.0f); glVertex2f(window_width / 2, 0);
                glTexCoord2f(0.0f, 0.0f); glVertex2f(0, 0);
                glTexCoord2f(0.0f, 1.0f); glVertex2f(0, window_width / 2);
                glTexCoord2f(1.0f, 1.0f); glVertex2f(window_width / 2, window_width / 2);
            glEnd();
        }
        if (loop == 1) {
            glTranslatef(0.0f, 0.0f, -14.0f);
            glRotatef(xrot, 1.0f, 0.0f, 0.0f);
            glRotatef(yrot, 0.0f, 1.0f, 0.0f);
            glRotatef(zrot, 0.0f, 0.0f, 1.0f);

            glEnable(GL_LIGHTING);
            gluSphere(quadric, 4.0f, 32, 32);
            glDisable(GL_LIGHTING);
        }
        if (loop == 2) {
            glTranslatef(0.0f, 0.0f, -2.0f);
            glRotatef(-45.0f, 1.0f, 0.0f, 0.0f);
            glRotatef(zrot / 1.5f, 0.0f, 0.0f, 1.0f);
            glBegin(GL_QUADS);
                glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f);
                glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
                glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
                glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f);
            glEnd();
        }
        if (loop == 3) {
            glTranslatef(0.0f, 0.0f, -7.0f);
            glRotatef(-xrot / 2, 1.0f, 0.0f, 0.0f);
            glRotatef(-yrot / 2, 0.0f, 1.0f, 0.0f);
            glRotatef(-zrot / 2, 0.0f, 0.0f, 1.0f);
            glEnable(GL_LIGHTING);
            glTranslatef(0.0f, 0.0f, -2.0f);
            gluCylinder(quadric, 1.5f, 1.5f, 4.0f, 32, 16);
            glDisable(GL_LIGHTING);
        }
    }
    glFlush();
}
Main.cpp

Thanks for Nehe's tutorials, this is his home.

posted @ 2016-10-11 18:10  clairvoyant  阅读(178)  评论(0编辑  收藏  举报