GLProgramming.com

home :: about :: development guides :: irc :: forums :: search :: paste :: links :: contribute :: code dump

-> Click here to learn how to get live help <-


New Paste :: Recent Pastes:: No Line Numbers


A Paste by Keelhaul
1
 
#include <iostream>
#include <windows.h>
#include <ctype.h>
#include <math.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>

// Global variables
static float  standx = 0.5, standz = 0.0;
static float  turnx = 0.5, turnz = 90.0;
static float  angle = 0.0;
static int    mousex_old = 0;

/* ==================================================================
 * Function: 'walk'
 * Description: Moves the camera across the floor in the given
 *              direction.
 * ================================================================== */
void walk(char direction)
{
    float swapx = turnx - standx;
    float swapz = turnz - standz;
    
    if(direction == 'f')
    {
        if(standx + swapx / 300 <= 26 && standx + swapx / 300 >= -25)
        {
            standx += swapx / 300;
            turnx += swapx / 300;
        }
    
        if(standz + swapz / 300 <= 25 && standz + swapz / 300 >= -25)
        {
            standz += swapz / 300;
            turnz += swapz / 300;
        }
    }
    else if(direction == 'b')
    {
        if (standx - swapx / 300 <= 26 && standx - swapx / 300 >= -25)
        {
            standx -= swapx / 300;
            turnx -= swapx / 300;
        }

        if (standz - swapz / 300 <= 25 && standz - swapz / 300 >= -25)
        {
            standz -= swapz / 300;
            turnz -= swapz / 300;
        }
    }
}

/* ==================================================================
 * Function: 'turn'
 * Description: Turns the camera in the given direction.
 * ================================================================== */
void turn(char direction)
{   
    if(direction == 'l') angle -= M_PI / 40;
    else angle += M_PI / 40;
    
    turnx = (-sin(angle)) * 90;
    turnz = cos(angle) * 90;
}

/* ==================================================================
 * Function: 'drawFloor'
 * Description: Draws the scene floor, chessboard pattern.
 * ================================================================== */
void drawFloor()
{
    bool tilecolor = false;
    
    for(int z=26; z>-26; z--)
    {
        for(int x=-26; x<27; x++)
        {
            glBegin(GL_QUADS);

            if(tilecolor)
            {
                glColor3f(0.5, 0.0, 0.0);
                tilecolor = false;
            }
            else
            {
                glColor3f(0.0, 0.0, 0.5);
                tilecolor = true;
            }
            glVertex3f(x, 0, z);
            glVertex3f(x, 0, z-1);
            glVertex3f(x+1, 0,z-1);
            glVertex3f(x+1, 0, z);

            glEnd();
        }
    }
}

/* ==================================================================
 * Function: 'drawPyramid'
 * Description: Draws a four sided pyramid object of a given height
 *              and width at a given coordinate in the scene.
 * ================================================================== */
void drawPyramid(float x, float z, float height, float width)
{
    glBegin(GL_TRIANGLES);

    glColor3f(0.5, 0.2, 0.0);      
    glVertex3f((2 * x + width) / 2, height, (2 * z + width) / 2);
    glVertex3f(x, 0, z + width);
    glVertex3f(x, 0, z);
    
    glColor3f(0.8, 0.5, 0.0);
    glVertex3f((2 * x + width) / 2, height, (2 * z + width) / 2);
    glVertex3f(x + width, 0, z + width);
    glVertex3f(x, 0, z + width);
    
    glColor3f(0.5, 0.2, 0.0);
    glVertex3f((2 * x + width) / 2, height, (2 * z + width) / 2);
    glVertex3f(x + width, 0, z);
    glVertex3f(x + width, 0, z + width);
    
    glColor3f(0.8, 0.5, 0.0);
    glVertex3f((2 * x + width) / 2, height, (2 * z + width) / 2);
    glVertex3f(x, 0, z);
    glVertex3f(x + width, 0, z);
    
    glEnd();
}

/* ==================================================================
 * Function: 'drawPrism'
 * Description: Draws a rectangular prism object of a given height
 *              and width at a given coordinate in the scene.
 * ================================================================== */
void drawPrism(float x, float z, float height, float width)
{
    glBegin(GL_QUADS);

    glColor3f(0.5, 0.0, 0.5);      
    glVertex3f(x, 0, z);
    glVertex3f(x, 0, z + width);
    glVertex3f(x, height, z + width);
    glVertex3f(x, height, z);
    
    glColor3f(0.2, 0.2, 0.5);      
    glVertex3f(x, 0, z + width);
    glVertex3f(x + width, 0, z + width);
    glVertex3f(x + width, height, z + width);
    glVertex3f(x, height, z + width);
    
    glColor3f(0.5, 0.0, 0.5);      
    glVertex3f(x + width, 0, z + width);
    glVertex3f(x + width, 0, z);
    glVertex3f(x + width, height, z);
    glVertex3f(x + width, height, z + width);
    
    glColor3f(0.2, 0.2, 0.5);      
    glVertex3f(x + width, 0, z);
    glVertex3f(x, 0, z);
    glVertex3f(x, height, z);
    glVertex3f(x + width, height, z);
    
    glColor3f(0.5, 0.0, 0.5);      
    glVertex3f(x, height, z);
    glVertex3f(x, height, z + width);
    glVertex3f(x + width, height, z + width);
    glVertex3f(x + width, height, z);
    
    glEnd();
}

void display()
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-2.0, 2.0, -0.5, 2.0, 5, 80);
    gluLookAt(standx, 1, standz,
          turnx, 0, turnz,
          0, 1, 0);

    // Drawing the scene
    drawFloor();
    drawPyramid(-26.0, -26.0, 5.0, 4.0);
    drawPyramid(23.0, -26.0, 5.0, 4.0);
    drawPyramid(23.0, 22.0, 5.0, 4.0);
    drawPyramid(-26.0, 22.0, 5.0, 4.0);
    drawPrism(-3.0, 15.0, 5.0, 1.0);
    drawPrism(-1.0, 15.0, 5.0, 1.0);
    drawPrism(1.0, 15.0, 5.0, 1.0);
    drawPrism(3.0, 15.0, 5.0, 1.0);

    glutSwapBuffers();
}

void reshape(int w, int h)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, w, h);
    glFrustum(-2.0, 2.0, -0.5, 2.0, 5, 40);
    gluLookAt(0, 1, 0,
          0, 0, 90,
          0, 1, 0);
    glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y)
{
    if(toupper(key) == 'Q') exit(0);

    if(toupper(key) == 'W')
    {
        walk('f');
        glutPostRedisplay();
    }
    
    if(toupper(key) == 'S')
    {
        walk('b');
        glutPostRedisplay();
    }

    if(toupper(key) == 'A')
    {
        x_alt = x;
        turn('l');
        glutPostRedisplay();
    }
    
    if(toupper(key) == 'D')
    {
        x_alt = x;
        turn('r');
        glutPostRedisplay();
    }
}

void keyboard_special(int key, int x, int y)
{
    if(key == GLUT_KEY_UP)
    {
        walk('f');
        glutPostRedisplay();
    }

    if(key == GLUT_KEY_DOWN)
    {
        walk('b');
        glutPostRedisplay();
    }
}

void mouse_motion(int x, int y)
{
    if(x < x_alt)
    {
        mousex_old = x;
        turn('l');
        glutPostRedisplay();
    }
    
    if(x > x_alt)
    {
        mousex_old = x;
        turn('r');
        glutPostRedisplay();
    }
}

void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    // get the device context (DC)
    *hDC = GetDC(hWnd);

    // set the pixel format for the DC
    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 = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat(*hDC, &pfd);
    SetPixelFormat(*hDC, iFormat, &pfd);

    // create and enable the render context (RC)
    *hRC = wglCreateContext(*hDC);
    wglMakeCurrent(*hDC, *hRC);
}

void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hRC);
    ReleaseDC(hWnd, hDC);
}

/* ==================================================================
 * Function: 'WinMain'
 * Description: Main program frame for Win32.
 * ================================================================== */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                   LPSTR lpCmdLine, int iCmdShow)
{
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;
    MSG msg;
    BOOL quit = FALSE;
    
    // register window class
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "GLSample";
    RegisterClass(&wc);
    
    // create main window
    hWnd = CreateWindow( 
        "GLSample", "OpenGL Sample", 
        WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
        0, 0, 256, 256,
        NULL, NULL, hInstance, NULL);
    
    // enable OpenGL for the window
    EnableOpenGL(hWnd, &hDC, &hRC);
    
    // program main loop
    while(!quit)
    {
        // check for messages
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // handle or dispatch messages
            if(msg.message == WM_QUIT) quit = TRUE;
            else 
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        } 
        else 
        {
            // OpenGL animation code goes here
            
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            
            glPushMatrix();
            // CODE HERE
            glPopMatrix();
            
            SwapBuffers(hDC);
            
            theta += 1.0f;
        }
    }
    
    // shutdown OpenGL
    DisableOpenGL(hWnd, hDC, hRC);

    // destroy the window explicitly
    DestroyWindow(hWnd);

    return msg.wParam;
}

// Window Procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_CREATE:
            return 0;
        case WM_CLOSE:
            PostQuitMessage(0);
            return 0;
        case WM_DESTROY:
            return 0;
        case WM_KEYDOWN:
            switch(wParam)
            {
                case VK_ESCAPE:
                    PostQuitMessage(0);
                    return 0;
            }
            return 0;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
}

/* ==================================================================
 * Function: 'main'
 * Description: Main program frame for Linux.
 * ================================================================== */
/*
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitWindowSize(1024, 768);
    glutInitWindowPosition(100, 100);
    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("CheapGin");

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutSpecialFunc(keyboard_special);
    glutPassiveMotionFunc(mouse_motion);

    glEnable(GL_DEPTH_TEST);
    glutMainLoop();

    return 0;
}
*/