使用鼠标在OpenGL中移动绘图

3

我正在尝试在按住鼠标左键的情况下在openGL中移动一张图片。 我不是要拖动一个对象,只是移动整个图片。它是一个二维分形的绘图,我被告知可以使用gluOrtho2D,但我找不到任何关于如何实现它的信息或类似的尝试。 我猜想应该像这样:

void mouse_callback_func(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    gluOrtho2D(x-250.0, x+250.0, y-250.0,y+250.);
glutPostRedisplay();
}  

我想让一个500x500像素的窗口,但它不起作用。我一左键点击窗口就会变成空白。有什么办法吗?


也许发生了溢出,导致图片超出屏幕?虽然我不知道答案,但这应该有助于您调试问题。在mouse_callback_func()中,在提示符上打印x和y的值。 一旦您获得这个值,请将它们替换为gluOrtho2D(x-250.0, x+250.0, y-250.0,y+250.);并正常渲染图像(现在不要使用鼠标)。检查图片是否正确地呈现在屏幕上。我假设它不会,然后您可以尝试减少/增加值以检查哪些范围的x/y值将呈现到您的视口。 - viktorzeid
你的初始预测是什么? - jozxyqk
我尝试过了,但是没有起作用。我甚至降低到 x-1、x+1、y-1、y+1 的程度来看会发生什么事情,但屏幕仍然变空白了。 - Deadalus
1个回答

2

gluOrtho2D修改当前矩阵。它通常与glMatrixMode(GL_PROJECTION)一起使用,例如:

glMatrixMode(GL_PROJECTION); //start editing the projection matrix
glLoadIdentity(); //remove current projection
gluOrtho2D(...); //create new one
glMatrixMode(GL_MODELVIEW); //back to editing the modelview matrix

设置摄像机概念可能更简单...

float cameraX, cameraY;
int lastMouseX, lastMouseY;

void mouse_callback_func(int button, int state, int x, int y)
{
    int dx = x - lastMouseX;
    int dy = y - lastMouseY;
    const float speed = 0.1f;
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        cameraX += dx * speed; //or -=, depending on which direction feels more natural to you
        cameraY -= dy * speed; //-= as mouse origin is top left, so +y is moving down
        glutPostRedisplay();
    }
    lastMouseX = x;
    lastMouseX = y;
}

void display()
{
    glLoadIdentity(); //remove transforms from previous display() call
    glTranslatef(-cameraX, -cameraY, 0.0f); //move objects negative = move camera positive
    ...

我被告知这正是gluortho2d可以做到的。而不是实际移动我的图片,我可以改变视窗(即移动相机)。并且我被要求特别使用gluortho2d来完成它:S - Deadalus
我玩弄了一下 glMatrixMode(GL_PROJECTION) 等等。但是我完全无法理解的是,即使我包含 postredisplay,仍然需要不断地重绘。当我按住鼠标左键拖动时,什么也没有发生,然后我必须右键单击并选择一个数字(在右键单击时,您可以更改组成图像的随机点数)。 - Deadalus
可以使用投影矩阵来“移动相机”,但如果引入光照,则无法正常工作。OpenGL没有相机的概念。唯一的方法是移动场景中的所有内容。考虑上面的glTranslatef-通过将场景中的所有内容向左移动,相机向右移动。这就是相机的实现方式。您还可以添加glRotatef以使相机旋转。gluLookAt是一个方便的函数,直到您掌握自己进行矩阵变换的技巧。 - jozxyqk
关于重绘,@Deadalus,请问右键单击代码的作用是什么,会导致重新绘制吗?尝试在所有函数中添加打印语句-查看它们何时被调用。也许可以尝试将glutPostRedisplay放入空闲函数甚至显示函数本身中,以强制进行连续更新的测试。 - jozxyqk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接