【问题标题】:true isometric projection with opengl使用opengl进行真正的等距投影
【发布时间】:2010-11-06 17:58:48
【问题描述】:

我是使用 C++ 进行 OpenGL 编程的新手,数学不太好。有没有简单的等距投影方法?

我的意思是the true isometric projection,而不是一般的正交投影。

(等距投影仅在单位 X、Y 和 Z 向量的投影长度相等且它们之间的夹角正好为 120 度时才会发生。)

非常感谢代码 sn-ps..

【问题讨论】:

标签: c++ opengl projection isometric


【解决方案1】:

如果你不想使用 GLU,这里是使用 glOrtho 的基本框架

void gl_enter_2_5d_mode (void)
{
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    glLoadIdentity();

    double scale = 50;
    glOrtho(-scale,
            scale,
            -scale * 0.7,
            scale * 0.7,
            -scale,
            scale);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    glLoadIdentity();

    glRotatef(35.264f, 1.0f, 0.0f, 0.0f);
    glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
}

void gl_leave_2_5d_mode (void)
{
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
}

then draw a cube in it

void cube (double size)
{
    glBegin(GL_QUADS);

    glVertex3f(size,size,size);
    glVertex3f(-size,size,size);
    glVertex3f(-size,-size,size);
    glVertex3f(size,-size,size);

    glVertex3f(size,size,-size);
    glVertex3f(-size,size,-size);
    glVertex3f(-size,-size,-size);
    glVertex3f(size,-size,-size);

    glVertex3f(size,size,size);
    glVertex3f(size,-size,size);
    glVertex3f(size,-size,-size);
    glVertex3f(size,size,-size);

    glVertex3f(-size,size,size);
    glVertex3f(-size,-size,size);
    glVertex3f(-size,-size,-size);
    glVertex3f(-size,size,-size);

    glVertex3f(size,size,size);
    glVertex3f(-size,size,size);
    glVertex3f(-size,size,-size);
    glVertex3f(size,size,-size);

    glVertex3f(size,-size,size);
    glVertex3f(-size,-size,size);
    glVertex3f(-size,-size,-size);
    glVertex3f(size,-size,-size);

    glEnd();
}

void test (void)
{
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glBindTexture(GL_TEXTURE_2D, 0);
    cube(1.0);
    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}

并调用这样的东西

gl_enter_2_5d_mode()
test()
gl_leave_2_5d_mode()

如果你想在 2d 和 2.5d 之间切换(这样你就可以绘制你的 UI)然后我有类似的功能来进入和离开 2d 模式,例如

void gl_init_2d_mode (void)
{
    /*
     * Enable Texture Mapping
     */
    glEnable(GL_TEXTURE_2D);

    /*
     * Enable alpha blending for sprites
     */
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    /*
     * Setup our viewport
     */
    glViewport(0, 0, game.video_pix_width,
               game.video_pix_height);

    /*
     * Make sure we're changing the model view and not the projection
     */
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    /*
     * Reset the view
     */
    glLoadIdentity();

    gl_init_fbo();
}

void gl_enter_2d_mode (void)
{
    /*
     * Change to the projection matrix and set our viewing volume.
     */
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    /*
     * Reset the view
     */
    glLoadIdentity();

    /*
     * 2D projection
     */
    glOrtho(0,
             game.video_gl_width, game.video_gl_height,
             0, -1200.0, 1200.0);

    /*
     * Make sure we're changing the model view and not the projection
     */
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    /*
     * Reset the view
     */
    glLoadIdentity();
}

【讨论】:

    【解决方案2】:

    尝试使用gluLookAt

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    /* use this length so that camera is 1 unit away from origin */
    double dist = sqrt(1 / 3.0);
    
    gluLookAt(dist, dist, dist,  /* position of camera */
              0.0,  0.0,  0.0,   /* where camera is pointing at */
              0.0,  1.0,  0.0);  /* which direction is up */
    glMatrixMode(GL_MODELVIEW);
    
    glBegin(GL_LINES);
    
    glColor3d(1.0, 0.0, 0.0);
    glVertex3d(0.0, 0.0, 0.0);
    glVertex3d(1.0, 0.0, 0.0);
    
    glColor3d(0.0, 1.0, 0.0);
    glVertex3d(0.0, 0.0, 0.0);
    glVertex3d(0.0, 1.0, 0.0);
    
    glColor3d(0.0, 0.0, 1.0);
    glVertex3d(0.0, 0.0, 0.0);
    glVertex3d(0.0, 0.0, 1.0);
    
    glEnd();
    
    glFlush();
    

    结果

    我们可以画一个立方体来检查平行线是否确实平行

    glPushMatrix();
    glTranslated(0.5, 0.5, 0.5);
    glColor3d(0.5, 0.5, 0.5);
    glutWireCube(1);
    glPopMatrix();
    

    【讨论】:

    • 这不会为您提供等轴测投影,因为平行线(例如沿 x 轴和 y 轴)不会看起来平行,而实际上它们应该平行。
    • 查看问题中也链接的维基百科文章上的图片,这看起来与那个投影完全一样。因为这是正交投影 (en.wikipedia.org/wiki/Orthographic_projection),所以任何平行线都将显示为平行。 x 和 y 轴不平行。
    • 我并不是说 x 轴和 y 轴是平行的,但是平行于 x 轴的线在等轴测投影中应该看起来是平行的(我认为它们不会出现在你的投影中),并且同样在 y 方向上。
    • 哎呀,我的错。我错过了您调用 gluLookAt。立即 +1。
    【解决方案3】:

    等距投影只是使用具有特定旋转角度的正交投影。

    您应该能够通过正交投影选择 8 个潜在方向中的任何一个,并获得模型的完美等距视图。只需按照您引用的 Wiki 文章中的数学设置来设置视图矩阵,然后为您的投影矩阵进行正交投影,一切就绪。

    【讨论】:

      【解决方案4】:

      也许我没有完全正确地理解数学,但你不能按照维基百科链接中的说明定位你的相机并使用标准正交投影吗?

      即使不一样,投影堆栈也完全取决于您。

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      // your isometric matrix here (see math on Wikipedia)
      glMatrixMode(GL_MODELVIEW);
      

      【讨论】:

        猜你喜欢
        • 2012-02-10
        • 2011-10-03
        • 2014-02-28
        • 1970-01-01
        • 2014-11-17
        • 2013-02-10
        • 1970-01-01
        • 1970-01-01
        • 2015-11-01
        相关资源
        最近更新 更多