线系统和单位?

时间:2011-05-08 00:36:53

标签: opengl

如何更改OpenGL中的默认线缆系统和单元?

现在它正在使用默认值,意味着它从-1.0(左)变为1.0(右),0为原点(与Y相同,-1.0为顶部,1.0为底部)。

最好我会1)想要将单位改为大致相同的像素数。例如,在800x600显示器上,它从-400到400(在x上)和-300到300(在y上)。似乎比-1.0到1.0

更容易使用

2)奖励积分:如何更改x / y?我看过一个游戏引擎,它从0到maxWidth,从0到maxHeight。

也就是说,0,0是左上角,800,600是右下角。 (0,600将留在底部,800,0将在右上角)

我认为这些都与视点命令有关,但不知道我是否完全理解它。

2 个答案:

答案 0 :(得分:2)

首先回答你的最后一点:没有“viewpo i nt”commant。有 glViewport ,它定义了从所谓的剪辑空间[-1,1]×[-1,1]×[-1,1]到窗口/屏幕空间的映射 - 重要: glViewport 没有设置一些剪裁,因此如果您的视口仅覆盖窗口的一些较小的中间部分,那么在渲染中超出视口的事物可能/将导致视口外的工件。剪刀测试(启用并使用* glEnable(GL_SCISSOR_TEST)*和 glScissor 设置)执行此类裁剪,这也适用于视口(非常适合实现选择橡皮筋!)。

现在来讨论你的第一个问题:OpenGL的坐标系是你想要的;在OpenGL-3.1和OpenGL-4中根本没有默认的坐标系!在OpenGL-2及以下版本中,有许多所谓的转换矩阵,最重要的是 modelview 投影

你可以认为投影是某种相机的镜头(虽然它完全不同)。它的作用是将 world (或modelview)空间转换为前面提到的剪辑空间。正是这个投影矩阵,允许您将任何仿射坐标系映射到剪辑空间。版本3之前的OpenGL为最常用的投影提供辅助函数 glFrustum glOrtho :Perspective和Ortho。

让我们自己构建一些投影(它是一个原点,但我想展示数学方面的工作原理)。假设你想在[0; 200],y在[0; 100]到[-1; 1](从左到右),[ - 1,1](从上到下),并保持原样。然后

x_clip = -1 + x*(1-(-1))*(200-0) = -1 + x*2/200
y_clip =  1 + y*(-1  1 )*(100-0) =   1 + x*(-2)/100
z_clip = z

这转换为以下矩阵:

2/200      0     0    -1
    0 -2/100     0     1
    0      0     1     0
    0      0     0     1

现在可以使用 glLoadMatrix 将其放入投影矩阵中。

modelview 矩阵用于移动世界空间中的东西。它也用于定义视点:OpenGL没有摄像头。相反,我们只是以与我们将世界范围内的相机移动到所需视点的方式相反的方式移动整个世界(这次......点,而不是......端口!)

答案 1 :(得分:1)

glOrtho()

#include <GL/glut.h>

unsigned int win_w = 0;
unsigned int win_h = 0;

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, win_w, win_h, 0, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glColor3ub(255,0,0);
    glPushMatrix();
        glScalef(50,50,50);
        glBegin(GL_QUADS);
            glVertex2f(0,0);
            glVertex2f(1,0);
            glVertex2f(1,1);
            glVertex2f(0,1);
        glEnd();
    glPopMatrix();

    glFlush();
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    win_w = w;
    win_h = h;
    glViewport(0, 0, w, h);
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

    glutInitWindowSize(800,600);
    glutCreateWindow("Ortho);

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}