在OpenGL中渲染视觉上完美的方块?

时间:2014-07-01 13:14:40

标签: opengl

在OpenGL的固定管道中,默认情况下,使用glVertex3f指定顶点坐标相当于在屏幕空间中指定-1.0和+1.0之间的位置。因此,使用GL_TRIANGLE_STRIP(或甚至GL_QUADS)给出一组4个完全相邻的屏幕空间顶点,除非您的窗口已经是完全正方形,否则您将始终渲染矩形而不是完美的正方形。 ..

知道窗户的宽度,高度和纵横比,有什么办法可以解决这个问题吗? 我尝试将顶点坐标乘以纵横比,遗憾的是它似乎达到了相同的视觉效果。


以下是我目前正在使用的完整源代码:

#include "main.h"
#pragma comment(lib, "glut32.lib")


int g_width = 800;
int g_height = 600;
int g_aspectRatio = double(g_width) / double(g_height);
bool g_bInitialized = false;


int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(g_width, g_height);
    glutCreateWindow("OpenGL Test App");
    glutDisplayFunc(onRender);
    glutReshapeFunc(onSize);
    glutIdleFunc(onRender);
    glutMainLoop();

    return 0;
}

void onInit()
{
    glFrontFace(GL_CW);
}

void onRender()
{
    if(!g_bInitialized)
        onInit();

    static float angle = 0.0f;

    const float p = 0.5f * g_aspectRatio;
    glLoadIdentity();
    gluLookAt(
        0.0f, 0.0f, 10.0f,
        0.0f, 0.0f,  0.0f,
        0.0f, 1.0f,  0.0f
    );

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glScalef(1, -1, 1); // Flip the Y-axis
    glRotatef(angle, 0.0f, 1.0f, 0.0f);
    glBegin(GL_TRIANGLE_STRIP);
    {
        glColor4f(1.0, 0.0, 0.0, 1.0);  // Red
        glVertex3f(-p, -p, 0.0);        // Top-Left
        glColor4f(0.0, 1.0, 0.0, 1.0);  // Green
        glVertex3f(p, -p, 0.0);         // Top-Right
        glColor4f(0.0, 0.0, 1.0, 1.0);  // Blue
        glVertex3f(-p, p, 0.0);         // Bottom-Left
        glColor4f(1.0, 1.0, 0.0, 1.0);  // Yellow
        glVertex3f(p, p, 0.0);          // Bottom-Left
    }
    glEnd();

    angle += 0.6f;
    glutSwapBuffers();
}

void onSize(int w, int h)
{
    g_width = max(w, 1);
    g_height = max(h, 1);
    g_aspectRatio = double(g_width) / double(g_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, w, h);
    gluPerspective(45, g_aspectRatio, 1, 1000);
    glMatrixMode(GL_MODELVIEW); 
}



修改: 这已经解决了......在上面的代码中,我将g_aspectRatio定义为int而不是浮点值。因此,它的价值总是1 ......

2 个答案:

答案 0 :(得分:1)

在我的(旧)经历中,这就是为什么你有gluPerspective()的宽高比参数。

The manual page说:

  

一般来说,gluPerspective中的纵横比应该匹配          相关视口的宽高比。例如,aspect = 2.0          意味着观察者的视角在x中的宽度是y的两倍。          如果视口的宽度是其高度的两倍,则会显示图像          没有失真。

检查g_aspectRatio值。

答案 1 :(得分:-1)

  

默认情况下,使用glVertex3f指定顶点坐标相当于在屏幕空间中指定-1.0和+1.0之间的位置

错误。通过glVertex或glVertexPointer顶点数组传递给OpenGL的坐标位于模型空间中。通过 modelview 矩阵转换为视图空间,并通过投影矩阵从视图空间转换为剪辑空间,从而实现对屏幕空间的转换。然后应用裁剪并应用透视分割以达到标准化坐标空间

因此glVertex的值范围可以是您喜欢的任何值。通过应用正确的投影矩阵,您可以将视图空间设置为[-aspect;方面]×[-1,1]如果你喜欢的话。

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-aspect, aspect, -1, 1, -1, 1);