Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (522)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (590)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Perspective projection matrix incorrect  (Read 298 times)
0 Members and 1 Guest are viewing this topic.
Offline 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?
Offline 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.

Offline 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 buffer
program.attach(); // simply calls glUseProgram
program.setUniformMatrix4x4("mvp", camera.update()); // calls setUniformMatrix4, the matrix isn't transposed
vao.attach();
vao.render(Primitive.TRIANGLE_STRIP, 4); // calls glDrawArrays
VertexArrayObject.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?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Troubleshoots

JGO Knight


Medals: 36
Exp: 7-9 months


Damn maths.


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

 Clueless --> Emo -->  Cranky -->  Stare -->  Shocked -->  Grin -->  Angry Angry Angry Angry -->  Cool

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:[] Angry#;{@~:~{@:?:@:@:@:';[p];[;]-p]=;[]=+{}= Angry='[];[#';];'[#;
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?
Offline Gef
« Reply #4 - Posted 2014-02-04 17:54:24 »

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

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

trollwarrior1 (27 views)
2014-11-22 12:13:56

xFryIx (69 views)
2014-11-13 12:34:49

digdugdiggy (48 views)
2014-11-12 21:11:50

digdugdiggy (42 views)
2014-11-12 21:10:15

digdugdiggy (36 views)
2014-11-12 21:09:33

kovacsa (60 views)
2014-11-07 19:57:14

TehJavaDev (64 views)
2014-11-03 22:04:50

BurntPizza (62 views)
2014-11-03 18:54:52

moogie (77 views)
2014-11-03 06:22:04

CopyableCougar4 (77 views)
2014-11-01 23:36:41
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!