开发者

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. Assuming my window is 640x480, I want the top left of the screen be axis (0, 0), and the bottom right (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. I don't want something hackish only to flip 1 shape. I want it to flip all future shapes I make on the y axis while maintaining the coordinate system. 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); will flip my shape, but I have to include it inside glPushMatrix() 开发者_如何学Cof my shapes, and I don't know if this is the proper way to do this or if its a hackish solution.


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


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. Also, you do not have to set the Allegro-to-view matrix per frame; once during initialization is enough for most use cases. You might, however, push GL_MODELVIEW and apply any model transforms that are necessary.


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, i.e. coordinates where the origin is top-left corner of the orthographic projection (in this case, this relates directly to the screen). 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).

First, you reorient (scale) the y-axis of desired coordinates to match view coordinates (middle figure). Second, you translate the origin of desired coordinates to match the origin of view coordinates. This translation is made relative to view coordinates (i.e. 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 = (P.x, P.y) to P' = (P.x, -P.y). The translate transforms the point P' to P'' = (P.x - w/2, P.y + h/2) where w is the width of the screen (480px) and h is the height (640px). (Sorry, the final diagram incorrectly switches h and w for P'' because I can't do diagrams on SO very well).

Note that the z-axis points out of the screen since we did not scale it by -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). 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.

Inverting y axis, and setting coordinate system in OpenGL


You should read: http://www.opengl.org/documentation/specs/version2.0/glspec20.pdf It very explicitly spells out all coordinate transforms. 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. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜