problem using a simple shader

Ceee4d1295c32a0c1c08a9eae8c9459d
0
v71 105 Mar 08, 2013 at 17:45

Hello everybody, i am experiencing a strange problem, i atta ch my simple vertex and pixel shader hoping that some shader expert will shed some light on it , excuse me but i am pretty new to shaders.

vertex shader:

#version 330

precision highp float;

uniform mat4 ViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform mat4 ModelViewProjectionMatrix;

in vec4 VertexPosition;
in vec3 VertexNormal;
out vec3 Normal;

void main()
{
// All vertex shaders should write the transformed homogeneous clip space
// vertex position into the gl_Position variables.

gl_Position = ModelViewProjectionMatrix * VertexPosition;

// normal

Normal = VertexNormal;

}

pixel shader :

#version 330

precision highp float;

out vec4 FragColor;

uniform vec4 WireFrameColor;

void main()
{

FragColor = WireFrameColor ;

}

The strange fact is that if in the vertex shader, i comment out the ‘normal’ , i don’t get rendered anything.
Where am i wrong ?
Does anybody know a place to learn modern opengl shaders ?
Thanks

10 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Mar 08, 2013 at 18:02

Are you checking for errors after each GL call in the process of compiling and linking the shaders?

(BTW, you can use [ code ] … [ /code ] tags to post code on the forum, to retain the formatting.)

Ceee4d1295c32a0c1c08a9eae8c9459d
0
v71 105 Mar 08, 2013 at 18:12

Thanks for reminding me the code tags, i tend to forget them on a regular basis, yes i tried , but i don’t get any error , i get only a blank screen.
Could it be that the shader compiler get ‘confused’ about the vertex formatting ? i keep everything packed in a struct, but the byte alignment is correct when i pass adresses to opengl :

glVertexAttribPointer(VertexAttribPosition,     4, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), BUFFER_OFFSET(0));
glVertexAttribPointer(NormalAttribPosition,     3, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), BUFFER_OFFSET(sizeof(float) * 4));
glVertexAttribPointer(TexCoordAttribPosition  , 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), BUFFER_OFFSET(sizeof(float) * 7));
glVertexAttribPointer(ColorCoordAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), BUFFER_OFFSET(sizeof(float) * 9));

glEnableVertexAttribArray(VertexAttribPosition);
glEnableVertexAttribArray(NormalAttribPosition);
glEnableVertexAttribArray(TexCoordAttribPosition);
glEnableVertexAttribArray(ColorCoordAttribPosition);
A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Mar 08, 2013 at 18:26

Interleaved vertex arrays are fine; I think that’s how everyone does them (better for cache). I’m not sure what else to look for, then. BTW, for modern OpenGL tutorials I usually point people at http://www.opengl-tutorial.org/.

B5262118b588a5a420230bfbef4a2cdf
0
Stainless 151 Mar 09, 2013 at 06:22

I would try working with the alternate syntax, I know that using in and out as variables does not work on all platforms.

I use uniform and varying, and that works on all the platforms I have tried.

I’ll give you an example

precision mediump float;
precision mediump int;

uniform mat4 u_m4_matrix;
uniform float time;

attribute vec4 a_v4_vertex;
attribute vec2 a_v2_texcord;
varying vec2 v_v2_texcord;
varying float v_time;

void main(void)
{
gl_Position = u_m4_matrix * a_v4_vertex;
v_v2_texcord = a_v2_texcord;
v_time = time;

};

and a pixel shader

//================================================//
// Led.frag generated from forth haiku            
//================================================//

precision mediump float;
precision mediump int;

varying vec2 v_v2_texcord;

void main(void)
{
   vec4 result;
    float d0;
    float d1;
    float d2;
    float d3;
    float d4;
    d0=v_v2_texcord.x;
    // var
    d1=1.000000;
    d0=d0+d1;
    d1=v_v2_texcord.y;
    // var
    d2=7.000000;
    // *
    d1=d1*d2;
    // Sin
    d1=sin(d1);
    // swap
    d2=d1;
    d1=d0;
    d0=d2;
    // var
    d2=7.000000;
    // *
    d1=d1*d2;
    // Cos
    d1=cos(d1);
    // *
    d0=d0*d1;
    // dup
    d1=d0;
    // *
    d0=d0*d1;
    d1=v_v2_texcord.x;
    d2=v_v2_texcord.y;
    // var
    d3=7.000000;
    // *
    d2=d2*d3;
    // Sin
    d2=sin(d2);
    // swap
    d3=d2;
    d2=d1;
    d1=d3;
    // var
    d3=7.000000;
    // *
    d2=d2*d3;
    // Cos
    d2=cos(d2);
    // *
    d1=d1*d2;
    // dup
    d2=d1;
    // *
    d1=d1*d2;
    d2=v_v2_texcord.x;
    d1=d1+d2;
    d2=v_v2_texcord.x;
    d3=v_v2_texcord.y;
    // var
    d4=7.000000;
    // *
    d3=d3*d4;
    // Sin
    d3=sin(d3);
    // swap
    d4=d3;
    d3=d2;
    d2=d4;
    // var
    d4=7.000000;
    // *
    d3=d3*d4;
    // Cos
    d3=cos(d3);
    // *
    d2=d2*d3;
    // dup
    d3=d2;
    // *
    d2=d2*d3;
    result.x=d0;
    result.y=d1;
    result.z=d2;
    result.w=1.0;

    gl_FragColor = result;
}

This is actually a generated texture and the pixel shader is generated from some forth code , but it will do as an example

The original and much cleaner code is here

http://forthsalon.appspot.com/haiku-view/ahBzfmZvcnRoc2Fsb24taHJkcgwLEgVIYWlrdRi6Fww

Ceee4d1295c32a0c1c08a9eae8c9459d
0
v71 105 Mar 09, 2013 at 18:02

One more question , i use vao , so basically the vao wraps all calls to pointers and attributes in a single function call , let’s suppose i have 2 shaders, i use a vbo and ibo ( index buffer object ) as a template for my mesh, the first shaders draws a flat triangle and the second draw a textured triangle.
As far as i understand i need 2 different vaos, for each type of shader , correct ?
Is there a better way to handle this situation ? is this the current practice ? i have read that is better to pack models which uses the same shader in the same vbo, but others say the opposite.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Mar 09, 2013 at 22:21

If you have different vertex formats for different models, you will need different VAOs. It actually doesn’t matter whether you change shaders; it just matters whether you change vertex formats. You could run both shaders on vertices in the same format, containing all the vertex components that are needed by either shader. Or you could split them and restrict each vertex format to just the components needed by that shader, e.g. the non-textured shader doesn’t need UVs.

If you can pack together models that use the same shader in the same vertex buffer then you can potentially draw them all in one draw call. On the other hand you might have other state (shader parameters) that needs to be set per model, or you might to instance each model, or sort them for transparency etc. so it’s not necessarily going to work.

Ceee4d1295c32a0c1c08a9eae8c9459d
0
v71 105 Mar 09, 2013 at 23:13

That is what i am doing, but i still get that issue, i create a vao and i use 2 different shaders with the same attribute layout, but in the second shader i must use the normal coordinates , even if i don’t make any computation out of it, or i do not get rendered anything.
Just to clarify in the first shader i do a phong computation , in the second i want to render the mesh in wireframe so i don’t need normals.
But if i don’t use the data from the attribute ‘vertexnormal”, in the second shader ,nothing gets rendered.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Mar 10, 2013 at 01:15

Odd; I would expect that to work (in D3D it certainly would). Maybe OpenGL is stricter about unused attributes. What if you glDisableVertexAttribArray the normal attribute for the second shader; does it work then?

6837d514b487de395be51432d9cdd078
0
TheNut 179 Mar 10, 2013 at 05:05

The video card will automatically optimize out the Normal attribute if it’s not used (assuming v71 isn’t using a debug flag in the shader compiler), so manually removing it from the shader should not have an effect on the renderer. It sounds like something else is at play here. Do you also comment out “out vec3 Normal” in your vertex shader? Just guessing here because maybe you have a driver conflict with leaving a varying variable dandling like that (it should be optimized out though). Check your debugger and see what the video card is returning for your attribute indices. Make sure they are >0, otherwise that means the shader was compiled with those attributes optimized out (your VertexPosition should be fine).

Ceee4d1295c32a0c1c08a9eae8c9459d
0
v71 105 Mar 10, 2013 at 09:03

Looks like the problem has been solved , i have bound the attributes before linking the shader program , instead before doing this , i had been getting them from the shader itself using the getattribute function, maybe the driver optimizes something under the hood leaving an address dangling (???), also i have forced the position for all the attributes using an enum variable, fixing the attribute at specific position.
Thanks for all the help guys, you really rock