将世界保持在视口范围内
Keep world within viewport bounds
我目前正在尝试创建一个2D侧滚动,我目前有我的"世界"绘图(一个大的白色盒子暂时),但我不能找出世界地图的边缘和视口的边缘之间的任何关系,以确保视口总是完全被地图覆盖。
我的基本世界绘制代码是:
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;
}
}
我该如何确保当我使用方向键和视口调整大小时,我不会超越地图的界限(目前为500x50块)?
如果你有一个平面场景(仅限2D),那么使用正交投影变换就足够了。投影变换决定了相机的参数。在当前状态下(使用透视投影),您有一个通常的针孔相机,垂直开口角度为60°。
一个正射影是由它的边定义的。假设你想让相机"看到"向左2个单位,向右3个单位,向上1个单位,向下4个单位。这是可能的,尽管在您的情况下可能不合理。
当前的透视相机上下"看到"大约11.5个单位。相应的宽度可以从窗口尺寸计算(我们不想拉伸图像)。因此,使用以下内容代替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
即可。-1
和1
为znear和zfar平面。这些平面之间的一切都是可见的。其他的都会被切断。但是因为你只有2D内容,所以这应该是不相关的。
在对glTranslatef(camX, camY, -20);
的调用中,将z坐标设置为0。这是不需要的,因为我们有一个正射影视图。
现在,如果您想检查映射是否仍然可见,请执行以下操作。我将展示一个检查左右边界的例子。垂直的情况类似:
//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
之后添加代码,或者当您移动相机时。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- 错误:未在此范围内声明'reverse'
- 并行用于C++17中数组索引范围内的循环
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- C++win32 API创建多个类似视口的窗口
- 不计算一个范围内的完美数
- 使用C++在Qt3D中创建多个视口时出现问题
- 错误:"imread"未在此范围内声明
- 我在范围内未声明的错误类有问题
- 如何在cpp中使用地图显示给定日期范围内(在下面的问题中)的费率?
- 我有一个数组,我想输入一个范围,然后找到范围内所有偶数的总和?
- 未在此范围内声明错误 'xy'
- 创建具有两个视口的Qt3D C++场景,其中显示适当的不同网格
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 命名空间范围内的外部 - GCC vs clang vs msvc
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 如何仅使用 While 循环在给定范围内找到可被 7 整除的计数整数
- Socklen_t未在此范围内声明
- 视口内的 OpenGL 视口
- 将世界保持在视口范围内