PDA

View Full Version : Simple Shader not working



Roberto
02-08-2015, 03:47 AM
Dear Forum..

before post my code composed by 2 very basic shader, i ask some basic question
about matrix manipulation and then about passign data to a vertex,that are not again
so clear to me, and maybe are the responsible of this error.

So, first question are:

1)About projection matrix. This code:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glfrustum(......);

is setting projection matrix P =I (so clear it) and then, the glfrustum() set the P matrix
derived from parameter of glfrustum. In particular, it multiply the Previous P for the new
P,so,P continue to change every time glfrustum is called...this is because we need to
reset every time with I.
The frustum also decide the clipping..
Is all correct ?


2)If previos is correct then:

a) if i want a perspective projection i use the previous code for set P.
b) if i want a ortho projection ,then i use

glMatrixMode(GL_PROJECTION);
glLoadIdentity()
glOrtho(......................);

The glortho is not modifing P (that is P=I), but is ONLY setting the clipping space.
Correct ?

3)Why in all code i see ,we must set the P ,the MV matrix and Viewport in the changesize()
event ?
The window dimension is some related to vieport,and,if i let it fix, and , if i dont change P
,why we need every time to reset to I and set?
Maybe is only necessary to reset the MV matrix in the render() roudine, if we use a translation,
rotation ecc....But is not so.Why??


For now i want be sure about this, and then post the new questions.

Thanks again
Roberto

GClements
02-08-2015, 07:14 AM
1)About projection matrix. This code:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glfrustum(......);

is setting projection matrix P =I (so clear it) and then, the glfrustum() set the P matrix
derived from parameter of glfrustum. In particular, it multiply the Previous P for the new
P,so,P continue to change every time glfrustum is called...this is because we need to
reset every time with I.

Most legacy OpenGL matrix functions post-multiply the current matrix with a matrix generated from the functions parameters. So in order to set the current matrix to a specific matrix you first have to "reset" the current matrix to the identity matrix.


The frustum also decide the clipping..

The clipping planes are fixed in clip space. The projection matrix transforms vertices from eye space to clip space. So the projection matrix will affect which portion of the geometry remains after clipping.



2)If previos is correct then:

a) if i want a perspective projection i use the previous code for set P.
b) if i want a ortho projection ,then i use

glMatrixMode(GL_PROJECTION);
glLoadIdentity()
glOrtho(......................);

The glortho is not modifing P (that is P=I), but is ONLY setting the clipping space.
Correct ?

The above code modifies the projection matrix. If the bottom,top,left,right parameters are -1,1,-1,1 respectively, then the X and Y coordinates will be unchanged by the projection transformation. The Z coordinate will typically still be affected (in particular, if farVal > nearVal then the sign of the Z coordinate will change), which will affect clipping against the near and far planes.



3)Why in all code i see ,we must set the P ,the MV matrix and Viewport in the changesize()
event ?
The window dimension is some related to vieport,and,if i let it fix, and , if i dont change P
,why we need every time to reset to I and set?
Maybe is only necessary to reset the MV matrix in the render() roudine, if we use a translation,
rotation ecc....But is not so.Why??

You can set the viewpoint and matrices wherever you like; all that matters is their values at the time you issue OpenGL commands. But at least the viewport should normally change in response to any change in the window dimensions. The projection matrix typically also needs to change in order to maintain the correct aspect ratio. The model-view matrix typically doesn't need to change in response to any changes to the window size. If you don't use the model-view matrix for modelling transformations, it's entirely possible to just leave the model-view matrix as the identity matrix (which is the default value at context creation).

Roberto
02-08-2015, 01:36 PM
Thanks very for reply.

Im able to create a shader,a programm, compile ,link ecc....I have problem in understand some
mechanism inside and when/how the things happend.

Some questions about shader (vertex for now).

1) A Vertex shader is a programm that lives in GPU,reading data & manipulating them .
When it start to read & elaborate ? Maybe when we use in the render() roudine the

glUseProgram(Programm_ID);
??

2)I read there are 3 way to pass data to a vertex shader:

a)Reading the Opengl state
b)Passing data &attribute to owr custom input's
c)Via a Texture

For now only About the first way..I understand we can read this state using a Buil-in attribute,
named -gl_Vertex-.The more simple way(for now trascure VBO & VAO) is to supply data via
functions :

glBegin(...)

glVertex(....)
............
glEnd()

But this functions already create some figure(es triangle).So, who is doing the job,my shader
or this function ? Maybe the first time the glBegin, & then my shader.?

If you can supply a example of this way to pass data i appreciate.

Thanks

roberto

GClements
02-09-2015, 12:42 PM
1) A Vertex shader is a programm that lives in GPU,reading data & manipulating them .
When it start to read & elaborate

Shaders are run during rendering, i.e. when you call the glDraw* functions or glBegin/glEnd.



But this functions already create some figure(es triangle).So, who is doing the job,my shader
or this function ?

The vertex shader is invoked for each vertex. It replaces any per-vertex portion of the fixed-function pipeline (vertex transformation, lighting, texture coordinate generation).

In the compatibility profile, values specified by glVertex, glNormal, glColor, and glTexCoord (and the *Pointer versions when using the glDraw* functions) are available in the vertex shader via built-in attributes (gl_Vertex, gl_Normal, etc).

In the core profile, all of the attributes must be declared in the shader, and data passed using glVertexAttrib or glVertexAttribPointer.

Roberto
02-10-2015, 02:47 AM
Thanks Mr Clements for reply....now much is more clear.

So,I try to pass data in the way named compatibilty profile.

But First i post a simple working code rendering a green triangle,then i
try to use a simple shader.

main()
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA|GLUT_DEPTH);
glutInitWindowSize(800,600);
glutCreateWindow("Ciao");

set_MVP_VIEWBOX_VIEWPORT(); //just set the fix viewport & viewbox & MVP matrix

glutReshapeFunc(changesize); //event changesize

glutDisplayFunc(render); //event render

glClearColor(0,0,0,1);

glutMainLoop();

return 0;

}


void set_MVP_VIEWBOX_VIEWPORT()
{

glMatrixMode(GL_MODELVIEW); //Unit MV
glLoadIdentity();

glMatrixMode(GL_PROJECTION) ;//Unit P
glLoadIdentity();

glOrtho (0, 10, 0,10, 20,-20); //For Ortho projection

glViewport(10 , 10 ,400,400); // fix viewport

return;
}



void changesize(GLsizei w,GLsizei h)
{

//Fix
glViewport(10 , 10 ,400,400);


}


void render(void)
{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glBegin(GL_TRIANGLES);

glColor3f(0,1,0); //green

glVertex3f(1,1,0);
glVertex3f(5,5,0);
glVertex3f(9,1,0);

glEnd();


glutSwapBuffers();


return;
}


This code work, and render a triangle.If i change the window dimension ,the triangle stay in fix position and dont scale
(viewport fix).

A first question is: If I dont set the viewport in the changesize() event, then the triangle change dimension if window change
dimension. Why ? I already fix the viewport in the -set_MVP_VIEWBOX_VIEWPORT()-



Now i try to pass data with shader. This are the shader:

//Vertex shader
void main()
{

gl_Position=gl_Vertex;
gl_FrontColor=gl_Color;

}


//Frag shader
void main()
{


gl_FragColor.rgb=gl_Color.rgb;

}

and in main, i write (i just avoid to post all code for semplify)

main()
{
//reading shader file
.......
//compile the vertex & frag shader
..........
//create programm
..............

//attach the shaders
...........

//Link
glLinkProgram(Programm_ID);



//& use Shader

glUseProgram(Programm_ID);


glutMainLoop();
return 0;


}

I let in render() the same code . This code is not working.
I see only black
Why?

Excuse for long mail

Roberto

Alexey Boreskov
02-10-2015, 03:46 AM
When you use identity matrices all your visible area of space is [-1,1]^3.
Your geometry is outside this area so you see nothing, try moving geometry near origin.

Roberto
02-10-2015, 04:05 AM
Thanks Alexey.

Changing as you suggest work.

But why . Also the code without shader was out of -1,1 and i can see the figure;this becasue glortho() goes from [0,10 ] ^3.

Why when use shader in same range then dont work ? What happend to my glortho?

Thanks

GClements
02-10-2015, 06:32 AM
Why when use shader in same range then dont work ? What happend to my glortho?
The current matrices (projection, model-view, texture) are part of the fixed-function pipeline. If you use a vertex shader, it replaces the part of the fixed-function pipeline which deals with transformations, so your vertex shader has to explicitly transform the vertices, e.g.:


gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;


Look at the OpenGL 3.x reference pages (https://www.opengl.org/sdk/docs/man3/). Only the core profile functions are described there. If a function which you're using isn't listed (e.g. glOrtho), then it may be part of the fixed-function pipeline, meaning that it doesn't do anything (except perhaps setting a compatibility uniform) if you're using shaders.

Similarly, glLight() and glMaterial() don't do anything (except set compatibility uniforms) if you have a vertex shader. If you want to calculate the vertex colour based upon light and material parameters, your vertex shader has to do that explicitly.

Alfonse Reinheart
02-10-2015, 09:02 AM
Excuse for long mail

Roberto

It's not the length that's the problem. It's the lack of proper formatting. Use code tags. It's right there in the posting guidelines (https://www.opengl.org/discussion_boards/showthread.php/176139-Forum-Posting-Guidelines?p=1230021#post1230021), linked at the top of every forum listing.

Roberto
02-11-2015, 12:58 PM
Thanks again Mr Clements for reply.

After your reply im able to pass data to my shader in multiple way.
Via VBO & read with build-in attribute , and via VAO reading with my personal attribute.

I post a last question about matrix, and then we can consider closed this thread .

The only thing i cant understand is why we need this operation:

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

Let me explain what i understand :

a)Image we want perspective projection.
I understand that in view space (or camera space) we define the frustum. The frustum set the P matrix ,and so,from
view space we go in what is named clip space ,where the frustum is deformed like a parallelepipid,and the clipping take
place becasue is more easy to clip here. Then, another transformation take us in the unit cube [-1,1]^3,that is the end space
before viewport.
In this case I can understand the multiplication for MVP matrix,becasue frustum change P

b)Image we want ortho projection (my case now)
Ortho set the P matrix =I ,so all vertex arrive in clip space not changed (who survive to clipping)
Then we go again in the unit cube with same transformation of before.
Here I cant understand the MVP multiplication: MVP is the unit matrix in this case (I set MV=I).
Or not ?

Thanks again
Roberto

GClements
02-11-2015, 05:55 PM
Here I cant understand the MVP multiplication: MVP is the unit matrix in this case (I set MV=I).
Or not ?

That depends upon the arguments to glOrtho(), but usually not.

In the example code you gave earlier:




glOrtho (0, 10, 0,10, 20, -20); //For Ortho projection


the resulting projection matrix will be


[[ 0.2 , 0. , 0. , -1. ],
[ 0. , 0.2 , 0. , -1. ],
[ 0. , 0. , 0.05, 0. ],
[ 0. , 0. , 0. , 1. ]])

Note the scale factors (inversely proportional to the size of the view volume in that dimension) and the x/y offsets due to zero being at an edge rather than the centre.

To get an identity matrix, you would need


glOrtho(-1, 1, -1, 1, 1, -1)

I.e. 1 in each dimension, with the Z values being flipped (conventional OpenGL modelling coordinates have +Z facing out of the screen, while clip coordinates and NDC have +Z facing into the screen, so a "typical" projection matrix has a negative scale factor for the Z component).

Roberto
02-20-2015, 01:58 AM
Thanks Mr Clement for reply

now many things are more clear.

Thank again for your time

Roberto