gluPerspective不起作用

gluPerspective not working

本文关键字:不起作用 gluPerspective      更新时间:2023-10-16

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

这是我的代码中显示的:

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

比率:窗口宽度和高度都是 700,它们是恒定的,以防万一。

fovy:我把0放是因为,"他们"说使用45很好画,但它停止在屏幕上画画。

这是完整的代码:

#include <Windows.h>
#include <glGL.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 <glGL.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);
}
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;
}

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

新代码:

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) 基本相同。