Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (595) Games in Android Showcase (169) games submitted by our members Games in WIP (647) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Perspective projection matrix incorrect  (Read 486 times) 0 Members and 1 Guest are viewing this topic.
Troubleshoots

JGO Knight

Medals: 36
Exp: 7-9 months

Damn maths.

 « Posted 2014-02-04 11:53:00 »

I spent most of yesterday debugging because I couldn't implement perspective projection. Anyway, I thought my issue was the fact that my matrix multiplication was incorrect, which I fixed (I then spent an hour this morning fixing orthographic projection). Now I'm having trouble getting perspective projection to work, which I've tried to debug but I'm not sure how to fix it.

Orthographic projection:
 1  2  3  4 `projection.overwrite(new float[] { 2f / width, 0f, 0f, 0f, 0f,      2f / height, 0f, 0f, 0f, 0f, -2f, 0f,      -((x * 2f + width) / width), -((y * 2f + height) / height),      -1f, 1f });`

t = top, b = bottom, l = left, r = right

Debugging results (it works):

Quote
Projection: [0.0025, 0.0, 0.0, 0.0, 0.0, 0.0033333334, 0.0, 0.0, 0.0, 0.0, -2.0, 0.0, -1.0, -1.0, -1.0, 1.0]
Scale: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
Rotation: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
Translation: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]

trsp: [0.0025, 0.0, 0.0, 0.0, 0.0, 0.0033333334, 0.0, 0.0, 0.0, 0.0, -2.0, 0.0, -1.0, -1.0, -1.0, 1.0]
[0.25, 0.33333334, 0.0, -199.0] <--- viewProjection(trsp) * (100, 100, 0, 1)

Perspective projection:
 1  2  3  4 `      projection.overwrite(new float[] { (2f * zNear) / width, 0f, 0f, 0f,            0f, (2f * zNear) / height, 0f, 0f, (2f * x + width) / width,            (2f * y + height) / height, -(-zFar + zNear) / (zFar - zNear),            -1f, 0f, 0f, -(2f * zFar * zNear) / (zFar - zNear), 0f });`

t = top, b = bottom, l = left, r = right, n = zNear, f = zFar

Debugging results - n = 1, f = 100 (nothing is displayed):

Quote
Projection: [0.0025, 0.0, 0.0, 0.0, 0.0, 0.0033333334, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, -2.020202, 0.0]
Scale: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
Rotation: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
Translation: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]

trsp: [0.0025, 0.0, 0.0, 0.0, 0.0, 0.0033333334, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, -2.020202, 0.0]
[0.25, 0.33333334, 199.0, 0.0] <-- I'm guessing it's something to do with the Z or with the W coordinate?

What could the problem be? I'm not really sure what I'm doing wrong. I've tried translating the Z coordinate and extending the far pane, but I see nothing. I'm clearing the depth buffer and I tried enabling depth testing. None of those things worked.

EDIT: I think it must be something to do with the Z coordinate, since when I translate it, the W coordinate changes but nothing is displayed.

Why are all OpenGL tutorials written in Brainf**k?
Gef
 « Reply #1 - Posted 2014-02-04 12:02:50 »

Because we don't see the code around this one, perhaps try disabling other stuffs like lighting, texture...

EDIT : here is a site that gives a well explanation on perspective projection, if that could help.

Troubleshoots

JGO Knight

Medals: 36
Exp: 7-9 months

Damn maths.

 « Reply #2 - Posted 2014-02-04 12:21:59 »

Because we don't see the code around this one, perhaps try disabling other stuffs like lighting, texture...

I've not got anything else enabled. The code:

The viewport is being set as the width and the height of the screen.
This is the render method (it uses my LWJGL wrapper/library). This is the same for orthographic projection (except for clearing depth buffer):
 1  2  3  4  5  6  7  8 `GL.glClearColor(colour);GL.glClear(Buffer.COLOR_DEPTH); // combined colour and depth bufferprogram.attach(); // simply calls glUseProgramprogram.setUniformMatrix4x4("mvp", camera.update()); // calls setUniformMatrix4, the matrix isn't transposedvao.attach();vao.render(Primitive.TRIANGLE_STRIP, 4); // calls glDrawArraysVertexArrayObject.detach();ProgramObject.detach();`

I'm updating my view*Projection uniform variable with this method (you can see the values of the matrices (column major) in my OP), this is the same for orthographic projection:
 1  2  3  4 `   public Matrix4 update() {      return scale.copy().multiply(rotation).multiply(translation)            .multiply(projection);   }`

This is how I'm setting the data for the attribute (it shouldn't really matter since orthographic projection works and uses the same data):
 1  2  3  4  5  6  7  8  9  10 `data = FloatBufferIO.create(0f, 0f, 100f, 0f, 0f, 100f, 100f, 100f);vertices = new BufferObject(Target.ARRAY_BUFFER, data,      Usage.STATIC_DRAW);vao = new VertexArrayObject();vao.attach();vertices.attach();vao.formatAttributeData(program.getAttributeIndex("position"), 2, // enables the attribute & calls glVertexAttribPointer      DataType.SIGNED_FLOAT, false, 8, 0);VertexArrayObject.detach();`

When resized (and when the camera is created), this is called in the PerspectiveCamera class:
 1  2  3  4 `projection.overwrite(new float[] { (2f * zNear) / width, 0f, 0f, 0f,      0f, (2f * zNear) / height, 0f, 0f, (2f * x + width) / width,      (2f * y + height) / height, -(-zFar + zNear) / (zFar - zNear),      -1f, 0f, 0f, -(2f * zFar * zNear) / (zFar - zNear), 0f });`

Sorry if it's unclear. If you want to see anything else just ask.

Edit: This is my matrix multiplication method (it seems to work correctly, judging by the debugging results):
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 `      float m00 = (components[0] * matrix.components[0])            + (components[1] * matrix.components[4])            + (components[2] * matrix.components[8])            + (components[3] * matrix.components[12]);      float m01 = (components[0] * matrix.components[1])            + (components[1] * matrix.components[5])            + (components[2] * matrix.components[9])            + (components[3] * matrix.components[13]);      float m02 = (components[0] * matrix.components[2])            + (components[1] * matrix.components[6])            + (components[2] * matrix.components[10])            + (components[3] * matrix.components[14]);      float m03 = (components[0] * matrix.components[3])            + (components[1] * matrix.components[7])            + (components[2] * matrix.components[11])            + (components[3] * matrix.components[15]);      float m10 = (components[4] * matrix.components[0])            + (components[5] * matrix.components[4])            + (components[6] * matrix.components[8])            + (components[7] * matrix.components[12]);      float m11 = (components[4] * matrix.components[1])            + (components[5] * matrix.components[5])            + (components[6] * matrix.components[9])            + (components[7] * matrix.components[13]);      float m12 = (components[4] * matrix.components[2])            + (components[5] * matrix.components[6])            + (components[6] * matrix.components[10])            + (components[7] * matrix.components[14]);      float m13 = (components[4] * matrix.components[3])            + (components[5] * matrix.components[7])            + (components[6] * matrix.components[11])            + (components[7] * matrix.components[15]);      float m20 = (components[8] * matrix.components[0])            + (components[9] * matrix.components[4])            + (components[10] * matrix.components[8])            + (components[11] * matrix.components[12]);      float m21 = (components[8] * matrix.components[1])            + (components[9] * matrix.components[5])            + (components[10] * matrix.components[9])            + (components[11] * matrix.components[13]);      float m22 = (components[8] * matrix.components[2])            + (components[9] * matrix.components[6])            + (components[10] * matrix.components[10])            + (components[11] * matrix.components[14]);      float m23 = (components[8] * matrix.components[3])            + (components[9] * matrix.components[7])            + (components[10] * matrix.components[11])            + (components[11] * matrix.components[15]);      float m30 = (components[12] * matrix.components[0])            + (components[13] * matrix.components[4])            + (components[14] * matrix.components[8])            + (components[15] * matrix.components[12]);      float m31 = (components[12] * matrix.components[1])            + (components[13] * matrix.components[5])            + (components[14] * matrix.components[9])            + (components[15] * matrix.components[13]);      float m32 = (components[12] * matrix.components[2])            + (components[13] * matrix.components[6])            + (components[14] * matrix.components[10])            + (components[15] * matrix.components[14]);      float m33 = (components[12] * matrix.components[3])            + (components[13] * matrix.components[7])            + (components[14] * matrix.components[11])            + (components[15] * matrix.components[15]);      components[0] = m00;      components[1] = m01;      components[2] = m02;      components[3] = m03;      components[4] = m10;      components[5] = m11;      components[6] = m12;      components[7] = m13;      components[8] = m20;      components[9] = m21;      components[10] = m22;      components[11] = m23;      components[12] = m30;      components[13] = m31;      components[14] = m32;      components[15] = m33;`

Edit2: I'll try transposing the projection matrix, since the page you linked me to has the exact same matrix transposed. It doesn't display, however this is the result:

Quote
Projection: [0.0025, 0.0, 1.0, 0.0, 0.0, 0.0033333334, 1.0, 0.0, 0.0, 0.0, 1.0, -2.002002, 0.0, 0.0, -1.0, 0.0]
Scale: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
Rotation: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
Translation: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
trsp: [0.0025, 0.0, 1.0, 0.0, 0.0, 0.0033333334, 1.0, 0.0, 0.0, 0.0, 1.0, -2.002002, 0.0, 0.0, -1.0, 0.0]
[0.25, 0.33333334, -2.002002, 0.0]

Edit3: Never-mind, that was based on row major order. It gives the exact same matrix. I think that the issue must be related to something else.

Why are all OpenGL tutorials written in Brainf**k?
Troubleshoots

JGO Knight

Medals: 36
Exp: 7-9 months

Damn maths.

 « Reply #3 - Posted 2014-02-04 13:01:06 »

--> -->  -->  -->  -->  -->  -->

That's the last 60 seconds of my life. ^^

The problem: -(-zFar + zNear) / (zFar - zNear).
The solution: -(zFar + zNear) / (zFar - zNear).

FFS@@~#'#;'#;'@~:@{:[';[p';[p#@:@:@:@:{l:[] #;{@~:~{@:?:@:@:@:';[p];[;]-p]=;[]=+{}= ='[];[#';];'[#;
Ten hours of debugging just for that...

Edit: It requires me to translate the camera 1 on the Z axis. Should I add 1 to -(2f * zFar * zNear) / (zFar - zNear)?

Why are all OpenGL tutorials written in Brainf**k?
Gef
 « Reply #4 - Posted 2014-02-04 17:54:24 »

Well done !
(I would not have imagined being so useless )

Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 KaiHH (23 views) 2015-07-07 11:39:58 deepthought (55 views) 2015-06-30 15:39:44 deepthought (58 views) 2015-06-30 15:39:09 deepthought (67 views) 2015-06-30 15:36:52 Za\'Anzabar (45 views) 2015-06-29 05:44:54 TritonDreyja (51 views) 2015-06-24 17:10:40 CopyableCougar4 (53 views) 2015-06-23 00:34:45 BurntPizza (58 views) 2015-06-21 20:36:46 cookiecompiler (100 views) 2015-06-11 15:42:53 cookiecompiler (58 views) 2015-06-11 15:41:14
 princec 31x orangepascal 22x wessles 21x CopyableCougar4 19x EgonOlsen 18x theagentd 18x opiop65 17x BurntPizza 17x ags1 15x nsigma 15x Riven 14x KaiHH 13x KevinWorkman 11x sunburn 11x Jesse 11x SauronWatchesYou 10x
 How Do I Expand My Game?by bashfrog2015-06-14 11:34:43List of Learning Resources2015-05-31 05:37:30Intersection Methodsby Roquen2015-05-29 08:19:33List of Learning Resources2015-05-05 10:20:32How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org