[Solved] Orthogonal Matrix using Vertex/Fragment shaders Problem

Started by Hydroque, February 10, 2016, 23:44:57

Previous topic - Next topic

Hydroque

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


QuoteAttempting 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.
final Matrix4f projection = Projection.createOrtho(0f, (float) window.getWidth(), 0f, (float) window.getHeight(), 0.1f, 100f);

GL11.glViewport(-400, -300, 800, 600);


Vertex Shader:
#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:
#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.

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.

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

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.

Kai

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?

Hydroque

QuoteYour 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.

QuoteAlso, what would be interesting is how you actually invoke createOrtho().
final Matrix4f projection = Projection.createOrtho(0f, (float) window.getWidth(), 0f, (float) window.getHeight(), 0.1f, 100f);


QuoteNext, how you upload the matrix to OpenGL, so essentially what does Shader.bindUniformm(int, Matrix4f) do?
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.


Kai

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.

Hydroque

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

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.

Hydroque

Geez fine. I'll obfuscate the code by putting it into one file.

Kai

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.

Hydroque

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.

Hydroque

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)