problem (picture explains)

Started by
13 comments, last by Kasya 13 years, 11 months ago
the object is on the line when camera is near as shown below (2 screenshots): Screenshot #1 Screenshot #2 when i move the moves back the object is like goes away from the line: Screenshot #3 I think the problem is projection matrix. Here is the source:
void Viewport::Perspective(real fov, uint w, uint h, real n, real f) {
		
		real range = Math::cot(Math::deg2rad(fov / 2));
		real aspect = (real) w / h;
		
		projectionMatrix.row[0] = range / aspect;
		projectionMatrix.row[5] = range;
		projectionMatrix.row[10] = (f + n) / (n - f);
		projectionMatrix.row[11] = (2 * n * f) / (n - f);
		projectionMatrix.row[14] = -1;
				
}

void Prerequisites() {
	currentCamera = &cameras[current];
	cameras[0].setPosition(Vector3(0, 1.5f, 7.0f), Vector3(1.0f, 1.0f, 0.0f));
	viewport.Perspective(60.0f, 640, 480, 1, 10.0f);
}

void Render() {

currentCamera->Look();

modelviewprojection = viewport.getProjectionMatrix() * currentCamera->getModelViewMatrix();

GPUProgramManager::Instance().BindProgram("helloworld.gpu");
GPUProgramManager::Instance().setUniformMatrix("helloworld.gpu", "modelViewProjection", modelviewprojection.row);

box->draw(); //just skipped that part because it drew correctly when used to use gluPerspective

GPUProgramManager::Instance().UnbindProgram();

//floor draw, octree bounds draw

}




and here is the shader:


[VertexShader]

#version 130

in vec3 POSITION;
uniform mat4 modelViewProjection;

void main() {	
			
	gl_Position = modelViewProjection * vec4(POSITION, 1.0);

}

[FragmentShader]

#version 130

out vec4 myfragcolor;

void main() {

	myfragcolor = vec4(0.0, 0.0, 0.0, 1.0);
	
}





Please Help! Thanks, Kasya
Advertisement
1. Your 'perspective' function only sets a few of the matrix elements. What are the other elements set to? Are they assumed already to be set to identity?

2. Are you sure you have all your conventions right? Is the matrix 'majorness' correct? Your matrix multiplication order suggests that column vectors are being used - are your transform functions set up accordingly? Are you using the right z-clipping range for OpenGL ([-1, 1])?
Quote:1. Your 'perspective' function only sets a few of the matrix elements. What are the other elements set to? Are they assumed already to be set to identity?


Yes they are.

Quote:2. Are you sure you have all your conventions right? Is the matrix 'majorness' correct? Your matrix multiplication order suggests that column vectors are being used - are your transform functions set up accordingly? Are you using the right z-clipping range for OpenGL ([-1, 1])?


My Matrix is Column Major. And the transform functions are setup correctly. Here is the code for multiplication

Matrix &Matrix::operator*=(const Matrix &m) {	for (int i = 0; i < 16; i+=4) {					for (int j = 0; j < 4; j++) {							row = row * m.row[ <span class="cpp-number">0</span> + j ] + row * m.row[ <span class="cpp-number">4</span> + j ] +<br>												row * m.row[ <span class="cpp-number">8</span> + j ] + row * m.row[ <span class="cpp-number">12</span> + j ];<br>			}<br>			<br>	}<br><br>	<span class="cpp-keyword">return</span> *<span class="cpp-keyword">this</span>;<br><br>}<br><br></pre></div><!–ENDSCRIPT–><br><br>I really don't know about the z-clipping range. Could this be the problem?
Why does this line have the word row in it?
setUniformMatrix("helloworld.gpu", "modelViewProjection", modelviewprojection.row)

Have you tried using the built in functionality with your shader and matrices independently?

For example, does your projection matrix code swap out unitly with the gluPerspective function?

Does your view and model transform work the same way?
Then when you combine them does it work with glMultMatrixf?
Lastly does it work when you pass it directly to shader? No :)

Edit: I guess i assume that row is a float row[16]; In which case you're probably borked because it's expecting a column major matrix, which means that the memory is stored in column order. So the first 4 floats are the first column. If anything your float data member should be called column, or the function through which you get it should say ToColumnMajor( ).
Quote:For example, does your projection matrix code swap out unitly with the gluPerspective function?


i really don't understand what you mean. if you mean that projection matrix and gluPerspective results they are not the same. I can't FEEL the result with my proj.mat than with gluPerspective.

Quote:Does your view and model transform work the same way?


i actually don't have 2 different matrices. i just have camera which calculates modelview immediately. Yes it works with glMultMatrixf. But can't feel result here too.
It's strange that you measure success with feelings. It aught to _look_ the same IMO.

Anyways, what i meant by the first question (does your projection code swap out with gluPerspective) is simply suggesting unit testing.

Download a NEHE tutorial that renders a simple 3d scene. Somewhere in that code is a call to gluPerspective, if you just replace that call with glMultMatrixf( GL_PERSPECTIVE_MATRIX, yourMatrix.row), there should be no visual difference.

That would be the first step in testing your projection matrix creation code. Alternatively you can return the matrix created by gluPerspective and inspect it element by element with the one created by your code.

Repeat this process for both gluLookAt and model transformations.
You didn't post your binary * operator, but if I'm not mistaken, your *= operator is implemented incorrectly (it looks to me like you're overwriting the elements of this as you go).
I think it could be your matrix multiplication. When I implemented mine I know I had to store a copy of the current matrix to use for the calculations before writing to the current matrix (but I don't know for sure, maybe I missed some opportunity for efficiency somewhere).
Quote:Original post by Kasya
Here is the code for multiplication


... yeah, usually you write the operator*= "long-hand" and implement operator* in terms of that. But for matrix multiplication that doesn't work so well. The problem is that elements that you calculate - and assign to - earlier in the process get used for calculating elements later in the process, using the newly assigned values, which messes everything up.

So the easiest thing is to just do it the other way around:

Matrix Matrix::operator*(const Matrix &m) {	Matrix result;	for (int i = 0; i < 16; i+=4) {				for (int j = 0; j < 4; j++) {						result.row = row * m.row[ <span class="cpp-number">0</span> + j ] + row * m.row[ <span class="cpp-number">4</span> + j ] +<br>												row * m.row[ <span class="cpp-number">8</span> + j ] + row * m.row[ <span class="cpp-number">12</span> + j ];<br>		}	<br>	}<br>	<span class="cpp-keyword">return</span> result;<br>}<br><br>Matrix&amp; Matrix::<span class="cpp-keyword">operator</span>*=(<span class="cpp-keyword">const</span> Matrix&amp; m) {<br>	Matrix tmp = *<span class="cpp-keyword">this</span> * m;<br>	*<span class="cpp-keyword">this</span> = tmp;<br>	<span class="cpp-keyword">return</span> *<span class="cpp-keyword">this</span>;<br>}<br><br></pre></div><!–ENDSCRIPT–> 
Im soo sorry. I just copied the wrong code:

Matrix Matrix::operator*(const Matrix &m) const {	return Matrix(	row[0] * m.row[0] + row[4] * m.row[1] + row[8] * m.row[2] + row[12] * m.row[3],	row[1] * m.row[0] + row[5] * m.row[1] + row[9] * m.row[2] + row[13] * m.row[3],	row[2] * m.row[0] + row[6] * m.row[1] + row[10] * m.row[2] + row[14] * m.row[3],	row[3] * m.row[0] + row[7] * m.row[1] + row[11] * m.row[2] + row[15] * m.row[3],	row[0] * m.row[4] + row[4] * m.row[5] + row[8] * m.row[6] + row[12] * m.row[7],	row[1] * m.row[4] + row[5] * m.row[5] + row[9] * m.row[6] + row[13] * m.row[7],	row[2] * m.row[4] + row[6] * m.row[5] + row[10] * m.row[6] + row[14] * m.row[7],	row[3] * m.row[4] + row[7] * m.row[5] + row[11] * m.row[6] + row[15] * m.row[7],		row[0] * m.row[8] + row[4] * m.row[9] + row[8] * m.row[10] + row[12] * m.row[11],	row[1] * m.row[8] + row[5] * m.row[9] + row[9] * m.row[10] + row[13] * m.row[11],	row[2] * m.row[8] + row[6] * m.row[9] + row[10] * m.row[10] + row[14] * m.row[11],	row[3] * m.row[8] + row[7] * m.row[9] + row[11] * m.row[10] + row[15] * m.row[11],	row[0] * m.row[12] + row[4] * m.row[13] + row[8] * m.row[14] + row[12] * m.row[15],	row[1] * m.row[12] + row[5] * m.row[13] + row[9] * m.row[14] + row[13] * m.row[15],	row[2] * m.row[12] + row[6] * m.row[13] + row[10] * m.row[14] + row[14] * m.row[15],	row[3] * m.row[12] + row[7] * m.row[13] + row[11] * m.row[14] + row[15] * m.row[15]	);}


And yes. I fixed the *= issue. Now im going to check these projection and modelview matrices to see whats going on there. I'll let you know :)

Thanks,
Kasya

This topic is closed to new replies.

Advertisement