0

I'm trying to set up a working camera in c++ with opengl - I want to implement it by myself, not using glm.

I was trying to find my error for long time now, tried much different approaches but it's not working like it should. vector&matrix are implemented in the framework I got at university (row-major).

I thought, setting the camera at +10 @z-axis and placing the object at the origin should at least show anything. But it's just a blue window. If i just load ViewMatrix*ModelMatrix to the vertex shader, I get a rectangle, which is fine.

I'm not sure if I understand near and far plane right - the values are regarding to the position of the camera, right ? So e.g. having the camera positioned at z=10, and having zn=2 & zf = 20, means that the planes are actually positioned on zn=8 and zf=-10, right ?

void Camera::calcProjMatrix() {

float s = 1.0f / (_alpha * tanf(_beta / 2.0f * M_PI / 180.0f ));
float frustum = _zf - _zn;

_projectionMatrix = matrix<float, 4, 4>(0);
_projectionMatrix._11 = s;
_projectionMatrix._22 = s * _alpha;
_projectionMatrix._33 = -(_zf + _zn) / frustum;
_projectionMatrix._34 = -(2 * _zf * _zn) / frustum;
_projectionMatrix._43 = -1;
}

void Camera::calcViewMatrix() {

vector<float, 3> zAxis = normalize(_pos - _target);
vector<float, 3> xAxis = normalize(cross(_up, zAxis));
vector<float, 3> yAxis = cross(zAxis, xAxis);

vector<float, 4> row1 = vector<float, 4>(xAxis.x, yAxis.x, zAxis.x, 0);
vector<float, 4> row2 = vector<float, 4>(xAxis.y, yAxis.y, zAxis.y, 0);
vector<float, 4> row3 = vector<float, 4>(xAxis.z, yAxis.z, zAxis.z, 0);
vector<float, 4> row4 = vector<float, 4>(-dot(xAxis, _pos), -dot(yAxis, _pos), -dot(zAxis, _pos), 1);

_viewMatrix = matrix<float, 4, 4>();
_viewMatrix = matrix<float, 4, 4>::from_rows(row1, row2, row3, row4);   
}

I'm creating the camera with following parameters:

vector<float, 3> position = vector<float, 3>(0.1f, 0.1f, 10);
vector<float, 3> up = vector<float, 3>(0, 1, 0);
vector<float, 3> target = vector<float, 3>(0, 0, 0);
float beta = 45.0f;
float zn = 2.0f; float zf = 30.0f;
float alpha = 4.0f / 3.0f;

camera = Camera(position, up, target, alpha, beta, zn, zf);

render loop: (modelmatrix is Identity matrix)

matrix<float, 4, 4> mv = camera.getViewMatrix() * cube.getModelMatrix();
matrix<float, 4, 4> mvp = camera.getProjMatrix() * mv;
shader.loadMatrix4f("mvp", GL_TRUE, mvp._m);

vertex shader:

#version 410
layout(location=0) in vec3 position;

uniform mat4 mvp;


void main()
{
    gl_Position = mvp * vec4(position, 1.0f);
}

Thanks for any help!

Mexx Kurz
  • 11
  • 3
  • 2
    Don't do the perspective projection yourself in the vertex shader. You'll get wrong clipping and interpolation results. Have a look here: http://stackoverflow.com/questions/41085117/why-does-gl-divide-gl-position-by-w-for-you-rather-than-letting-you-do-it-your – BDL Dec 22 '16 at 20:58
  • @BDL because of the reason the other Question is so old, i want to ask you here - I've read it 3 times now, but I still don't know how to solve this problem now. The task was to get a working camera with Projection, View and Modelmatrix with glm not allowed - I couldn't manage to do this at the last assignment, so I'm trying really hard to get it working now. Does it mean now that for the told reasons i shouldnt do it at all by myself (what i need to do ^^) or have you meant just not in the vertex shader ? – Mexx Kurz Dec 22 '16 at 21:17
  • @MexxKurz: "*because of the reason the other Question is so old*" Neither mathematics nor GPU hardware has changed since that question and answers were posted. Specifically, he's talking about the division by W part. – Nicol Bolas Dec 22 '16 at 21:46
  • @Nicol Bolas what i meant was: im not posting to the other Question (because 2011), but im posting here, that i do not understand how i can solve this now and ask for help :) – Mexx Kurz Dec 22 '16 at 21:52
  • Sorry, yeah. "perspective projection" should have been "perspective divide". It was not meant as an answer, just as a comment. – BDL Dec 22 '16 at 22:08
  • @BDL ok, but can you pls explain me maybe i 2 to 3 sentences why i shall not do it in the vertex shader, and where then ? sry, i really don't get it why - i'm new to opengl and thought it is the only way to do it there. – Mexx Kurz Dec 22 '16 at 22:16
  • It is done automatically by the gpu after clipping. When you do the perspective divide yourself, points outside of the near-plane will be mirrored and thus the clipped polygon will be wrong. You also get problems with perspective correct interpolation. Look at the answers of the question I linked above, it is explained there in detail. – BDL Dec 22 '16 at 22:19
  • ahhh ok, now i got it, thx a lot !! that means, that the problem must still be in my projection matrix – Mexx Kurz Dec 23 '16 at 11:17
  • because after deleting this row, it still shows a blue window – Mexx Kurz Dec 23 '16 at 11:20
  • you still need gl_Position = pos; what do you have in fragment shader ? btw, glm not allowed - they did force you write all matrix math yourself??? How you declared and passed projection matrix, that's important bit you've missed – Swift - Friday Pie Dec 23 '16 at 12:21
  • . The funny bit about OpenGl matrices is that they are stored in transposed mode, by columns, i.e. it is 4 values of first column, 4 of second, etc. be sure that your data model matches that. i.e. m[1][0] will be second element in memory. default representation becomes that basis axis is a row, not a column. this throws off all math of the canonical rails – Swift - Friday Pie Dec 23 '16 at 12:30
  • @Swift: yes, but this didnt change anything about my blue window, i'm updating how my actual vertex Shader looks like. they gave us a math&vector class where matrix is stored in row major style, so im transposing the MVP matrix at the glUniform4fv -> this is done inside this called function: `shader.loadMatrix4f("mvp", GL_TRUE, mvp._m);' so should be fine right ? fragmentShader is just setting a fixed orange color for testing camera. – Mexx Kurz Dec 23 '16 at 17:49

0 Answers0