Sign in to follow this  

getting input from WndProc to OpenGL code (Win32/OpenGL related)

This topic is 3727 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a standard windows application with OpenGL enabled, and some simple shapes flying around in 3d. Interesting huh? :) Well, I have a function handling drawing, and the standard WndProc function handling user input. My question is how should I go about getting the user input to the section of my program related to drawing? I'm not a C++ / OpenGL newb, I can do it, but not in a very good way (globals and messy code). How should I go about doing it properly? Here is my code
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>

char* WindowClass(HINSTANCE, HINSTANCE, LPSTR, int);
HWND Window(HINSTANCE, HINSTANCE, LPSTR, int);
LRESULT CALLBACK WndProc(HWND , UINT ,WPARAM , LPARAM );
void EnableOpenGL (HWND, HDC*, HGLRC*);
void DisableOpenGL (HWND, HDC, HGLRC);
void Loop(HDC*);
void Draw(HDC*);

/* Test function. */
void DrawLine(float originX, float originY, float originZ, float destinationX, float destinationY, float destinationZ)
{
    glPointSize(8.0f);

    glBegin(GL_POINTS);
    glColor3f(0.0f, 0.0f, 0.0f);
    glVertex3f(originX, originY, originZ);
    glVertex3f(destinationX, destinationY, destinationZ);
    glEnd();

    glLineWidth(2.0f);

    glBegin(GL_LINES);
    glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
    glVertex3f(originX, originY, originZ);
    glVertex3f(destinationX, destinationY, destinationZ);
    glEnd();
}

/* Creates a new window class. */
char* WindowClass(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
    WNDCLASS wc;
    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 = "BasicWindow";
    RegisterClass(&wc);

    return (char*)wc.lpszClassName;
}

/* Creates a new window. */
HWND Window(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
    char* myclass = WindowClass(hInstance, hPrevInstance, lpCmdLine, iCmdShow);

    HWND hWnd = CreateWindow(
        myclass, "Three Dimensions",
        WS_CAPTION | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX ,
        CW_USEDEFAULT, CW_USEDEFAULT, 1024, 768,
        NULL, NULL, hInstance, NULL);

    free(myclass);

    return hWnd;
}

/* Main event and OpenGL display loop. */
void Loop(HDC* DeviceContext)
{
    MSG msg;
    BOOL bQuit = FALSE;

    while(!bQuit)
    {
        /* check for messages */
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
            Draw(DeviceContext);
        }
    }
}

void Draw(HDC* DeviceContext)
{
    static float theta = 0.0f;

    /* OpenGL animation code goes here */

    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    gluPerspective(60.0f,(GLfloat)1024/(GLfloat)768, 0.2f ,150.0f);

    glTranslatef(0.0f, -0.0f, -5.0f);
    glRotatef(25.0f, 1.0f, 0.0f, 0.0f);

    glPushMatrix ();

    // spin so user can observe space
    glRotatef(theta, 0.0f, 1.0f, 0.0f);

    glLineWidth(3.0f);

    // x axis
    glBegin(GL_LINES);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(1.0f, 0.0f, 0.0f);
    glEnd();

    glBegin(GL_LINES);
    glColor4f(1.0f, 0.0f, 0.0f, 0.1f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(-1.0f, 0.0f, 0.0f);
    glEnd();

    // y axis
    glBegin(GL_LINES);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, 1.0f, 0.0f);
    glEnd();

    glBegin(GL_LINES);
    glColor4f(0.0f, 1.0f, 0.0f, 0.1f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, -1.0f, 0.0f);
    glEnd();

    // z axis
    glBegin(GL_LINES);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, 0.0f, 1.0f);
    glEnd();

    glBegin(GL_LINES);
    glColor4f(0.0f, 0.0f, 1.0f, 0.1f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, 0.0f, -1.0f);
    glEnd();

    // begin lines

    DrawLine(0,0,0,1,-2,1);
    DrawLine(1,-2,1,-2.2,0.4,1);
    DrawLine(-2.2,0.4,1,-0.8,0.6,0);
    DrawLine(-0.8,0.6,0,-0.8,0.6,0);
    DrawLine(-0.8,0.6,0,-1.3,1.6,3.8);
    DrawLine(-1.3,1.6,3.8,4.2,1.5,2.6);
    DrawLine(4.2,1.5,2.6,1.5,-2.4,-2.4);
    DrawLine(1.5,-2.4,-2.4,-3.2,-1.2,-3.9);
    DrawLine(-3.2,-1.2,-3.9,0,0,0);
    DrawLine(0,0,0,0,0,0);
    DrawLine(0,0,0,0,0,0);

    // finish lines

    /*glPushMatrix();
    glutStrokeCharacter(GLUT_STROKE_ROMAN, 'a');
    glPopMatrix();*/

    glPopMatrix();

    SwapBuffers(*DeviceContext);

    theta += 0.5f;
    Sleep(30);
}

/* WINAPI start point. */
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
    // Create window.
    HWND WindowHandle = Window(hInstance, hPrevInstance, lpCmdLine, iCmdShow);

    HDC DeviceContext;
    HGLRC RenderContext;

    // Enable OpenGL.
    EnableOpenGL(WindowHandle, &DeviceContext, &RenderContext);

    // Main loop.
    Loop(&DeviceContext);

    // Shutdown OpenGL.
    DisableOpenGL (WindowHandle, DeviceContext, RenderContext);

    // Destroy the window explicitly.
    DestroyWindow (WindowHandle);

    //return msg.wParam;
    return 0;
}

/********************
 * 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);
    }
}

/* Enable OpenGL. */
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);

    // Enable transparency and blending etc.
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_POINT_SMOOTH);
    glEnable (GL_LINE_SMOOTH);
}


/* Disable OpenGL. */
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent (NULL, NULL);
    wglDeleteContext (hRC);
    ReleaseDC (hWnd, hDC);
}
Here is example output if anyone is interested. Free Image Hosting at www.ImageShack.us The view is also rotating :)

Share this post


Link to post
Share on other sites

This topic is 3727 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this