简体   繁体   English

反转y轴并在OpenGL中设置坐标系

[英]Inverting y axis, and setting coordinate system in OpenGL

In OpenGL, I am trying to invert the y axis, and set a specific type of coordinate system just like how Allegro has it. 在OpenGL中,我试图反转y轴,并设置一种特定类型的坐标系,就像Allegro那样。 Assuming my window is 640x480, I want the top left of the screen be axis (0, 0), and the bottom right (640, 480). 假设我的窗口是640x480,我希望屏幕的左上角是轴(0,0),而右下角(640,480)。 So far, I managed to get the proper coordinate system I want, but I don't know if it is done the proper way. 到目前为止,我设法获得了所需的正确坐标系,但是我不知道它是否以正确的方式完成。 As for flipping the y axis, I was unable to invert it without modifying the coordinate system I currently have. 至于翻转y轴,我无法在不修改当前坐标系的情况下将其反转。 I don't want something hackish only to flip 1 shape. 我不希望某些东西只翻转1个形状。 I want it to flip all future shapes I make on the y axis while maintaining the coordinate system. 我希望它在保持坐标系的同时翻转我在y轴上所做的所有将来的形状。 Here is what I have so far. 这是我到目前为止所拥有的。

Initialize: 初始化:

const GLdouble XSize = 640, YSize = 480;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, XSize, YSize, 0, 1, 1000);
glMatrixMode(GL_MODELVIEW);

Render: 渲染:

float size = 30;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -500);

glPushMatrix();
glTranslatef(size, size, 0.0f);

glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.3, 0.8);
glVertex3f( 0.0f, size, 0.0f);
glVertex3f(-size,-size, 0.0f);
glVertex3f( size,-size, 0.0f);
glEnd();
glPopMatrix();

Edit: 编辑:

I figured out that adding glScalef(1, -1, 1); 我发现添加glScalef(1,-1,1); will flip my shape, but I have to include it inside glPushMatrix() of my shapes, and I don't know if this is the proper way to do this or if its a hackish solution. 会翻转我的形状,但是我必须将其包含在我的形状的glPushMatrix()中,而且我不知道这是否是执行此操作的正确方法,或者它是否是一种糟糕的解决方案。

To change the coordinate system, a scale and a translate are required in that order. 要更改坐标系,需要按比例缩放和平移。

// Initialize OpenGL matrices
void init_gl() {
    const float WIDTH = 640.0f;
    const float HEIGHT = 480.0f;

    const float HALF_WIDTH = WIDTH / 2.0f;
    const float HALF_HEIGHT = HEIGHT / 2.0f;

    // Setup the projection matrix
    glMatrixMode(GL_PROECTION);
    glLoadIDentity();
    glOrtho(0, WIDTH, HEIGHT, 0.0f, 0.0f, 1000.0f);

    // Setup the Allegro-to-view matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(-HALF_WIDTH, HALF_HEIGHT, 0.0f);
    glScalef(1.0f, -1.0f, 1.0f);
}

// Render scene
void render() {
    // Now render using points in Allegro coordinates
    const float size = 30.0f;
    glBegin(GL_TRIANGLES);
    glColor3f(0.1f, 0.3f, 0.8f);
    glVertex3f( 0.0f,  size, 0.0f);
    glVertex3f(-size, -size, 0.0f);
    glVertex3f( size, -size, 0.0f);
    glEnd();
}

Note that glTranslatef comes before glScalef because transformation matrices are multiplied on the right side of the current matrix value. 请注意, glTranslatefglScalef之前,因为转换矩阵在当前矩阵值的右侧相乘。 Also, you do not have to set the Allegro-to-view matrix per frame; 同样,您不必每帧设置Allegro-to-view矩阵。 once during initialization is enough for most use cases. 对于大多数使用情况,初始化期间只需一次即可。 You might, however, push GL_MODELVIEW and apply any model transforms that are necessary. 但是,您可以按GL_MODELVIEW并应用任何必要的模型转换。


Here is a conceptual analysis of how this works. 这是有关其工作原理的概念分析。 The goal is to allow you, the graphics programmer, to specify points using 'Allegro' or desired coordinates, ie coordinates where the origin is top-left corner of the orthographic projection (in this case, this relates directly to the screen). 目标是允许图形程序员使用“ Allegro”或所需坐标(即,原点为正交投影的左上角的坐标)指定点(在这种情况下,这直接与屏幕有关)。 To accomplish this, you setup the view matrix GL_MODELVIEW to transform from these desired coordinates to orthographic camera coordinates (also known as view space or eye space). 为此,可以设置视图矩阵GL_MODELVIEW从这些所需的坐标转换为正交相机坐标(也称为视图空间或眼睛空间)。

First, you reorient (scale) the y-axis of desired coordinates to match view coordinates (middle figure). 首先,您需要调整(缩放)所需坐标的y轴以匹配视图坐标(中间图)。 Second, you translate the origin of desired coordinates to match the origin of view coordinates. 其次,转换所需坐标的原点以匹配视图坐标的原点。 This translation is made relative to view coordinates (ie the origin of view coordinates is half the screen horizontally to the right and half the screen vertically down). 这种平移是相对于视图坐标进行的(即,视图坐标的原点是屏幕水平向右的一半,屏幕垂直向下的一半)。 This last step is equivalent to transforming points in the opposite direction of the shift. 最后一步等效于在换档的相反方向上变换点。

Symbolically, the scale transforms the point P = (Px, Py) to P' = (Px, -Py) . 象征性地,比例尺将点P = (Px, Py)P' = (Px, -Py) The translate transforms the point P' to P'' = (Px - w/2, Py + h/2) where w is the width of the screen (480px) and h is the height (640px). 转换将点P'转换为P'' = (Px - w/2, Py + h/2) ,其中w是屏幕的宽度(480px), h是高度(640px)。 (Sorry, the final diagram incorrectly switches h and w for P'' because I can't do diagrams on SO very well). (对不起,最终图错误地将P'' hw切换了,因为我不能很好地在SO上做图)。

Note that the z-axis points out of the screen since we did not scale it by -1. 请注意,z轴指向屏幕外,因为我们没有将其缩放为-1。

The way I prefer to conceptualize changes of coordinate systems (more accurately, change of frames when we include the concept of an origin) is that we're modifying the basis vectors (x, y, etc.) and the origin with subsequent scale, rotation, and translation operations (in that order). 我更喜欢概念化坐标系的变化(更准确地说,当我们包含原点的概念时更改框架 )的方式是,我们正在修改基向量(x,y等)以及具有后续比例的原点,旋转和平移操作(按此顺序)。 This is very similar to the way we conceptualize moving the camera around by applying translations in the opposite direction with which the camera is moving. 这非常类似于我们通过在与照相机移动相反的方向上应用平移来概念化照相机移动的方式。

两种转换的大致示意图

You'd be better off tweaking the projection (think of it as the "camera") in that case. 在这种情况下,最好调整一下投影(将其视为“相机”)。

Check out tzaman's answer here: Modifying OpenGL axis system 在这里查看tzaman的答案: 修改OpenGL轴系统

You should read: http://www.opengl.org/documentation/specs/version2.0/glspec20.pdf It very explicitly spells out all coordinate transforms. 您应该阅读: http : //www.opengl.org/documentation/specs/version2.0/glspec20.pdf它非常明确地阐明了所有坐标变换。 Follow how your glVertex input data goes through model-view and projection, then pay attention to how it becomes normalized window coordinates and pixels from there. 遵循glVertex输入数据如何通过模型视图和投影进行操作,然后注意它如何从那里变为标准化的窗口坐标和像素。 It is quite a read and you need to follow all the steps on paper to really understand it. 这是一本不错的书,您需要按照纸上的所有步骤进行操作才能真正理解它。 But it will be well worth it. 但这将是值得的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM