gluPerspective不工作

时间:2014-01-09 18:42:23

标签: c++ opengl drawing

我使用gluPerspective主要增加绘制距离,但它似乎不起作用。

这是我在代码中显示的内容:

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

比率:窗口宽度和高度都是700,如果想知道它们是不变的。

fovy:我把0放了,因为“他们”说使用45画画非常好,但它停止在画面上画画。

这是完整的代码:

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

怎么办?

编辑:新代码

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

2 个答案:

答案 0 :(得分:6)

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

fovyzNear必须都是正数且非零。

试试这个:

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

编辑:将相机推回一点:

#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;
}

答案 1 :(得分:0)

根据我们的评论,我对您的代码进行了一些更改,这些更改是正确处理透视投影矩阵和窗口大小调整所必需的。关于这段代码还有很多我不喜欢的东西,例如使用计时器绘图,但至少应该解决这些问题。

新代码:

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

对窗口消息处理程序的更改:

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

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

其他注意事项:

glColor3f将浮点值限制在[0.0,1.0]范围内,您使用的值 255 ,只有在使用glColor3ub时才适用与glColor3f (1.0f, 1.0f, 1.0f)基本相同。