设置正交投影矩阵?

Posted

技术标签:

【中文标题】设置正交投影矩阵?【英文标题】:Setting a orthographic projection matrix? 【发布时间】:2010-11-05 05:53:44 【问题描述】:

我无法设置尺寸为 4x2 的正交投影矩阵,其中 (0,0) 位于中心,(-2, -1) 位于左下角,(2, 1) 位于顶部右上角。

我使用glutInitWindowSize(600, 300); 来初始化窗口大小。 在我的重塑功能中,我使用glViewport(0, 0, w, h); 来设置视口。 同样在我的 reshape 函数中,我使用gluOrtho2D(-(float)w/h, (float)w/h, -2.0, 2.0); 来设置正交。

但是,当我移动鼠标查看世界坐标​​时,左下角是 (-1, -1),右上角是 (1, 1)。我在这里做错了什么吗?我假设因为我在 gluOrtho2D 调用中分别将底部和顶部设置为 -2 和 2,它应该给我正确的坐标。

如果您发现任何可能有问题的地方,请帮助我。

这是我目前的代码,请忽略手臂变量和绘图函数。

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>

#if 0 /*unix*/
#include <GL/glut.h>
#endif

#if 1 /*apple */
#include <GLUT/glut.h>
#include <OPENGL/gl.h>
#include <OPENGL/glext.h>
#endif

#if 0 /*windows*/
#include <io.h>
#include <fcntl.h>
#include <glut.h>
#endif

int GW, GH;
bool animfore, animupper;
float foreangle, upperangle;

using namespace std;

void drawShoulder();
void drawUpper();
void drawFore();

void display() 
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();

    //draw shoulder
    glPushMatrix();
        drawShoulder();
        //draw upper arm
        glPushMatrix();
            drawUpper();
            //draw forearm
            glPushMatrix();
                drawFore();
            glPopMatrix();
        glPopMatrix();
    glPopMatrix();

    glutPostRedisplay();
    glutSwapBuffers();


void drawShoulder() 
    //cout << "Enters" << endl;

    glBegin(GL_POLYGON);
        glColor3f((float)30/255, (float)0/255, (float)30/255);
        glVertex2f(-2.0, -0.4);
        glVertex2f(-2.0, -1.0);
        glVertex2f(-1.0, -1.0);
        glVertex2f(-1.0, -0.4);
    glEnd();


void drawUpper() 



void drawFore() 



void reshape(GLsizei w, GLsizei h) 
    GW = w;
    GW = h;
    glViewport(0, 0, w, h);
    glLoadIdentity();
    gluOrtho2D(-(float)w/h, (float)w/h, -1.0, 1.0);
    cout << "Enters" << endl;


void keyboard(unsigned char key, int x, int y) 
    switch(key) 
        case 'q' : case 'Q' :
            exit(EXIT_SUCCESS);
            break;
    


//control arm animations
void idle() 
    if(animupper) 

    
    if(animfore) 

    

float p2w_x(int gx) 
    return (float)2.*GW/(GW*GH-GH)*gx-(float)GW/GH;


float p2w_y(int gy) 
    int py = GH-1-gy;
    return (float)2./(GH-1.)*py-1;


void mouseMove(int x, int y) 
    cout << "(" << p2w_x(x) << "," << p2w_y(y) << ")" << endl;


int main(int argc, char **argv) 
    // global variable intializations
    GW = 600;
    GH = 300;
    animfore, animupper = true;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE);

    // initialization
    glutInitWindowSize(600, 300);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Robot Arm");
    glClearColor(1.0, 1.0, 1.0, 1.0);

    // callback functions
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutMotionFunc(mouseMove);

    glutMainLoop();

【问题讨论】:

【参考方案1】:

在设置任何投影矩阵之前使用 glMatrixMode(GL_PROJECTION),因为每个矩阵运算都在当前矩阵堆栈中进行。

那么对于绘图操作,使用 glMatrixMode(GL_MODELVIEW)。

【讨论】:

这仍然无法帮助我创建一个 4x2 且以 (0,0) 为中心的坐标系。 警告词。 glMatrixMode() 是废弃的功能。 khronos.org/opengl/wiki/Legacy_OpenGL 这与所谓的固定函数管道有关,现在在“现代 OpenGL”中建议您自己计算矩阵并将它们应用到着色器中。【参考方案2】:

您的问题是打印的值与您想要的坐标系不匹配吗?投影 manrix(glOrtho 和朋友)仅对您指定给 openGL 的坐标有影响 - 并且与您的窗口工具包如何将鼠标位置通信回您的应用程序大约为 0。

您可以将 GLUT 提供的窗口坐标取消投影到您想要的格式/坐标系统中。听起来您的 p2w_y 和 p2w_x 函数没有按照您的要求进行编码?

【讨论】:

以上是关于设置正交投影矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

opengl 的投影和正交矩阵

计算机图形学-MVP变换之投影(Projection)变换

openGL - 正交投影矩阵

OpenGL中的正交投影矩阵问题

使用 GLM 正交投影矩阵将三角形顶点放在错误的位置

OpenGL 3+,具有定向光的正交投影