开发者

Cord system and units?

开发者 https://www.devze.com 2023-03-04 20:05 出处:网络
How do I change default cord sy开发者_如何学Gostem and units in OpenGL? Right now it\'s using the default, meaning it goes from -1.0 (left) to 1.0 (right) with 0 being the origin (same with Y, -1.0 b

How do I change default cord sy开发者_如何学Gostem and units in OpenGL?

Right now it's using the default, meaning it goes from -1.0 (left) to 1.0 (right) with 0 being the origin (same with Y, -1.0 being top, 1.0 being bottom).

Optimally I would 1) want to change units to roughly same number of pixels. For example, on an 800x600 display have it go from -400 to 400 (on x) and -300 to 300 (on y). Seems like it would be easier to work with than -1.0 to 1.0

2) Bonus points: how do I change the x/y? One game engine had I seen had it go from 0 to maxWidth and 0 to maxHeight.

That is, 0,0 was top left and 800,600 was bottom right. (0, 600 would be left bottom and 800,0 would be top right)

I think these both have to do with the viewpoint command, but don't know if I fully understand it.


First answering your last point: There is no "viewpo i nt" commant. There is glViewport which defines the mapping from so called clip space [-1,1]×[-1,1]×[-1,1] into window/screen space — important: glViewport doesn't set some clipping, so if your viewport only covers some smaller, middle part of your window, things that exceed the viewport in rendering may/will cause artifacts outside the viewport. Scissor testing (enabled and set with *glEnable(GL_SCISSOR_TEST)* and glScissor) does this kind of clipping, which also works within the viewport (nice for implementing selection rubber bands!).

Now to cover your first question: OpenGL's coordinate system is whatever you want it to be; in OpenGL-3.1 and OpenGL-4 there's no default coordinate system at all! In OpenGL-2 and below there are a number of so called transformation matrices, most importantly modelview and projection.

You can think projection to be some kind of a camera's lens (although it works entirely differently). What is does is, it transforms the world (or modelview) space into the aforementioned clip space. It is this projection matrix, that allows you map any affine coordinate system into clip space. OpenGL before version 3 provides you helper functions glFrustum and glOrtho for the most oftenly used projections: Perspective and Ortho.

Let's construct some projection ourself (it's an ortho, but I'd like to show how things work on the math side). Say you'd like to map x in [0; 200], y in [0; 100] to [-1; 1] (left to right), [-1,1] (top to bottom), and leave z as it is. Then

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

This translates into the following matrix:

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

You could now put this into the projection matrix using glLoadMatrix.

The modelview matrix is used for moving stuff around in the world space. It's also used to define the viewpoint: OpenGL has no camera. Instead we just move the whole world in an opposite way to how we'd moved a camera within the world to the desired viewpoint (this time …point, not …port!)


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;
}
0

精彩评论

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