gpt4 book ai didi

c++ - 将世界保持在视口(viewport)范围内

转载 作者:行者123 更新时间:2023-11-28 07:01:39 27 4
gpt4 key购买 nike

我目前正在尝试创建一个 2D 横向滚动条,并且我目前有我的“世界”绘图(暂时是一个大白框),但我无法弄清楚世界地图的边缘与边缘之间的任何关系确保视口(viewport)始终完全被 map 覆盖。

我的基本世界绘图代码是:

void drawTiles(void)
{
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 500; j++)
{
glPushMatrix();
glTranslatef(j, -i, 0);

glBegin (GL_QUADS);
glTexCoord2d(0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);

glTexCoord2d(1.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);

glTexCoord2d(1.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);

glTexCoord2d(0.0, 1.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
glPopMatrix();
}
}
}

void display(void)
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
glEnable(GL_TEXTURE_2D);

glPushMatrix();
glTranslatef(camX, camY, -20); //translate back a bit to view the map correctly (our camera)

drawTiles(); //draw our tiles

glPopMatrix();

glutSwapBuffers();
}

void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
camY -= 0.25;
break;
case 's':
camY += 0.25;
break;
case 'a':
camX += 0.25;
break;
case 'd':
camX -= 0.25;
break;
}
}

我如何确保当我使用 WASD 和视口(viewport)调整大小时,我不会翻译超出 map 的边界(当前为 500x50 tiles)?

最佳答案

如果您有一个平面场景(仅限 2D),使用正交投影变换应该就足够了。投影变换决定了相机的参数。在当前状态下(使用透视投影),您有一个垂直打开角度为 60° 的普通针孔相机。

正交投影由其边定义。假设您希望相机“看到”左侧两个单位、右侧 3 个单位、上方 1 个单位和下方 4 个单位。这是可能的,尽管在您的情况下可能不合理。

当前的透视相机上下“看到”大约 11.5 个单位。可以根据窗口尺寸计算相应的宽度(我们不想拉伸(stretch)图像)。因此,不要使用 gluPerspective,而是使用以下内容:

float halfHeight = 11.5f;
float halfWidth = halfHeight * (GLfloat)w / (GLfloat)h; //based on window aspect ratio
glOrtho(-halfWidth, halfWidth, halfHeight, -halfHeight, -1, 1);

如果要改变可见区域,只需要调整halfHeight即可。 -11 是 znear 和 zfar 平面。这些平面之间的一切都是可见的。其他一切都将被切断。但由于您只有 2D 内容,因此这应该不相关。

在调用 glTranslatef(camX, camY, -20); 时,将 z 坐标设置为 0。不再需要这样做,因为我们有一个正交 View 。

现在,如果您想检查 map 是否仍然可见,请执行以下操作。我将仅展示检查左/右边界的示例。垂直情况类似:

//The camera can see from camX-halfWidth to camX+halfWidth
//You might want to make halfWidth and halfHeight class variables
float leftMapBoundary = 0;
float rightMapBoundary = 500;
//the camera must be
// * at least halfWidth right of the left boundary and
// * at least halfWidth left of the right one:
if(camX < leftMapBoundary + halfWidth)
camX = leftMapBoundary + halfWidth;
if(camX > rightMapBoundary - halfWidth)
camX = rightMapBoundary - halfWidth;

在键盘功能的 switch 之后或移动相机时添加代码。

关于c++ - 将世界保持在视口(viewport)范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22379988/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com