使用OpengGl的2D相机

时间:2016-03-20 14:47:13

标签: c++ opengl camera

我正在用2D编写一个小游戏,我想在他移动时实现一个跟随characacter的摄像机。 不幸的是,通过我的实现,我移动角色时的结果是黑屏......如果你知道我的错误在哪里,你能帮助我吗?我是openGl的新手。

这是我的主要代码代码:

int main(int argc, char** argv) {

glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(300, 350);

glutCreateWindow("Map");
init();
glutDisplayFunc(drawMap);
glutSpecialFunc(specialkeyboard);

glutIdleFunc(moveObjects);
glutMainLoop();
return 0;
}

绘制地图的功能:     void drawMap()     {

//int x=0;
//Initialisation
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(0.0,500.0,0.0,500.0); 
glViewport(0,0,1000,700); 

// drawing the rest of the map //

这里是相机代码,我认为问题来自相机功能。

void camera() {


float left = C.x - (300/2.0); 
float  bottom = C.y - (350/2.0); 

float  right = left + 300;
float  top = bottom + 350;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(left, right, bottom, top); 
glMatrixMode(GL_MODELVIEW);

}

功能特殊键盘:

void specialkeyboard(int key, int x, int y)
{
switch (key) {
    case GLUT_KEY_UP:
        C.y += 2;
        camera();
        break;
    case GLUT_KEY_DOWN:
        C.y -= 2;
        camera();
        break;
    case GLUT_KEY_RIGHT:
        C.x += 2;
        camera();
        break;
    case GLUT_KEY_LEFT:
        C.x -= 2;
        camera();
        break;
}
glutPostRedisplay();
}

非常感谢你的帮助:)

编辑

所以现在问题是地图向错误的方向移动,它与角色一起移动但不跟随他。 (红色圆圈是角色)

主要代码:

int main(int argc, char** argv) {

glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 700);
glutCreateWindow("Map");
init();
glutDisplayFunc(drawMap);
glutSpecialFunc(specialkeyboard);

glutIdleFunc(moveObjects);
glutMainLoop();
return 0;
}

绘制地图:

void drawMap()
{
std::cout << "Debut Drawmap " << std::endl;
//TRY
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D(0.0,500.0,0.0,500.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}

//drawing the map//

// Red circle
C.DrawCircle();
camera();
glutSwapBuffers ();
std::cout << "Fin drawmap " << std::endl;    
}

相机:

  void camera(){  
  glViewport(C.x,0,1000,700);
  }

1 个答案:

答案 0 :(得分:0)

只要您调用了camera()函数,就会应用两个glOrtho()矩阵,这肯定不是您想要的。

固定功能GL会将产品Projection * ModelView应用于您绘制的每个顶点。最初,Projection将成为身份,因此无效,您将ModelView设置为Ortho2D(0.0,500.0,0.0,500.0)

在该状态下绘制时,x=0的顶点坐标将映射到视口的左边缘,x=500将映射到右边的坐标。但是,这只是这种情况,因为GL在应用矩阵后将始终应用视口变换。 Ortho2D实际上做的是创建比例和平移,以便眼睛空间中的视觉效果沿着NDC空间中的所有维度从-1变换为立方体

现在,当您还将投影矩阵设置为ortho时,您将获得以下效果:

ModelView会将x=0转换为-1并将x=500转换为1.然后,应用投影,将基于相机的left映射到-1和{{1}如果您的left + 300C.x当时都为零,则会产生图像缩小到原始大小的1/300和1/350的效果。但是,由于您至少将摄像机位置增加或减少了两个单位 - 现在正好是原始图像区域的大小(由于第一个C.y) - 您可以保证该点不再出现在屏幕上

说了这么多,我可以给出几个建议:

  1. 永远不要将ortho矩阵放在ModelView堆栈上。它并不意味着以这种方式使用。
  2. 只需在投影矩阵上保持一个正交调用,并且取决于您的摄像头位置。
  3. 忘记Ortho2DglMatrixMode等所有内容。自十年以来,GL中的这些已弃用。 OpenGL的现代核心配置文件根本不支持这些功能。如果你现在开始学习OpenGL,那就不用担心上一次在上一个千年中有意义的旧版本了。通过使用可编程管道了解正确的方法。