Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (736)
Games in Android Showcase (223)
games submitted by our members
Games in WIP (813)
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 1172 times)
0 Members and 1 Guest are viewing this topic.
Offline 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!
Offline 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 matrix
uniform vec2 offset;      // The entity position

layout (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 410

uniform 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?

Offline KaiHH

JGO Kernel


Medals: 442



« 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 120
uniform 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!
Legends of Yore - The Casual Retro Roguelike
Offline KaiHH

JGO Kernel


Medals: 442



« 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. Smiley

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  
 
 
You cannot reply to this message, because it is very, very old.

 
cybrmynd (117 views)
2017-08-02 12:28:51

cybrmynd (139 views)
2017-08-02 12:19:43

cybrmynd (136 views)
2017-08-02 12:18:09

Sralse (152 views)
2017-07-25 17:13:48

Archive (619 views)
2017-04-27 17:45:51

buddyBro (730 views)
2017-04-05 03:38:00

CopyableCougar4 (1255 views)
2017-03-24 15:39:42

theagentd (1235 views)
2017-03-24 15:32:08

Rule (1213 views)
2017-03-19 12:43:22

Rule (1265 views)
2017-03-19 12:42:17
List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05

SF/X Libraries
by SkyAphid
2017-03-02 06:38:56

SF/X Libraries
by SkyAphid
2017-03-02 06:38:32

SF/X Libraries
by SkyAphid
2017-03-02 06:38:05

SF/X Libraries
by SkyAphid
2017-03-02 06:37:51
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!