magnavimaras
magnavimaras

Reputation: 69

gluPerspective not working

I use gluPerspective to mainly increase the draw distance, but it doesn't seem to work.

This is how it shows in my code:

gluPerspective(0, 70/70, 0, 4333);

ratio: The window Width and Height is both 700 and they are constant, in case of wondering.

fovy: I put 0 because, "they" say that using 45 is very nice to draw, but it stops drawing on the screen.

This is the full code:

#include <Windows.h>
#include <gl\GL.h>
#include <gl/glut.h>

    WNDCLASSEX wclass;
    MSG msg;
    HWND hwnd;
    HDC hdc;

    HDC p_hdc;

    float t;
    int red, green, blue, x, y, z;
    void update()
    {
        RECT rec;
        GetClientRect(hwnd, &rec);
        InvalidateRect(hwnd, &rec, false);
        UpdateWindow(hwnd);
        t += 0.5f;
    }
    void game()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0, 0, 0, 0);
        float norm = 1;
        float z = 0;
        red = 255;
        green = 255;
        glPushMatrix();
        glRotatef(t, 0, 1, 1);
        glBegin(GL_TRIANGLES);
        glColor3f(255, 0, 0);
        glVertex3f(-norm, norm, z);
        glVertex3f(norm, norm, z);
        glColor3f(0, 110, 10);
        glVertex3f(-norm, -norm, z);
        glEnd();
        gluPerspective(45, 70/70, 0.01f, 4333);
        glPopMatrix();
        SwapBuffers(hdc);
    }
    HGLRC hrc;
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
{

    wclass.cbSize = sizeof(WNDCLASSEX);
    wclass.style = 0;
    wclass.lpfnWndProc = WinProc;
    wclass.cbClsExtra = 0;
    wclass.cbWndExtra = 0;
    wclass.hInstance = hInstance;
    wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
    wclass.lpszMenuName = NULL;
    wclass.lpszClassName = "CLASS";
    wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wclass))
    {
         MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
         return 0;
    }

    hwnd = CreateWindowEx(
    0, "CLASS", "OPENGL WORLD", WS_OVERLAPPEDWINDOW,
    0, 0, 700, 700,
    HWND_DESKTOP, NULL, hInstance, NULL
    );

    EnableOpenGL(hwnd, &hdc, &hrc);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    if(hwnd == NULL)
    {
        MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
    }
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
    {
        case WM_CREATE:
            SetTimer(hwnd, 1, 1, NULL);
            break;
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        case WM_TIMER:
            game();
            update();
            break;
        case WM_PAINT:
            PAINTSTRUCT ps;
            HDC win;
            win = BeginPaint(hwnd, &ps);
            p_hdc = win;
            game();
            EndPaint(hwnd, &ps);
            break;
        default:
                return DefWindowProc (hwnd, msg, wParam, lParam);
    }

    return 0;
}

void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
    PIXELFORMATDESCRIPTOR pfd;

    int iFormat;

    *hDC = GetDC(hwnd);

    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);

    *hRC = wglCreateContext(*hDC);

    wglMakeCurrent(*hDC, *hRC);
}

What to do?

EDIT: THE NEW CODE

#include <Windows.h>
#include <gl\GL.h>
#include <gl/glut.h>

    WNDCLASSEX wclass;
    MSG msg;
    HWND hwnd;
    HDC hdc;

    HDC p_hdc;

    float t;
    int red, green, blue, x, y, z;
    float cx, cy, cz;

    void handle_resize()
    {
        RECT rec;
        GetClientRect(hwnd, &rec);
        long width = rec.right - rec.left;
        long height = rec.top - rec.bottom;
        float aspect = (float)width/(float)height;

        glViewport(0, 0, 700, 700);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(45, aspect, 0.01f, 99999);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    void update()
    {
        RECT rec;
        GetClientRect(hwnd, &rec);
        InvalidateRect(hwnd, &rec, false);
        UpdateWindow(hwnd);
        t += 0.5f;
        cz = -3;
    }
    void game()
    {
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        float norm = 1;
        float z = 0;
        red = 255;
        green = 255;

        glPushMatrix();
        glRotatef(t, 0, 1, 1);
        glBegin(GL_TRIANGLES);
        glColor3f(255, 0, 0);
        glVertex3f(-norm, norm, z);
        glVertex3f(norm, norm, z);
        glColor3f(0, 110, 10);
        glVertex3f(-norm, -norm, z);
        glEnd();
        glPopMatrix();

        SwapBuffers(hdc);
    }
    HGLRC hrc;
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
{

    wclass.cbSize = sizeof(WNDCLASSEX);
    wclass.style = 0;
    wclass.lpfnWndProc = WinProc;
    wclass.cbClsExtra = 0;
    wclass.cbWndExtra = 0;
    wclass.hInstance = hInstance;
    wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
    wclass.lpszMenuName = NULL;
    wclass.lpszClassName = "CLASS";
    wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wclass))
    {
         MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
         return 0;
    }

    hwnd = CreateWindowEx(
    0, "CLASS", "OPENGL WORLD", WS_OVERLAPPEDWINDOW,
    0, 0, 700, 700,
    HWND_DESKTOP, NULL, hInstance, NULL
    );

    EnableOpenGL(hwnd, &hdc, &hrc);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    glMatrixMode(GL_PROJECTION);
    glMatrixMode(GL_MODELVIEW);
    if(hwnd == NULL)
    {
        MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
    }
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
    {
        case WM_CREATE:
            SetTimer(hwnd, 1, 1, NULL);
            break;
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        case WM_TIMER:
            game();
            update();
            break;
        case WM_PAINT:
            PAINTSTRUCT ps;
            HDC win;
            win = BeginPaint(hwnd, &ps);
            p_hdc = win;
            game();
            EndPaint(hwnd, &ps);
            break;
        case WM_SIZE:
            handle_resize();
            break;
        default:
                return DefWindowProc (hwnd, msg, wParam, lParam);
    }

    return 0;
}

void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
    PIXELFORMATDESCRIPTOR pfd;

    int iFormat;

    *hDC = GetDC(hwnd);

    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);

    *hRC = wglCreateContext(*hDC);

    wglMakeCurrent(*hDC, *hRC);
}

Upvotes: 0

Views: 2603

Answers (2)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

As-per our comments, I made a few changes to your code that are necessary to properly deal with the perspective projection matrix and window sizing. There are still a number of things about this code that I do not like, such as drawing using a timer but this should at least address the small things.

New code:

void handle_resize (void)
{
    RECT rec;
    GetClientRect(hwnd, &rec);

    long width  = rec.right - rec.left;
    long height = rec.top   - rec.bottom;

    float aspect = (float)width/(float)height;

    glViewport     (0, 0, width, height);

    glMatrixMode   (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (45, aspect, 0.01f, 4333);

    glMatrixMode   (GL_MODELVIEW);
    glLoadIdentity ();
}

void game()
{
    glClearColor(0, 0, 0, 0); // Do this first
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    float norm = 1;
    float z = 0;
    red = 255;
    green = 255;
    glMatrixMode (GL_MODELVIEW);
    glPushMatrix();
    glRotatef(t, 0, 1, 1);
    glBegin(GL_TRIANGLES);
    glColor3ub(255, 0, 0);
    glVertex3f(-norm, norm, z);
    glVertex3f(norm, norm, z);
    glColor3ub(0, 110, 10);
    glVertex3f(-norm, -norm, z);
    glEnd();
    //gluPerspective(45, 70/70, 0.01f, 4333); // GET THIS OUT OF HERE!!!
    glPopMatrix();
    SwapBuffers(hdc);
}

Changes to your window message handler:

switch (msg)
{
    case WM_CREATE:
        SetTimer(hwnd, 1, 1, NULL);
        break;

    // NEW EVENT: Handle window size change
    case WM_SIZE:
        handle_resize ();
        break;

Other things to note:

glColor3f clamps the floating-point value to the range [0.0,1.0], you were using values of 255 which is only appropriate if you use glColor3ub, which is essentially the same thing as glColor3f (1.0f, 1.0f, 1.0f).

Upvotes: 0

genpfault
genpfault

Reputation: 52082

gluPerspective(0, 70/70, 0, 4333);
               ^ nope    ^ nope

fovy and zNear must both be positive and non-zero.

Try this:

gluPerspective( 45, 70/70, 0.1, 4333 );

EDIT: Push your camera back a bit too:

#include <GL/glut.h>

float t = 0;
void timer( int val )
{
    t += 0.5f;
    glutTimerFunc( 10, timer, 0 );
    glutPostRedisplay();
}

void display()
{
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    gluPerspective( 45, w / h, 0.1, 4333.0 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0, 0, -5 );

    float norm = 1;
    float z = 0;
    glPushMatrix();
    glRotatef(t, 0, 1, 1);
    glBegin(GL_TRIANGLES);
    glColor3f(255, 0, 0);
    glVertex3f(-norm, norm, z);
    glVertex3f(norm, norm, z);
    glColor3f(0, 110, 10);
    glVertex3f(-norm, -norm, z);
    glEnd();
    glPopMatrix();

    glutSwapBuffers();
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow( "GLUT" );
    glutDisplayFunc( display );
    glutTimerFunc( 0, timer, 0 );
    glutMainLoop();
    return 0;
}

Upvotes: 7

Related Questions