我想在 OpenGL 中实现一个简单的例子来测试第一个透视图(不使用lookAt 工具),但这让我发疯!
我使用Processing制作了一个小原型(这个东西与OpenGL非常相似),但是当相机开始移动时我得到了奇怪的行为!
我不清楚这是转换的顺序(我已经尝试过所有组合;-))!
我在想它应该很简单,一个可能的解决方案可能是:
- 平移到相机的位置
- 按相机角度旋转
- 平移每个对象的位置
在我的简单示例中,我在 (0, 0, -400) 中放置了一个框和一个网格,但它没有按预期工作。当我沿 X 或 Z 轴移动相机时,围绕 Y 轴的旋转似乎围绕错误的中心旋转!我想模拟相机围绕自己的 Y 轴旋转,就像经典的 FPS 游戏一样。
这是我的示例代码,用户可以移动相机并旋转(仅围绕 Y 轴),您可以使用 Processing 或使用OpenProcessing进行测试。只有前几行与问题相关......所以这是一个非常小的测试!
float cameraXPos = 0;
float cameraYPos = 0;
float cameraZPos = 0;
float cameraYAngle = 0;
float moveIncrement = 5;
float angleIncrement = 5;
// Keys:
// W
// ^
// |
// A <- -> D
// |
// V
// S
//
// F and R for Z+/Z-
// O and P for rotation around Y axis
void setup()
{
size(640, 480, OPENGL);
resetCameraPos();
}
// Reset camera
void resetCameraPos()
{
cameraXPos = width / 2;
cameraYPos = height / 2;
cameraZPos = (height /2 ) / tan(PI/6);
cameraYAngle = 0;
}
void draw()
{
// Clear screen
background(0);
// View transform
translate(cameraXPos, cameraYPos, cameraZPos);
rotateY(radians(cameraYAngle));
// World transform
translate(0, 0, -400);
// Draw a red box and a grid in the center
stroke(255, 0, 0);
noFill();
box(100);
drawGrid();
// Check if user is pressing some key and update the camera position
updateCameraPos();
}
/////////////////////////////////////////////////////////////////////
// The following part is not so relevant to the problem (I hope! ;-))
/////////////////////////////////////////////////////////////////////
void drawGrid()
{
// Draw a white grid (not so important thing here!)
stroke(255, 255, 255);
float cellSize = 40;
int gridSize = 10;
float cY = 100;
for(int z = 0; z < gridSize; z++)
{
float cZ = (gridSize / 2 - z) * cellSize;
for(int x = 0; x < gridSize; x++)
{
float cX = (x - gridSize / 2) * cellSize;
beginShape();
vertex(cX, cY, cZ);
vertex(cX + cellSize, cY, cZ);
vertex(cX + cellSize, cY, cZ - cellSize);
vertex(cX, cY, cZ - cellSize);
vertex(cX, cY, cZ);
endShape();
}
}
}
// Just update camera position and angle rotation
// according to the pressed key on the keyboard
void updateCameraPos()
{
if (keyPressed)
{
switch(this.key)
{
case 'w': // Y++
cameraYPos += moveIncrement;
break;
case 's': // Y--
cameraYPos -= moveIncrement;
break;
case 'a': // X--
cameraXPos += moveIncrement;
break;
case 'd': // X++
cameraXPos -= moveIncrement;
break;
case 'r': // Z++
cameraZPos += moveIncrement;
break;
case 'f': // Z--
cameraZPos -= moveIncrement;
break;
case ' ': // RESET
resetCameraPos();
break;
case 'o': // Angle++
cameraYAngle += angleIncrement;
break;
case 'p': // Angle--
cameraYAngle -= angleIncrement;
break;
}
}
}