Hello Guest

[Solved] Orthogonal Matrix using Vertex/Fragment shaders Problem

  • 10 Replies
  • 6729 Views
I've been stuck on one problem for weeks - creating a matrix which projects my two triangles drawn. I am making a 2D game.

I have fiddled with the vertex coordinates and that doesn't do anything when my projection is being multiplied on the matrix stack.

Affected Files:
  • Main
  • Shader
  • ShaderModel
  • DefaultShader
  • ModelLoader
  • Model
  • Element
  • Renderer
  • Projection
  • res/shader/default.v
  • res/shader/default.f
  • res/texture/example.png


Quote
Attempting to use 'Windows' from native folder.
Using OpenGL Version: 3.1.0 - Build 9.17.10.3040
Using Shader Version: 1.40 - Intel Build 9.17.10.3040

This is my project. It was written in Eclipse. This is the project folder you can just import and play.
http://www.mediafire.com/download/1ptluo03vw3g6f4/2D_Game.zip

I am trying to define pixel space. I rooted my problem specifically to the orthogonal matrix.

This is what I use to create the projection matrix.
Code: [Select]
final Matrix4f projection = Projection.createOrtho(0f, (float) window.getWidth(), 0f, (float) window.getHeight(), 0.1f, 100f);
Code: [Select]
GL11.glViewport(-400, -300, 800, 600);
Vertex Shader:
Code: [Select]
#version 400 core

in vec3 position;
in vec2 texcoord;

out vec2 pass_texcoord;

uniform mat4 matrix_transform;
uniform mat4 matrix_projection;
uniform mat4 matrix_camera;

void main(void) {
pass_texcoord = texcoord;
gl_Position = matrix_projection * matrix_camera * matrix_transform * vec4(position.x, position.y, position.z, 1.0);
}

Fragment Shader:
Code: [Select]
#version 400 core

in vec2 pass_texcoord;

out vec4 out_Color;

uniform sampler2D u_texture;

void main(void) {
out_Color = texture(u_texture, pass_texcoord);
}

My shaders compile perfectly. They also run. Everything is all fine and dandy when I take out my projection matrix. I have successfully drawn my two triangles into a quad.

This is my model. The first table are verticies, the second table are texture coordinates (which go fine), and the last is the indices.

Code: [Select]
final Model model = ModelLoader.loadModel(
new float[] {
0, 10f, //should we convert this to different?
0, 0,
10f, 0,
10f, 10f
}, new float[] {
0, 0,
0, 1,
1, 1,
1, 0
}, new int[] {0, 3, 1, 1, 3, 2});

public static Model loadModel(float[] positions, float[] texture_coords, int[] indicies) {
final int vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
final int[] vbos = new int[4];
vbos[0] = store(0, 2, positions);
vbos[1] = store(1, 2, texture_coords);
vbos[2] = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vbos[2]);
final IntBuffer ib = BufferUtils.createIntBuffer(indicies.length);
ib.put(indicies);
ib.flip();
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, ib, GL15.GL_STATIC_DRAW);
GL30.glBindVertexArray(0);
final Model m = new Model(vao, vbos, indicies.length);
Models.add(m);
return m;
}

public static int store(int id, int len, float[] fltarr) {
final int vbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
final FloatBuffer fb = BufferUtils.createFloatBuffer(fltarr.length);
fb.put(fltarr);
fb.flip();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, fb, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(id, len, GL11.GL_FLOAT, false, 0, 0);
return vbo;
}

This is the ortho setup I have.

Code: [Select]
public static Matrix4f createOrtho(float left, float right, float bottom, float top, float near, float far) {

final Matrix4f matrix = new Matrix4f();
matrix.setIdentity();

matrix.m00 = 2.0f / (right - left);
matrix.m01 = 0;
matrix.m02 = 0;
matrix.m03 = 0;
matrix.m10 = 0;
matrix.m11 = 2.0f / (top - bottom);
matrix.m12 = 0;
matrix.m13 = 0;
matrix.m20 = 0;
matrix.m21 = 0;
matrix.m22 = -2.0f / (far - near);
matrix.m23 = 0;
matrix.m30 = -(right + left) / (right - left);
matrix.m31 = -(top + bottom) / (top - bottom);
matrix.m32 = -(far + near) / (far - near);
matrix.m33 = 1;

return matrix;
}

I see nothing on screen whatsoever. Not even 1 pixel drawn.

This is how I actually draw.
Code: [Select]
final Model model = e.getModel();
final ShaderModel shader = e.getShader();
GL30.glBindVertexArray(model.getVao());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glUseProgram(shader.getShader().getProgram());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, e.getTexture().getId());
shader.getShader().bindUniformi(shader.getShader().getUniform("u_texture"), 0);
shader.updateView(projection, e.getMatrix(), camera.getMatrix());
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glUseProgram(0);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL30.glBindVertexArray(0);

And my shader model is set up as so.

Code: [Select]
private int matrix_projection, matrix_transform, matrix_camera;

@Override
public void init() { //yes it is inited
shader.bindAttribute(0, "position");
shader.bindAttribute(1, "texcoord");

matrix_projection = shader.getUniform("matrix_projection");
matrix_transform = shader.getUniform("matrix_transform");
matrix_camera = shader.getUniform("matrix_camera");
}

@Override //called in the main update loop
public void updateView(Matrix4f projection, Matrix4f transform, Matrix4f camera) {
shader.bindUniformm(matrix_projection, projection);
shader.bindUniformm(matrix_transform, transform);
shader.bindUniformm(matrix_camera, camera);
}

Any need-to-knows please ask. I am through with this bug.

Solution:
Everything was all fine, but I accidentally messed up my super() calls to super classes, as it wasn't regarding scale.
Switched to a system where scale determined the width and height of geometry (had to update shaders and matrix stuff).
- Previously I believed that the scale being 0-1 would be mapped to what I use with orthogonal, it's not.
« Last Edit: February 16, 2016, 00:33:13 by Hydroque »

*

Kai

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #1 on: February 11, 2016, 08:37:57 »
Your quad is hardly visible, as it likely only takes up 10 pixels in width/height (if you setup the ortho projection like I think you do) and it might appear at the bottom left of your screen.
Also, what would be interesting is how you actually invoke createOrtho().
Next, how you upload the matrix to OpenGL, so essentially what does Shader.bindUniformm(int, Matrix4f) do?
« Last Edit: February 11, 2016, 10:33:23 by Kai »

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #2 on: February 11, 2016, 15:04:23 »
Quote
Your quad is hardly visible, as it likely only takes up 10 pixels in width/height (if you setup the ortho projection like I think you do) and it might appear at the bottom left of your screen.
I should add a screen shot. There is nothing displayed even when I translate my view projection.

Quote
Also, what would be interesting is how you actually invoke createOrtho().
Code: [Select]
final Matrix4f projection = Projection.createOrtho(0f, (float) window.getWidth(), 0f, (float) window.getHeight(), 0.1f, 100f);
Quote
Next, how you upload the matrix to OpenGL, so essentially what does Shader.bindUniformm(int, Matrix4f) do?
Code: [Select]
public void bindUniformm(int location, Matrix4f mat) {
mat.store(temp_buffer);
temp_buffer.flip();
GL20.glUniformMatrix4(location, false, temp_buffer);
}
This works fine. All values are as expected or seemingly as they expected because view matrix draws properly as well as transform.

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #3 on: February 13, 2016, 00:25:31 »

*

Kai

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #4 on: February 13, 2016, 23:58:20 »
Did you try to fix the problem yourself first? Requiring people to download 28.47 MB off a very suspicious file sharing hosting platform and fumble over your (possibly) hundreds of classes for hours is just not going to happen.
Build a single-file Minimal Working Example that demonstrates your problem and which does not make use of any third-party dependencies, 3D models, sound files or textures or anything. While doing that you are very likely to find the issue yourself.

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #5 on: February 14, 2016, 20:45:13 »
It's the full source code to the project and the file hosting thing only has adverts, no fancy download button spam, and it's in the form of a .ZIP, not jar. I already outlined the problems, what I have tried, and I guess I can outline the files that affect the program.

*

Kai

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #6 on: February 14, 2016, 20:52:36 »
You did not understand what I or @abcdef was saying, apparently.
NO ONE is going to go through your whole project. And neither do I nor anyone else care whether it is a zip or a jar (which is a zip).
The fact that it is "the full source code" is what is BAD!
You should AVOID doing that instead of advertizing it as something which would help people find your problem. In fact providing the full source severely harms the likeliness of people even _wanting_ to help you. Let alone actually finding the issue.
Like I said: Do a (hopefully single-file) MWE and people will care to help.

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #7 on: February 14, 2016, 21:01:50 »
Geez fine. I'll obfuscate the code by putting it into one file.

*

Kai

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #8 on: February 14, 2016, 21:10:55 »
You again did not get the point: The purpose is not to have a single file "no matter what the cost" but to have something which people can grasp and oversee fast and concentrate on a particular aspect.
Obviously it will do you no good as well to chunk your 23 Megabytes of compressed Java source code files... Jesus... into a single file.
Isolate the possible error factors by eliminating aspects of your game/engine which are likely irrelevant to the problem.
And that is where we end up with a MWE.
Build the MWE from scratch if need be.

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #9 on: February 14, 2016, 21:49:26 »
The reason it was so big is because I use twl's png decoder, had 3 images, 8 or so sounds, and Luaj script language library.
I am very neat and organized and my redundancy hatred makes my code that much more easier to grasp. Anyways, I get what you meant about the MWE, but I've already isolated the problem.

Re: Orthogonal Matrix using Vertex/Fragment shaders Problem
« Reply #10 on: February 14, 2016, 21:53:49 »
So I was like okay let's mess with the scale. When I did, setting scale to 100f instead of 1f made it visible. I also put it to 700f and 800f to check if it was actually 100 pixels long. It was. What a strange scenario.

How can I cut scaling out so that 1 = 800 without normalized unit multiplication?

It was strange because my SpriteElement subclass was clashing with it's superclass too. Never trusting auto-generation of constructors again when super(position, rotation, scale) has super(position, rotation, scale, another_attrib).

I followed your advise on MWE and now I have a completely stripped in-one-class representation of my project, which can be useful I guess because it has all the variables in my face. (Well except for my shader stuff)
« Last Edit: February 14, 2016, 21:59:32 by Hydroque »