I would like to implement a simple example in OpenGL just to test the first perspective view (without using lookAt facility), but it is driving me crazy!
I made a little prototype using Processing (that for this stuff is quite similar to OpenGL), but I got strange behavior when camera start to move!
It's not clear to me which it is the order of transformation (I have already tried all combination ;-))!
I was thinking that it should be simple and a possible solution could be:
- Translate to the position of the camera
- Rotate by angle of the camera
- Translate each object in its position
In my simple example I positioned a box and a grid in the (0, 0, -400), but it doesn't work as expected. When I move camera along the X or Z axis the rotation around Y axis seems to rotate around a wrong center! I'd like to simulate a rotation of the camera around its own Y axis, just like a classic FPS game.
Here my sample code where user can move the camera and rotate (just around Y axis), you can test with Processing or using OpenProcessing. Only the first few lines are relevant to the problem... So it's a very little test!
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;
}
}
}
lookAt
? Does it work then? – Xymostech