Java-Gaming.org Hi !
 Featured games (90) games approved by the League of Dukes Games in Showcase (753) Games in Android Showcase (228) games submitted by our members Games in WIP (842) 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
 Should I still use a 4x4 matrix for a 2D game with OpenGL?  (Read 1665 times) 0 Members and 1 Guest are viewing this topic.
sci4me

Junior Devvie

Medals: 1

 « Posted 2017-01-08 06:55:39 »

The title says it all, really. In a 3D game, we use 4x4 matrices for all our transformations. Does this apply to 2D games too or should I use a different size matrix? And, I am using OpenGL. Thanks!
SHC
 « Reply #1 - Posted 2017-01-08 13:36:45 »

Even if it is 2D, you'd need the projection matrix, to project from the world space to the NDC. In case you need a moving camera, then you better go with a matrix, but you can optimize it to use a single vector offset.

Now considering the model matrix (better call it as sprite matrix I think) if all you need is positioning objects, there is no need to use the matrix in the first place, you can just go with a 2D vector.

 1  2  3  4 `uniform mat4 projView;  // AKA the combined camera matrixuniform vec2 offset;      // The entity positionlayout (location = 0) in vec2 position; // The vertex position`

Then you simply multiply it with the projView matrix and get your output in NDC. In case you have rotation (2D rotations are just rotations on the z-axis) so you can get away with a 2D matrix for rotations:

You can simply multiply this matrix with your position to make it rotated. So the final shader might look like this:

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18 `#version 410uniform mat4 projView;uniform vec2 offset;uniform float rotation;layout (location = 0) in vec2 position;void main(){    float sinR = sin(rotation);    float cosR = cos(rotation);    mat2 rot = mat2(cosR, sinR, -sinR, cosR);    vec2 vPos = offset + (rot * position);    gl_Position = viewProj * vec4(vPos, 0.0, 1.0);}`

I however, recommend against this, because it is not that necessary to super optimize the program. The second thing is, I believe that premature optimization is the root of all evil. If your hardware supports a lot of power, why not utilize it?

KaiHH

JGO Kernel

Medals: 511

 « Reply #2 - Posted 2017-01-08 14:29:03 »

Technically, you only ever need a mat3x2 (3 columns x 2 rows) for everything in 2D, because you only need:
- translation (third column)
- scale (upper-left 2x2 submatrix)
- rotation (also upper-left 2x2 submatrix)

Transforming from world-space (which is in 2D) to NDC (which is also in 2D***) only requires 2D scaling and 2D translation, because it is essentially an interval mapping from [left, right] -> [-1, +1] and [bottom, top] -> [-1, +1], so this:

Using the matrix in GLSL:
 1  2  3  4  5  6 `#version 120uniform mat3x2 view;in vec2 position;void main() {    gl_Position = vec4(view * vec3(position, 1.0), 0.0, 1.0);}`

***well, actually it is 3D, but we only care about the Z=0 plane
 Games published by our own members! Check 'em out!
KaiHH

JGO Kernel

Medals: 511

 « Reply #3 - Posted 2017-01-09 12:17:06 »

Latest 1.9.2-SNAPSHOT of JOML now has support for 3x2 matrices via Matrix3x2f specially geared for 2D, so you can get going right away.

Here are some usage examples:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23 `Matrix3x2f m = new Matrix3x2f()// define a view of x in [-10, +10] and y in [-8, +8].// Everything within these bounds is visible on the viewport:.view(-10, +10, -8, +8)// translate model to (2, 3):.translate(2, 3)// rotate model 45 degrees clockwise:.rotate((float)Math.toRadians(45))// and scale-down the model to half its size:.scale(0.5f);// Upload to OpenGL (via LWJGL):FloatBuffer fb = <6 floats>;GL21.glUniformMatrix3x2fv(mat3x2Loc, false, m.get(fb));// or the old way:FloatBuffer fb = <16 floats>;GL11.glLoadMatrixf(m.get4x4(fb));// Convert mouse coordinates (mouseX, mouseY) to world// coordinates for a viewport of (800, 600):float vpw = 800, vph = 600;Vector2f world = new Vector2f();m.unproject(mouseX, vph-mouseY, new int[] {0, 0, vpw, vph}, world);`
Pages: [1]
 ignore  |  Print

 ivj94 (583 views) 2018-03-24 14:47:39 ivj94 (48 views) 2018-03-24 14:46:31 ivj94 (382 views) 2018-03-24 14:43:53 Solater (62 views) 2018-03-17 05:04:08 nelsongames (109 views) 2018-03-05 17:56:34 Gornova (159 views) 2018-03-02 22:15:33 buddyBro (702 views) 2018-02-28 16:59:18 buddyBro (92 views) 2018-02-28 16:45:17 xxMrPHDxx (493 views) 2017-12-31 17:17:51 xxMrPHDxx (733 views) 2017-12-31 17:15:51
 Java Gaming Resourcesby philfrei2017-12-05 19:38:37Java Gaming Resourcesby philfrei2017-12-05 19:37:39Java Gaming Resourcesby philfrei2017-12-05 19:36:10Java Gaming Resourcesby philfrei2017-12-05 19:33:10List of Learning Resourcesby elect2017-03-13 14:05:44List of Learning Resourcesby elect2017-03-13 14:04:45SF/X Librariesby philfrei2017-03-02 08:45:19SF/X Librariesby philfrei2017-03-02 08:44:05
 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