Jump to content


problem using a simple shader


10 replies to this topic

#1 v71

    Valued Member

  • Members
  • PipPipPipPip
  • 357 posts

Posted 08 March 2013 - 05:45 PM

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
Check my code in the c/c++ section :
http://www.binpress.com/browse/c

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 5344 posts
  • LocationSanta Clara, CA

Posted 08 March 2013 - 06:02 PM

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.)
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 v71

    Valued Member

  • Members
  • PipPipPipPip
  • 357 posts

Posted 08 March 2013 - 06:12 PM

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);


Check my code in the c/c++ section :
http://www.binpress.com/browse/c

#4 Reedbeta

    DevMaster Staff

  • Administrators
  • 5344 posts
  • LocationSanta Clara, CA

Posted 08 March 2013 - 06:26 PM

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/.
reedbeta.com - developer blog, OpenGL demos, and other projects

#5 Stainless

    Member

  • Members
  • PipPipPipPip
  • 610 posts
  • LocationSouthampton

Posted 09 March 2013 - 06:22 AM

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

#6 v71

    Valued Member

  • Members
  • PipPipPipPip
  • 357 posts

Posted 09 March 2013 - 06:02 PM

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.
Check my code in the c/c++ section :
http://www.binpress.com/browse/c

#7 Reedbeta

    DevMaster Staff

  • Administrators
  • 5344 posts
  • LocationSanta Clara, CA

Posted 09 March 2013 - 10:21 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#8 v71

    Valued Member

  • Members
  • PipPipPipPip
  • 357 posts

Posted 09 March 2013 - 11:13 PM

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.
Check my code in the c/c++ section :
http://www.binpress.com/browse/c

#9 Reedbeta

    DevMaster Staff

  • Administrators
  • 5344 posts
  • LocationSanta Clara, CA

Posted 10 March 2013 - 01:15 AM

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?
reedbeta.com - developer blog, OpenGL demos, and other projects

#10 TheNut

    Senior Member

  • Moderators
  • 1718 posts
  • LocationCyberspace

Posted 10 March 2013 - 05:05 AM

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).
http://www.nutty.ca - Being a nut has its advantages.

#11 v71

    Valued Member

  • Members
  • PipPipPipPip
  • 357 posts

Posted 10 March 2013 - 09:03 AM

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
Check my code in the c/c++ section :
http://www.binpress.com/browse/c





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users