我目前正在尝试创建一个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
之后添加代码,或者当您移动相机时。