PDA

View Full Version : Object-positioning with gl_ModelViewProjectionMatrix



art-ganseforth
09-25-2016, 06:20 AM
Hi there!

I have just started to use GLSL and i currently have general problems in understanding matrix-operations. It's years ago, when i had to work with matrices. So i have a newbie question concerning gl_ModelViewProjectionMatrix.

Background:
My idea (or some kind of experiment) is, to use the vertex-shader as "object-generator" - which is more flexible than static C-code. A huge part already works fine.
In the C-part of my program, i just generate a flat rectangle with x and y between 0 and 1 (with variable resolution) and z=0. In the vertex-shader i use x and y as sources to generate objects like ie. simply a torus.
Also normal-vectors are already calculated correct by the shader.

My problem is the object-positioning. For C-generated objects, i used "gl_Position = ftransform()", which i cant use in this case.
Using gl_ModelViewProjectionMatrix i get correct rotations but - somehow - translations are lost. So my torus can be rotated by calling glRotatef() in the C-part of the program, but glTranslatef() doesn't have any effect.

Here is the relevant vertex-shader-code (some function are shortened):


varying vec4 Vertex;
varying vec3 Normal;

vec4 rotateX (vec3 v, float a) {...}
vec4 rotateY (vec3 v, float a) {...}
vec4 rotateZ (vec3 v, float a) {...}

vec3 NormalVec(vec4 p, vec4 vX, vec4 vY) {...}


vec4 Torus(vec2 pos) {
vec4 v = vec4 (0.0, 0.0, 0.1, 0.0);
v = rotateY (v, pos.y * 2.0) + vec3(0.0, 0.0, 0.25);
v = rotateX (v, pos.x * 2.0);
return v;
}

void main () {
vec4 t1 = Torus(vec2(gl_Vertex));
vec4 t2 = Torus(vec2(gl_Vertex) + vec2(0.0, 0.01));
vec4 t3 = Torus(vec2(gl_Vertex) + vec2(0.01, 0.0));
Normal = NormalVec(t1, t2, t3);
t1 = t1 * gl_ModelViewProjectionMatrix;
Vertex = vec4(t1.x, t1.y, t1.z, 1);

gl_Position = Vertex;
}


Anyone knows why tranlations are lost??

Regards,
Frank

BBeck1
09-25-2016, 07:10 AM
Just glancing over your code, it appears you are attempting to position the objects with your code; that is the job of the Model matrix, and so you could be positioning it multiple times with unintended results. The view matrix, as your camera, could also position them off screen.

You're also not really creating the objects in the shader. The objects are the vertices and you're passing those in. So, then there's a huge confusion as to whether you're working in normalized device coordinates, or 3D coordinates. Generally the first thing you do is combine the vertex position (just one of the pieces of information in most vertices) with the WorldViewProjection matrix in order to make them 2D coordinates that are basically normalized device coordinates. That's before you start working with the vertices in the vertex shader.

I'm not sure how gl_ModelViewProjectionMatrix even gets fed. I started with OGL 4.5 and haven't really learned previous versions of OGL before modern. But in modern, you use uniforms to feed the Model, View, and Projection matrix (usually separately).

I would recommend going through these tutorials (http://learnopengl.com/). I haven't really gone through them, but someone else recommended them and glancing over them they look really good.

Before, during, or after that, I would recommend going through my Vector (https://www.youtube.com/watch?v=56v9BgwSzsg) and Matrix (https://www.youtube.com/watch?v=T7sb4yKKzFg) videos on my YouTube channel VirtuallyProgramming.com.

At some point, it may be worth your while to go through my HLSL shader videos as well. On my website, I have a GLSL shader project where the shader is basically the exact same shader that you end up with at the end of my HLSL videos. Most of it's math anyway. So, the math and the theory is the same whether you're doing HLSL or GLSL. But that website tutorial I linked first will walk you through the GLSL version of that. My HLSL series is basically about building the main shader you will use the vast majority of the time and which you can build off of to do even more advanced or different things. So, not surprisingly, other tutorials will walk you through basically the same shader. All my videos kind of build off the previous videos. So, unless you have a very very solid understanding of vectors in game programming, you'll probably want to watch that video before the matrix video. It's 3 hours of video, but it's covers just about everything you need to know about the two subjects in order to get started with 3D game programming.

art-ganseforth
09-25-2016, 08:06 AM
Thanks for the suggestions. I'll take a look at the tutorial but videos wont help. I'm not a native english-speaker. When reading i can help myself with unknown vocabulary, but in videos this is too hard.

Concerning the version of OGL i'm not sure, but it implements GLSL 4.0

Concerning:
You're also not really creating the objects in the shader. The objects are the vertices and you're passing those in.
Hmmm... Not really (if i understand you right). The input of the vertex-shader is just a planar grid of 3d-vertices. The positon of the passed vertices are not the used as positions. They are just used as counters. The shader calculates where each vertex has to be positioned to build a torus (or what ever).

As far as i know (most of this i have tried successfullly myself) gl_ProjectionMatrix "contains" the view-angel and any manipulations of glMatrixMode(GL_PROJECTION) and gl_ModelViewMatrix any manipulations of glMatrixMode(GL_MODELVIEW). gl_ModelViewProjectionMatrix combines both.

But still i dont know, why rotations work and translations don't...


Kind regards,
Frank

GClements
09-25-2016, 02:12 PM
t1 = t1 * gl_ModelViewProjectionMatrix;
Vertex = vec4(t1.x, t1.y, t1.z, 1);


That should be:



Vertex = gl_ModelViewProjectionMatrix * t1;


The matrices generated by the legacy matrix functions are designed to be multiplied with the matrix on the left and a column vector on the right (this is consistent with most textbooks, but the opposite to DirectX).