First you need your perspective matrix - if you havn't created one here is some code as an example
NSMatrix4Df NSMatrix4Df::getProjectionMatrix(float fovAngle, int screenWidth, int screenHeight, float zNear, float zFar)
float aspectRatio = float(screenWidth) / float(screenHeight);
float zRange = zNear - zFar;
float usefulNum = tanf(DegreesToRadians(fovAngle) / 2.0f);
projMat.value(0,0) = ( 1.0f / (aspectRatio * usefulNum) );
projMat.value(1,1) = ( 1.0f / usefulNum );
projMat.value(2,2) = (-zNear - zFar) / zRange;
projMat.value(2,3) = (2.0f * zFar * zNear) / zRange;
projMat.value(3,2) = 1.0f;
projMat.value(3,3) = 0.0f;
NSMatrix4Df is just a class representation of a 2x2 array (  ) and value(x,y) is the same thing as matrix[x][y].
If you already have your perspective matrix then you need to have a world space transform for each one of your tiles you want drawn on the screen based on their position, scale, and orientation in world space. Here is some showing how to create these tranforms..
NSMatrix4Df NSMatrix4Df::getRotationMatrix(float xAxisAng, float yAxisAng, float zAxisAng)
float xRad = DegreesToRadians(xAxisAng);
float yRad = DegreesToRadians(yAxisAng);
float zRad = DegreesToRadians(zAxisAng);
xRotMat.value(1,1) = cosf(xRad); xRotMat.value(1,2) = -sinf(xRad);
xRotMat.value(2,1) = sinf(xRad); xRotMat.value(2,2) = cosf(xRad);
yRotMat.value(0,0) = cosf(yRad); yRotMat.value(0,2) = -sinf(yRad);
yRotMat.value(2,0) = sinf(yRad); yRotMat.value(2,2) = cosf(yRad);
zRotMat.value(0,0) = cosf(zRad); zRotMat.value(0,1) = -sinf(zRad);
zRotMat.value(1,0) = sinf(zRad); zRotMat.value(1,1) = cosf(zRad);
return zRotMat * yRotMat * xRotMat;
NSMatrix4Df NSMatrix4Df::getTranslationMatrix(float xMove, float yMove, float zMove)
// set the fourth column of the matrix to the translation amount
// the rest of the matrix is the identity matrix
NSMatrix4Df NSMatrix4Df::getScalingMatrix(float scaleX, float scaleY, float scaleZ)
// replace 1s in identity with scaling factors here
identity.value(0,0) = scaleX;
identity.value(1,1) = scaleY;
identity.value(2,2) = scaleZ;
I should also mention that the NSMatrix4Df class initializes the matrix with the identity matrix - as shown below
data = 1.0f; data = 0.0f; data = 0.0f; data = 0.0f;
data = 0.0f; data = 1.0f; data = 0.0f; data = 0.0f;
data = 0.0f; data = 0.0f; data = 1.0f; data = 0.0f;
data = 0.0f; data = 0.0f; data = 0.0f; data = 1.0f;
So now for each tile you want to draw to screen space you need to
multiply projMat * TranslationMat * RotationMat * ScaleMat * (your tiles position in 3d space)
If you had all that then that's great - you can use these tranforms to find clipping space for the screen.
This, by the way, is assuming you dont have a camera in place yet. If you do you need to make sure and insert the camera transform between the projMat and the TranslationMat.
If you have these matrixes you can take the position of your tile in x,y,z,w (for example 2,6,10,1) and multiply it by all of your matrixes. The result will be a four dimensional vector (x,y,z,w). You then need to divide that vector by its w because the opengl pipeline won't be doing it for you.
And now you can check the resulting 4 dimensional vector - if ( x < -1 || x > 1 || y < -1 || y > 1) then don't draw the tile.
Just as an aside - I hope you are using shaders for the draw operations, and then I hope you are using buffers to store your verts and indices. If you are going to have a bunch of the same tiles I would suggest learning about..
glDrawElementsInstanced(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0, translationMatrixes.size());
- drawing your tiles instanced could very well be the way to go here. A lot of advantages. Something to think about.
Edited by EarthBanana, 28 March 2013 - 10:27 PM.