使用Ortho2D移动当前图纸并不适用于GLUT

时间:2016-03-13 22:50:53

标签: c++ opengl graphics glut

我有这个用C ++ / OpenGL做的迷你项目,允许用户使用鼠标在屏幕上绘制形状。

现在我想让用户使用他的键盘左右移动/平移屏幕,让我们说屏幕上有4个形状在不同的地方,我希望他们在#时向左移动34; A"键被按下了。

我已经设法在之前的项目中进行了操作,甚至可以放大/缩小但是在这个程序中有些东西是行不通的,我设法做的最接近的事情是用户创建的所有新形状" A"按下的键位于新位置而不是鼠标位置。

这是我的主要,初始化,显示和键盘代码:

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(W_WIDTH, W_HEIGHT);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("OpenGL Excercise");
    init();
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutPassiveMotionFunc(My_mouse_routine);

    createMenu();

    glutMainLoop();
}


void init()
{
    // Select a clear color
    glClearColor(0.933, 0.933, 0.933, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    gluOrtho2D(0, W_WIDTH, W_HEIGHT, 0);
}

void display() {/* clear all pixels */

    // draw text at the bottom
    char* text_to_draw = "Press right mouse button for menu...";
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0, W_WIDTH, 0, W_HEIGHT);
    glColor3f(0.129, 0.129, 0.129);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glRasterPos2i(10, W_HEIGHT - 15);  // move in 10 pixels from the left and bottom edges
    for (int i = 0; i < (int)strlen(text_to_draw); ++i) {
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, text_to_draw[i]);
    }
    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);



    glFlush();
}

void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
    case 27:
        exit(0);
    case 'A':
    case 'a':
        glMatrixMode(GL_PROJECTION); //start editing the projection matrix
        glLoadIdentity(); //remove current projection
        glPopMatrix();
        gluOrtho2D(1,0,1,0); //create new one
        glPushMatrix();
        glMatrixMode(GL_MODELVIEW); //back to editing the modelview matrix
        glFlush();
    default:
        break;
    }

    glutPostRedisplay();
}

最后这里是一个矩形绘图的例子:

GLfloat colors[][3] = { { 0.957f, 0.263f, 0.212f },{ 0.298f, 0.686f, 0.314f },{ 0.129f, 0.588f, 0.953f }, };
static int col = 0;

glColor3f(colors[col][0], colors[col][1], colors[col][2]);
glBegin(GL_POLYGON);
glVertex3f(mouse_x - 50, mouse_y - 50, 0.0);
glVertex3f(mouse_x + 50, mouse_y - 50, 0.0);
glVertex3f(mouse_x + 50, mouse_y + 50, 0.0);
glVertex3f(mouse_x - 50, mouse_y + 50, 0.0);
glEnd(); /* don't wait!!! start processing buffered OpenGL routines */

col += 1;

if (col == sizeof(colors) / sizeof(colors[0])) {
    col = 0;
}

glutPostRedisplay();

我知道在这个网站和其他数百个网站上有很多关于这个问题的问题,我几乎肯定它与矩阵有关,但我不知道我做错了什么

1 个答案:

答案 0 :(得分:1)

  1. 为什么要更改A按键上的投影矩阵?

    我假设您想要使用 WSAD (这对于像我这样的老派 OPQAM 这些人来说极为不舒服)来平息观点。

    第一个问题是,您在GL_PROJECTION按键上更改了A,但在display()渲染时重置了该按键,使按键代码无效。要解决这个问题,您应该在GL_PROJECTION函数中初始化init()。顺便说一句,您遗失了glMatrixMode并将其从display()中移除。

    另一个问题是你在GL_PROJECTION内使用了相机/视图矩阵,而不是GL_MODELVIEW,它被称为:

    当您使用高级照明和雾时(除非您切换到 GLSL ),这将导致您出现严重问题。

    最后,当您通过ortho设置视图时,您应该只使用glTranslate进行平移。这至少是我的意见。

  2. 您的场景存储在哪里?

    从你的文字中我假设这应该是一些简单的矢量绘画,比如能够在场景中添加/绘制形状的编辑器。所以你需要有一些能够存储你场景的所有信息的列表,如:

    • 对象类型
    • 控制点
    • 颜色

    我没有在你的代码中看到这样的信息,而是我看到直接使用鼠标坐标,这对于最后添加的点的预览是好的,但是对于更复杂的形状(例如直线)将会失败。

    这里看看:

    了解如何做到这一点。