So basically I'm trying to make a simple open gl 3D graphics engine using my own linear algebra to make projection and transformation matrices. OpenGL has a class called glUniformMatrix4fv()
which I use to pass the matrices as a float[].
Here is my "Matrix" class to construct a float[] for that openGl method:
private float[] m= {
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};
public Matrix() {}
public Matrix(float[] m) {
this.m=m;
}
//gets value at x,y coords of matrix
public float getValue(int x,int y) {
return m[y*4 + x];
}
//sets value of x,y coord to n
public void setValue(int x,int y,float n) {
m[y*4 + x]=n;
}
To construct a transformation for object translation and rotation I first create translation Matrix (s is for scale). Also a vertex is basically just a size 4 float array I have my Vector/vertex info in:
public Matrix createTranslationMatrix(Vertex pos,float s) {
Matrix m=new Matrix();
m.setValue(0,0,s);
m.setValue(1,1,s);
m.setValue(2,2,s);
m.setValue(3,0,pos.getValue(0));
m.setValue(3,1,pos.getValue(1));
m.setValue(3,2,pos.getValue(2));
return m;
}
Then I create a rotation matrix which is a combo of x, y, and z rotation of object around origin
public Matrix createRotationMatrix(Vertex rot) {
//if rotation is screwed up maybe mess around with order of these :)
Matrix rotX=createRotationMatrixX(rot.getValue(0));
Matrix rotY=createRotationMatrixY(rot.getValue(1));
Matrix rotZ=createRotationMatrixZ(rot.getValue(2));
Matrix returnValue=multiply(rotX,rotY);
returnValue=multiply(returnValue,rotZ);
return returnValue;
}
private Matrix createRotationMatrixX(float num) {
float n=num;
n=(float)Math.toRadians(n);
Matrix rot=new Matrix();
rot.setValue(1, 1, (float)Math.cos(n));
rot.setValue(1, 2, (float)Math.sin(n));
rot.setValue(2, 1, (float)-Math.sin(n));
rot.setValue(2, 2, (float)Math.cos(n));
return rot;
}
//rotation mat Y
private Matrix createRotationMatrixY(float num) {
float n=num;
n=(float)Math.toRadians(n);
Matrix rot=new Matrix();
rot.setValue(0, 0, (float)Math.cos(n));
rot.setValue(0, 2, (float)-Math.sin(n));
rot.setValue(2, 0, (float)Math.sin(n));
rot.setValue(2, 2, (float)Math.cos(n));
return rot;
}
//rotation mat Z
private Matrix createRotationMatrixZ(float num) {
float n=num;
n=(float)Math.toRadians(n);
Matrix rot=new Matrix();
rot.setValue(0, 0, (float)Math.cos(n));
rot.setValue(0, 1, (float)Math.sin(n));
rot.setValue(1, 0, (float)-Math.sin(n));
rot.setValue(1, 1, (float)Math.cos(n));
return rot;
}
I combine the translation and create my objectTransform
float[] using a matrix with multiply(rotationMat,translationMat):
public Matrix multiply(Matrix a, Matrix b){
Matrix m=new Matrix();
for(int y=0;y<4;y++) {
for(int x=0;x<4;x++) {
//if this doesn't work maybe try switching x and y around?
m.setValue(x,y,a.getValue(x,0)*b.getValue(0,y) + a.getValue(x,1)*b.getValue(1,y) + a.getValue(x,2)*b.getValue(2,y) + a.getValue(x,3)*b.getValue(3, y));
}
}
return m;
}
And my code for my worldTransorm
is defined from by combining a transformation with negative values for position and rotation (so it moves vertex and rotates opposite from camera position and rotation), then combinging rotation and transformation like so multiply(translationMat,rotationMat) , so it theoretically moves opposite camera pos, THEN rotates opposite camera rotation.
then I create my projection
using this function:
public Matrix createProjectionMatrix(float fov, float aspectRatio, float near, float far) {
float fovRad=1/(float)Math.tan(Math.toRadians(fov*.5));
Matrix projection=new Matrix(base);
projection.setValue(0,0,aspectRatio*fovRad);
projection.setValue(1,1,fovRad);
projection.setValue(2,2,far/(far-near));
projection.setValue(2,3,(-far*near)/(far-near));
projection.setValue(3,2,1);
projection.setValue(3,3,0);
return projection;
}
I combine my projection
, worldTransform
, and objectTransform
with my Vec3 position
(vector with mesh coordinates I import). These are all multiplied together in my openGL shader class like so:
gl_Position=projection * worldTransform * objectTransform * vec4(position,1);
Write now if I back my camera up by 3, rotate it around with hopes of finding the "triangle" mesh I made
float[] verts= {
//top left tri
-.5f,-.5f,0,
0,.5f,0,
.5f,-.5f,0,
};
Then I get a really small pixel moving really fast accross my screen from top to bottom. I also have the object spinning, but that (if my code worked properly) shouldn't be an issue, but if I don't have the object spinning, then I don't see any pixel at all. So my thinking is the object transformation is applying like the world transormation should be working, moving the vertex by "translation" then rotating it, or the triangle is really small and not scaled properly (do I have to offset it somehow?), but then it shouldn't be flying off the screen repeatedly as if its rotating around the camera. I've tried switching multiplication of translation and rotation for both types of transforms, but either the triangle doesn't appear at all or I just see a teensy tiny little pixel, almost orbitting the camera at high speeds (when I should see just the triangle and camera rotating seperately)
I know its a lot to ask but what am I doing wrong? Do I need to transpose something? Is my projection matrix out of wack? I feel like everything should be right :(